diff --git a/src/app/calendar-app/calendar-app.module.ts b/src/app/calendar-app/calendar-app.module.ts index 8f8a54ce9..fa5be005d 100644 --- a/src/app/calendar-app/calendar-app.module.ts +++ b/src/app/calendar-app/calendar-app.module.ts @@ -60,13 +60,13 @@ import { CalendarEventCardComponent } from './calendar-event-card.component'; // See https://momentjs.com/docs/#/displaying/format/ export const MOMENT_FORMATS = { - parseInput: 'l LT', - fullPickerInput: 'l LT', - datePickerInput: 'l', - timePickerInput: 'LT', - monthYearLabel: 'MMM YYYY', - dateA11yLabel: 'LL', - monthYearA11yLabel: 'MMMM YYYY', + parseInput: 'YYYY-MM-DD HH:mm', + fullPickerInput: 'YYYY-MM-DD HH:mm', + datePickerInput: 'YYYY-MM-DD', + timePickerInput: 'HH:mm', + monthYearLabel: 'YYYY-MM', + dateA11yLabel: 'YYYY-MM-DD', + monthYearA11yLabel: 'YYYY-MM', }; @NgModule({ diff --git a/src/app/calendar-app/calendar-event-card.component.html b/src/app/calendar-app/calendar-event-card.component.html index a0611c65d..b6d6c1980 100644 --- a/src/app/calendar-app/calendar-event-card.component.html +++ b/src/app/calendar-app/calendar-event-card.component.html @@ -9,10 +9,10 @@ Starts Started - {{ event.dtstart.calendar() }} + {{ formatDateTime(event.dtstart) }} - Ends {{ event.dtend.calendar() }} + Ends {{ formatDateTime(event.dtend) }} {{ event.recurringFrequency }} event diff --git a/src/app/calendar-app/calendar-event-card.component.ts b/src/app/calendar-app/calendar-event-card.component.ts index bce517620..880359348 100644 --- a/src/app/calendar-app/calendar-event-card.component.ts +++ b/src/app/calendar-app/calendar-event-card.component.ts @@ -18,6 +18,7 @@ // ---------- END RUNBOX LICENSE ---------- import { Component, EventEmitter, Input, Output } from '@angular/core'; +import moment from 'moment'; import { EventOverview } from './event-overview'; @Component({ @@ -31,4 +32,8 @@ export class CalendarEventCardComponent { @Output() edit = new EventEmitter(); constructor() { } + + formatDateTime(value: moment.Moment): string { + return value.format('YYYY-MM-DD HH:mm'); + } } diff --git a/src/app/calendar-app/calendar-formatting.spec.ts b/src/app/calendar-app/calendar-formatting.spec.ts new file mode 100644 index 000000000..f1c2c05c5 --- /dev/null +++ b/src/app/calendar-app/calendar-formatting.spec.ts @@ -0,0 +1,71 @@ +// --------- BEGIN RUNBOX LICENSE --------- +// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com). +// +// This file is part of Runbox 7. +// +// Runbox 7 is free software: You can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// Runbox 7 is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Runbox 7. If not, see . +// ---------- END RUNBOX LICENSE ---------- + +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'; +import { MatLegacyCardModule as MatCardModule } from '@angular/material/legacy-card'; +import moment from 'moment'; + +import { CalendarEventCardComponent } from './calendar-event-card.component'; +import { MOMENT_FORMATS } from './calendar-app.module'; +import { EventOverview } from './event-overview'; + +describe('calendar date formatting', () => { + describe('date-time picker formats', () => { + it('uses unambiguous ISO-style date and time formats', () => { + expect(MOMENT_FORMATS.parseInput).toBe('YYYY-MM-DD HH:mm'); + expect(MOMENT_FORMATS.fullPickerInput).toBe('YYYY-MM-DD HH:mm'); + expect(MOMENT_FORMATS.datePickerInput).toBe('YYYY-MM-DD'); + expect(MOMENT_FORMATS.timePickerInput).toBe('HH:mm'); + }); + }); + + describe('CalendarEventCardComponent', () => { + let component: CalendarEventCardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CalendarEventCardComponent], + imports: [ + MatButtonModule, + MatCardModule, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(CalendarEventCardComponent); + component = fixture.componentInstance; + }); + + it('renders event dates with ISO-style date and 24-hour time', () => { + component.event = new EventOverview( + 'Deployment window', + moment('2031-11-12T09:05:00'), + moment('2031-11-12T10:35:00'), + ); + + fixture.detectChanges(); + + const text = fixture.nativeElement.textContent; + expect(text).toContain('Starts'); + expect(text).toContain('2031-11-12 09:05'); + expect(text).toContain('Ends 2031-11-12 10:35'); + }); + }); +});