Skip to content

Commit ed7752a

Browse files
committed
Test ambiguous time
1 parent 989826c commit ed7752a

3 files changed

Lines changed: 16 additions & 3 deletions

File tree

.github/workflows/linux.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
5959

6060
- name: Set timezone
61-
run: sudo timedatectl set-timezone 'Europe/Minsk'
61+
run: sudo timedatectl set-timezone 'Europe/Kyiv'
6262

6363
- name: Install GCC 4.9
6464
run: |

include/fmt/chrono.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,15 +2320,16 @@ struct formatter<local_time<Duration>, Char> : formatter<std::tm, Char> {
23202320
template <typename FormatContext>
23212321
auto format(local_time<Duration> val, FormatContext& ctx) const
23222322
-> decltype(ctx.out()) {
2323+
auto t = gmtime(val.time_since_epoch().count());
23232324
using period = typename Duration::period;
23242325
if (period::num == 1 && period::den == 1 &&
23252326
!std::is_floating_point<typename Duration::rep>::value) {
2326-
return formatter<std::tm, Char>::format(localtime(val), ctx);
2327+
return formatter<std::tm, Char>::format(t, ctx);
23272328
}
23282329
auto epoch = val.time_since_epoch();
23292330
auto subsecs = detail::duration_cast<Duration>(
23302331
epoch - detail::duration_cast<std::chrono::seconds>(epoch));
2331-
return formatter<std::tm, Char>::do_format(localtime(val), ctx, &subsecs);
2332+
return formatter<std::tm, Char>::do_format(t, ctx, &subsecs);
23322333
}
23332334
};
23342335

test/chrono-test.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,18 @@ TEST(chrono_test, local_system_clock_time_point) {
428428

429429
#endif // FMT_USE_LOCAL_TIME
430430

431+
TEST(chrono_test, daylight_savings_time_end) {
432+
// 2024-10-27 03:05 as the number of seconds since epoch in Europe/Kyiv time.
433+
// It is slightly after the DST end and passing it to to_sys will result in
434+
// an ambiguous time error:
435+
// 2024-10-27 03:05:00 is ambiguous. It could be
436+
// 2024-10-27 03:05:00 EEST == 2024-10-27 00:05:00 UTC or
437+
// 2024-10-27 03:05:00 EET == 2024-10-27 01:05:00 UTC
438+
auto t = fmt::local_time<std::chrono::seconds>(
439+
std::chrono::seconds(1729998300));
440+
EXPECT_EQ(fmt::format("{}", t), "2024-10-27 03:05:00");
441+
}
442+
431443
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
432444

433445
TEST(chrono_test, format_default) {

0 commit comments

Comments
 (0)