Skip to content

Commit 93491a5

Browse files
committed
Cleanup chrono tests and set consistent TZ
1 parent b282144 commit 93491a5

3 files changed

Lines changed: 29 additions & 53 deletions

File tree

.github/workflows/windows.yml

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

4141
- name: Set timezone
42-
run: tzutil /s "Pacific Standard Time"
42+
run: tzutil /s "FLE Standard Time"
4343

4444
- name: Create Build Environment
4545
run: cmake -E make_directory ${{runner.workspace}}/build

include/fmt/chrono.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,7 +2206,8 @@ template <typename Char> struct formatter<std::tm, Char> {
22062206
detail::arg_ref<Char> width_ref_;
22072207

22082208
protected:
2209-
basic_string_view<Char> fmt_;
2209+
basic_string_view<Char> fmt_ =
2210+
detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
22102211

22112212
template <typename Duration, typename FormatContext>
22122213
auto do_format(const std::tm& tm, FormatContext& ctx,
@@ -2261,10 +2262,6 @@ template <typename Char> struct formatter<std::tm, Char> {
22612262

22622263
template <typename Char, typename Duration>
22632264
struct formatter<sys_time<Duration>, Char> : formatter<std::tm, Char> {
2264-
FMT_CONSTEXPR formatter() {
2265-
this->fmt_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
2266-
}
2267-
22682265
template <typename FormatContext>
22692266
auto format(sys_time<Duration> val, FormatContext& ctx) const
22702267
-> decltype(ctx.out()) {
@@ -2303,10 +2300,6 @@ struct formatter<utc_time<Duration>, Char>
23032300

23042301
template <typename Duration, typename Char>
23052302
struct formatter<local_time<Duration>, Char> : formatter<std::tm, Char> {
2306-
FMT_CONSTEXPR formatter() {
2307-
this->fmt_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
2308-
}
2309-
23102303
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
23112304
return this->do_parse(ctx, true);
23122305
}

test/chrono-test.cc

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
#include "util.h" // get_locale
1616

1717
using fmt::runtime;
18+
using fmt::sys_time;
1819
using testing::Contains;
1920

20-
template <typename Duration>
21-
using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
22-
2321
#if defined(__MINGW32__) && !defined(_UCRT)
2422
// Only C89 conversion specifiers when using MSVCRT instead of UCRT
2523
# define FMT_HAS_C99_STRFTIME 0
@@ -240,27 +238,19 @@ TEST(chrono_test, format_to_empty_container) {
240238
EXPECT_EQ(s, "42");
241239
}
242240

243-
TEST(chrono_test, empty_result) { EXPECT_EQ(fmt::format("{}", std::tm()), ""); }
244-
245-
auto equal(const std::tm& lhs, const std::tm& rhs) -> bool {
246-
return lhs.tm_sec == rhs.tm_sec && lhs.tm_min == rhs.tm_min &&
247-
lhs.tm_hour == rhs.tm_hour && lhs.tm_mday == rhs.tm_mday &&
248-
lhs.tm_mon == rhs.tm_mon && lhs.tm_year == rhs.tm_year &&
249-
lhs.tm_wday == rhs.tm_wday && lhs.tm_yday == rhs.tm_yday &&
250-
lhs.tm_isdst == rhs.tm_isdst;
251-
}
252-
253241
TEST(chrono_test, gmtime) {
254242
auto t = std::time(nullptr);
255-
auto tm = *std::gmtime(&t);
256-
EXPECT_TRUE(equal(tm, fmt::gmtime(t)));
257-
}
258-
259-
template <typename TimePoint>
260-
auto strftime_full_utc(TimePoint tp) -> std::string {
261-
auto t = std::chrono::system_clock::to_time_t(tp);
262-
auto tm = *std::gmtime(&t);
263-
return system_strftime("%Y-%m-%d %H:%M:%S", &tm);
243+
auto expected = *std::gmtime(&t);
244+
auto actual = fmt::gmtime(t);
245+
EXPECT_EQ(actual.tm_sec, expected.tm_sec);
246+
EXPECT_EQ(actual.tm_min, expected.tm_min);
247+
EXPECT_EQ(actual.tm_hour, expected.tm_hour);
248+
EXPECT_EQ(actual.tm_mday, expected.tm_mday);
249+
EXPECT_EQ(actual.tm_mon, expected.tm_mon);
250+
EXPECT_EQ(actual.tm_year, expected.tm_year);
251+
EXPECT_EQ(actual.tm_wday, expected.tm_wday);
252+
EXPECT_EQ(actual.tm_yday, expected.tm_yday);
253+
EXPECT_EQ(actual.tm_isdst, expected.tm_isdst);
264254
}
265255

266256
template <typename Time> void test_time(Time time) {
@@ -345,6 +335,11 @@ TEST(chrono_test, local_time) {
345335
fmt::format_error, "no timezone");
346336
}
347337

338+
TEST(chrono_test, tm) {
339+
auto time = fmt::gmtime(290088000);
340+
test_time(time);
341+
}
342+
348343
TEST(chrono_test, daylight_savings_time_end) {
349344
// 2024-10-27 03:05 as the number of seconds since epoch in Europe/Kyiv time.
350345
// It is slightly after the DST end and passing it to to_sys will result in
@@ -357,8 +352,6 @@ TEST(chrono_test, daylight_savings_time_end) {
357352
EXPECT_EQ(fmt::format("{}", t), "2024-10-27 03:05:00");
358353
}
359354

360-
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
361-
362355
TEST(chrono_test, format_default) {
363356
EXPECT_EQ(fmt::format("{}", std::chrono::seconds(42)), "42s");
364357
EXPECT_EQ(fmt::format("{}", std::chrono::duration<int, std::atto>(42)),
@@ -535,12 +528,12 @@ auto format_tm(const std::tm& time, fmt::string_view spec,
535528
TEST(chrono_test, locale) {
536529
auto loc = get_locale("ja_JP.utf8");
537530
if (loc == std::locale::classic()) return;
538-
# define EXPECT_TIME(spec, time, duration) \
539-
{ \
540-
auto jp_loc = std::locale("ja_JP.utf8"); \
541-
EXPECT_EQ(format_tm(time, spec, jp_loc), \
542-
fmt::format(jp_loc, "{:L" spec "}", duration)); \
543-
}
531+
#define EXPECT_TIME(spec, time, duration) \
532+
{ \
533+
auto jp_loc = std::locale("ja_JP.utf8"); \
534+
EXPECT_EQ(format_tm(time, spec, jp_loc), \
535+
fmt::format(jp_loc, "{:L" spec "}", duration)); \
536+
}
544537
EXPECT_TIME("%OH", make_hour(14), std::chrono::hours(14));
545538
EXPECT_TIME("%OI", make_hour(14), std::chrono::hours(14));
546539
EXPECT_TIME("%OM", make_minute(42), std::chrono::minutes(42));
@@ -787,8 +780,6 @@ TEST(chrono_test, cpp20_duration_subsecond_support) {
787780
"-01:01.250000");
788781
}
789782

790-
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
791-
792783
// Disable the utc_clock test for windows, as the icu.dll used for tzdb
793784
// (time zone database) is not shipped with many windows versions.
794785
#if FMT_USE_UTC_TIME && !defined(_WIN32)
@@ -861,19 +852,11 @@ TEST(chrono_test, timestamp_sub_seconds) {
861852
auto t8 =
862853
sys_time<std::chrono::nanoseconds>(std::chrono::nanoseconds(123456789));
863854
EXPECT_EQ(fmt::format("{:%S}", t8), "00.123456789");
855+
EXPECT_EQ(fmt::format("{:%T}", t8), "00:00:00.123456789");
864856

865-
auto t9 = std::chrono::time_point_cast<std::chrono::nanoseconds>(
866-
std::chrono::system_clock::now());
867-
auto t9_sec = std::chrono::time_point_cast<std::chrono::seconds>(t9);
868-
auto t9_sub_sec_part = fmt::format("{0:09}", (t9 - t9_sec).count());
869-
EXPECT_EQ(fmt::format("{}.{}", strftime_full_utc(t9_sec), t9_sub_sec_part),
870-
fmt::format("{:%Y-%m-%d %H:%M:%S}", t9));
871-
EXPECT_EQ(fmt::format("{}.{}", strftime_full_utc(t9_sec), t9_sub_sec_part),
872-
fmt::format("{:%Y-%m-%d %T}", t9));
873-
874-
auto t10 =
857+
auto t9 =
875858
sys_time<std::chrono::milliseconds>(std::chrono::milliseconds(2000));
876-
EXPECT_EQ(fmt::format("{:%S}", t10), "02.000");
859+
EXPECT_EQ(fmt::format("{:%S}", t9), "02.000");
877860

878861
auto epoch = sys_time<std::chrono::milliseconds>();
879862
auto d = std::chrono::milliseconds(250);

0 commit comments

Comments
 (0)