Skip to content

Commit 5e5ca06

Browse files
committed
test(time_zone): verify GMT round-trip across DST boundaries
1 parent 7b12382 commit 5e5ca06

3 files changed

Lines changed: 110 additions & 0 deletions

File tree

include/time_shield/time_zone_conversions.hpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,48 @@ namespace time_shield {
9494
return cet_to_gmt(eet - SEC_PER_HOUR);
9595
}
9696

97+
/// \brief Convert Greenwich Mean Time to Central European Time.
98+
/// \param gmt Timestamp in seconds in GMT.
99+
/// \return Timestamp in seconds in CET.
100+
inline ts_t gmt_to_cet(ts_t gmt) {
101+
DateTimeStruct dt = to_date_time(gmt);
102+
const int SWITCH_HOUR = 1;
103+
104+
if(dt.mon > MAR && dt.mon < OCT) {
105+
return gmt + SEC_PER_HOUR * 2;
106+
} else if(dt.mon == MAR) {
107+
int last = last_sunday_month_day(dt.year, MAR);
108+
if(dt.day > last) {
109+
return gmt + SEC_PER_HOUR * 2;
110+
} else if(dt.day < last) {
111+
return gmt + SEC_PER_HOUR;
112+
} else {
113+
if(dt.hour >= SWITCH_HOUR)
114+
return gmt + SEC_PER_HOUR * 2;
115+
return gmt + SEC_PER_HOUR;
116+
}
117+
} else if(dt.mon == OCT) {
118+
int last = last_sunday_month_day(dt.year, OCT);
119+
if(dt.day > last) {
120+
return gmt + SEC_PER_HOUR;
121+
} else if(dt.day < last) {
122+
return gmt + SEC_PER_HOUR * 2;
123+
} else {
124+
if(dt.hour >= SWITCH_HOUR)
125+
return gmt + SEC_PER_HOUR;
126+
return gmt + SEC_PER_HOUR * 2;
127+
}
128+
}
129+
return gmt + SEC_PER_HOUR;
130+
}
131+
132+
/// \brief Convert Greenwich Mean Time to Eastern European Time.
133+
/// \param gmt Timestamp in seconds in GMT.
134+
/// \return Timestamp in seconds in EET.
135+
inline ts_t gmt_to_eet(ts_t gmt) {
136+
return gmt_to_cet(gmt) + SEC_PER_HOUR;
137+
}
138+
97139
/// \}
98140

99141
} // namespace time_shield
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include <time_shield/time_zone_conversions.hpp>
2+
#include <time_shield/time_conversions.hpp>
3+
#include <cassert>
4+
5+
/// \brief Round-trip tests for GMT and CET/EET conversions around DST boundaries.
6+
int main() {
7+
using namespace time_shield;
8+
9+
for(int year : {2021, 2022, 2023, 2024}) {
10+
int start_day = last_sunday_month_day(year, MAR);
11+
12+
ts_t cet_start_before = to_timestamp(year, int(MAR), start_day, 1, 59, 0);
13+
ts_t gmt_from_cet_before = cet_to_gmt(cet_start_before);
14+
assert(gmt_to_cet(gmt_from_cet_before) == cet_start_before);
15+
16+
ts_t cet_start_after = to_timestamp(year, int(MAR), start_day, 3, 0, 0);
17+
ts_t gmt_from_cet_after = cet_to_gmt(cet_start_after);
18+
assert(gmt_to_cet(gmt_from_cet_after) == cet_start_after);
19+
20+
ts_t eet_start_before = to_timestamp(year, int(MAR), start_day, 2, 59, 0);
21+
ts_t gmt_from_eet_before = eet_to_gmt(eet_start_before);
22+
assert(gmt_to_eet(gmt_from_eet_before) == eet_start_before);
23+
24+
ts_t eet_start_after = to_timestamp(year, int(MAR), start_day, 4, 0, 0);
25+
ts_t gmt_from_eet_after = eet_to_gmt(eet_start_after);
26+
assert(gmt_to_eet(gmt_from_eet_after) == eet_start_after);
27+
28+
int end_day = last_sunday_month_day(year, OCT);
29+
30+
ts_t cet_end_before = to_timestamp(year, int(OCT), end_day, 1, 59, 0);
31+
ts_t gmt_from_cet_end_before = cet_to_gmt(cet_end_before);
32+
assert(gmt_to_cet(gmt_from_cet_end_before) == cet_end_before);
33+
34+
ts_t cet_end_after = to_timestamp(year, int(OCT), end_day, 3, 0, 0);
35+
ts_t gmt_from_cet_end_after = cet_to_gmt(cet_end_after);
36+
assert(gmt_to_cet(gmt_from_cet_end_after) == cet_end_after);
37+
38+
ts_t eet_end_before = to_timestamp(year, int(OCT), end_day, 3, 59, 0);
39+
ts_t gmt_from_eet_end_before = eet_to_gmt(eet_end_before);
40+
assert(gmt_to_eet(gmt_from_eet_end_before) == eet_end_before);
41+
42+
ts_t eet_end_after = to_timestamp(year, int(OCT), end_day, 4, 0, 0);
43+
ts_t gmt_from_eet_end_after = eet_to_gmt(eet_end_after);
44+
assert(gmt_to_eet(gmt_from_eet_end_after) == eet_end_after);
45+
}
46+
47+
return 0;
48+
}

tests/time_zone_conversion_test.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,25 @@ int main() {
3535
ts_t gmt_eet_summer = eet_to_gmt(eet_summer);
3636
assert(gmt_eet_summer == to_timestamp(2023, 7, 1, 9, 0, 0));
3737

38+
for(int year : {2021, 2022, 2023, 2024}) {
39+
int day = last_sunday_month_day(year, OCT);
40+
41+
ts_t cet_end_before = to_timestamp(year, int(OCT), day, 1, 30, 0);
42+
ts_t gmt_end_before = cet_to_gmt(cet_end_before);
43+
assert(gmt_end_before == to_timestamp(year, int(OCT), day - 1, 23, 30, 0));
44+
45+
ts_t cet_end_after = to_timestamp(year, int(OCT), day, 3, 30, 0);
46+
ts_t gmt_end_after = cet_to_gmt(cet_end_after);
47+
assert(gmt_end_after == to_timestamp(year, int(OCT), day, 2, 30, 0));
48+
49+
ts_t eet_end_before = to_timestamp(year, int(OCT), day, 2, 30, 0);
50+
ts_t gmt_eet_end_before = eet_to_gmt(eet_end_before);
51+
assert(gmt_eet_end_before == to_timestamp(year, int(OCT), day - 1, 23, 30, 0));
52+
53+
ts_t eet_end_after = to_timestamp(year, int(OCT), day, 4, 30, 0);
54+
ts_t gmt_eet_end_after = eet_to_gmt(eet_end_after);
55+
assert(gmt_eet_end_after == to_timestamp(year, int(OCT), day, 2, 30, 0));
56+
}
57+
3858
return 0;
3959
}

0 commit comments

Comments
 (0)