Skip to content

Commit 1042bdc

Browse files
authored
Scheduler: fix recurrence appointment display date according DST (T1305659) (#31307)
1 parent e0b3b39 commit 1042bdc

3 files changed

Lines changed: 360 additions & 201 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import {
2+
describe, expect, it,
3+
} from '@jest/globals';
4+
5+
import { createScheduler } from './__mock__/create_scheduler';
6+
import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler';
7+
import type { AppointmentModel } from './__mock__/model/appointment';
8+
9+
const ChicagoDST = [new Date('2025-03-08T00:00:00.000Z'), new Date('2025-11-01T00:00:00.000Z')]; // +1, -1
10+
const SydneyDST = [new Date('2025-04-07T00:00:00.000Z'), new Date('2025-10-04T00:00:00.000Z')]; // -1, +1
11+
const BelgradeDST = [new Date('2025-03-29T00:00:00.000Z'), new Date('2025-10-25T00:00:00.000Z')]; // +1, -1
12+
const dailyAppointment = {
13+
startDate: new Date('2025-01-07T13:00:00.000Z'),
14+
endDate: new Date('2025-01-07T14:00:00.000Z'),
15+
startDateTimeZone: 'America/Chicago',
16+
endDateTimeZone: 'America/Chicago',
17+
recurrenceRule: 'FREQ=DAILY',
18+
};
19+
const views = [{ type: 'week', intervalCount: 2 }];
20+
21+
const getDisplayDates = (appointments: AppointmentModel[]): string[] => appointments
22+
.map((appointment) => appointment.getDisplayDate());
23+
const reduceDates = (texts: string[]): string[] => texts
24+
.reduce<string[]>((result, time) => {
25+
if (result.at(-1) !== time) {
26+
result.push(time);
27+
}
28+
29+
return result;
30+
}, []);
31+
32+
/*
33+
* NOTE:
34+
* display date = source date - source time zone offset + target time zone offset
35+
*
36+
* Chicago: UTC-6h, UTC-5h, UTC-6h
37+
* Sydney: UTC+11h, UTC+10h, UTC+11h
38+
* Belgrade: UTC+1h, UTC+2h, UTC+1h
39+
*
40+
* Chicago to Chicago: should keep the same display date
41+
* Chicago to Sydney: +17h, +16h, +15h, +16h, +17h
42+
* Chicago to Belgrade: +7h, +6h, +7h, +6h, +7h
43+
*/
44+
describe('Recurrence appointments', () => {
45+
it('should change dates according to DST in target (Chicago) and appointment timezones (T1305659)', async () => {
46+
setupSchedulerTestEnvironment();
47+
const { POM, scheduler } = await createScheduler({
48+
timeZone: 'America/Chicago',
49+
dataSource: [dailyAppointment],
50+
views,
51+
currentView: 'week',
52+
currentDate: ChicagoDST[0],
53+
});
54+
55+
const getDates = () => getDisplayDates(POM.getAppointments());
56+
57+
const dates = getDates();
58+
scheduler.option('currentDate', ChicagoDST[1]);
59+
dates.push(...getDates());
60+
61+
expect(reduceDates(dates)).toEqual([
62+
'7:00 AM - 8:00 AM',
63+
]);
64+
});
65+
66+
it('should change dates according to DST in target (Sydney) and appointment timezones (T1305659)', async () => {
67+
setupSchedulerTestEnvironment();
68+
const { POM, scheduler } = await createScheduler({
69+
timeZone: 'Australia/Sydney',
70+
dataSource: [dailyAppointment],
71+
views,
72+
currentView: 'week',
73+
currentDate: ChicagoDST[0],
74+
});
75+
76+
const getDates = () => getDisplayDates(POM.getAppointments());
77+
78+
const dates = getDates();
79+
scheduler.option('currentDate', SydneyDST[0]);
80+
dates.push(...getDates());
81+
scheduler.option('currentDate', SydneyDST[1]);
82+
dates.push(...getDates());
83+
scheduler.option('currentDate', ChicagoDST[1]);
84+
dates.push(...getDates());
85+
86+
expect(reduceDates(dates)).toEqual([
87+
'12:00 AM - 1:00 AM',
88+
'11:00 PM - 12:00 AM',
89+
'10:00 PM - 11:00 PM',
90+
'11:00 PM - 12:00 AM',
91+
'12:00 AM - 1:00 AM',
92+
]);
93+
});
94+
95+
it('should change dates according to DST in target (Belgrade) and appointment timezones (T1305659)', async () => {
96+
setupSchedulerTestEnvironment();
97+
const { POM, scheduler } = await createScheduler({
98+
timeZone: 'Europe/Belgrade',
99+
dataSource: [dailyAppointment],
100+
views,
101+
currentView: 'week',
102+
currentDate: ChicagoDST[0],
103+
});
104+
105+
const getDates = () => getDisplayDates(POM.getAppointments());
106+
107+
const dates = getDates();
108+
scheduler.option('currentDate', BelgradeDST[0]);
109+
dates.push(...getDates());
110+
scheduler.option('currentDate', BelgradeDST[1]);
111+
dates.push(...getDates());
112+
scheduler.option('currentDate', ChicagoDST[1]);
113+
dates.push(...getDates());
114+
115+
expect(reduceDates(dates)).toEqual([
116+
'2:00 PM - 3:00 PM',
117+
'1:00 PM - 2:00 PM',
118+
'2:00 PM - 3:00 PM',
119+
'1:00 PM - 2:00 PM',
120+
'2:00 PM - 3:00 PM',
121+
]);
122+
});
123+
});

0 commit comments

Comments
 (0)