mirror of
https://github.com/fmtlib/fmt.git
synced 2025-06-25 01:11:40 +02:00
Test ambiguous time
This commit is contained in:
2
.github/workflows/linux.yml
vendored
2
.github/workflows/linux.yml
vendored
@ -58,7 +58,7 @@ jobs:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||
|
||||
- name: Set timezone
|
||||
run: sudo timedatectl set-timezone 'Europe/Minsk'
|
||||
run: sudo timedatectl set-timezone 'Europe/Kyiv'
|
||||
|
||||
- name: Install GCC 4.9
|
||||
run: |
|
||||
|
@ -2320,15 +2320,20 @@ struct formatter<local_time<Duration>, Char> : formatter<std::tm, Char> {
|
||||
template <typename FormatContext>
|
||||
auto format(local_time<Duration> val, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto time_since_epoch = val.time_since_epoch();
|
||||
auto seconds_since_epoch =
|
||||
detail::duration_cast<std::chrono::seconds>(time_since_epoch);
|
||||
// Use gmtime to prevent time conversion since local_time has an
|
||||
// unspecified time zone.
|
||||
auto t = gmtime(seconds_since_epoch.count());
|
||||
using period = typename Duration::period;
|
||||
if (period::num == 1 && period::den == 1 &&
|
||||
!std::is_floating_point<typename Duration::rep>::value) {
|
||||
return formatter<std::tm, Char>::format(localtime(val), ctx);
|
||||
return formatter<std::tm, Char>::format(t, ctx);
|
||||
}
|
||||
auto epoch = val.time_since_epoch();
|
||||
auto subsecs = detail::duration_cast<Duration>(
|
||||
epoch - detail::duration_cast<std::chrono::seconds>(epoch));
|
||||
return formatter<std::tm, Char>::do_format(localtime(val), ctx, &subsecs);
|
||||
auto subsecs =
|
||||
detail::duration_cast<Duration>(time_since_epoch - seconds_since_epoch);
|
||||
return formatter<std::tm, Char>::do_format(t, ctx, &subsecs);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -428,6 +428,18 @@ TEST(chrono_test, local_system_clock_time_point) {
|
||||
|
||||
#endif // FMT_USE_LOCAL_TIME
|
||||
|
||||
TEST(chrono_test, daylight_savings_time_end) {
|
||||
// 2024-10-27 03:05 as the number of seconds since epoch in Europe/Kyiv time.
|
||||
// It is slightly after the DST end and passing it to to_sys will result in
|
||||
// an ambiguous time error:
|
||||
// 2024-10-27 03:05:00 is ambiguous. It could be
|
||||
// 2024-10-27 03:05:00 EEST == 2024-10-27 00:05:00 UTC or
|
||||
// 2024-10-27 03:05:00 EET == 2024-10-27 01:05:00 UTC
|
||||
auto t =
|
||||
fmt::local_time<std::chrono::seconds>(std::chrono::seconds(1729998300));
|
||||
EXPECT_EQ(fmt::format("{}", t), "2024-10-27 03:05:00");
|
||||
}
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
|
||||
TEST(chrono_test, format_default) {
|
||||
@ -1033,7 +1045,7 @@ TEST(chrono_test, glibc_extensions) {
|
||||
{
|
||||
auto t = std::tm();
|
||||
t.tm_year = -5 - 1900;
|
||||
EXPECT_EQ(fmt::format( "{:%Y}", t), "-005");
|
||||
EXPECT_EQ(fmt::format("{:%Y}", t), "-005");
|
||||
EXPECT_EQ(fmt::format("{:%_Y}", t), " -5");
|
||||
EXPECT_EQ(fmt::format("{:%-Y}", t), "-5");
|
||||
}
|
||||
@ -1045,8 +1057,6 @@ TEST(chrono_test, glibc_extensions) {
|
||||
EXPECT_EQ(fmt::format("{:%_m}", t), " 7");
|
||||
EXPECT_EQ(fmt::format("{:%-m}", t), "7");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST(chrono_test, out_of_range) {
|
||||
|
Reference in New Issue
Block a user