Skip to content

Commit 2015800

Browse files
committed
Implement %j specifier for std::chrono::duration
This adds support for `%j` presentation type for duration types: > "If the type being formatted is a specialization of duration, the decimal number of days without padding." Fixes fmtlib#3643.
1 parent 99b9fbf commit 2015800

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

include/fmt/chrono.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,7 @@ struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
16221622

16231623
template <typename Char>
16241624
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
1625+
FMT_CONSTEXPR void on_day_of_year() {}
16251626
FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}
16261627
FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}
16271628
FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}
@@ -1806,6 +1807,7 @@ struct chrono_formatter {
18061807
return true;
18071808
}
18081809

1810+
Rep days() const { return static_cast<Rep>(s.count() / 86400); }
18091811
Rep hour() const { return static_cast<Rep>(mod((s.count() / 3600), 24)); }
18101812

18111813
Rep hour12() const {
@@ -1884,10 +1886,14 @@ struct chrono_formatter {
18841886
void on_dec0_week_of_year(numeric_system) {}
18851887
void on_dec1_week_of_year(numeric_system) {}
18861888
void on_iso_week_of_year(numeric_system) {}
1887-
void on_day_of_year() {}
18881889
void on_day_of_month(numeric_system) {}
18891890
void on_day_of_month_space(numeric_system) {}
18901891

1892+
void on_day_of_year() {
1893+
if (handle_nan_inf()) return;
1894+
return write(days(), 0);
1895+
}
1896+
18911897
void on_24_hour(numeric_system ns, pad_type pad) {
18921898
if (handle_nan_inf()) return;
18931899

test/chrono-test.cc

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ using testing::Contains;
2424
# define FMT_HAS_C99_STRFTIME 1
2525
#endif
2626

27+
#if !(defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907L)
28+
using days = std::chrono::duration<std::chrono::hours::rep, std::ratio<86400>>;
29+
#endif
30+
2731
auto make_tm() -> std::tm {
2832
auto time = std::tm();
2933
time.tm_mday = 1;
@@ -533,6 +537,12 @@ TEST(chrono_test, format_specs) {
533537
EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(24)));
534538
EXPECT_EQ("04", fmt::format("{:%I}", std::chrono::hours(4)));
535539
EXPECT_EQ("02", fmt::format("{:%I}", std::chrono::hours(14)));
540+
# if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907L
541+
EXPECT_EQ("12345", fmt::format("{:%j}", std::chrono::days(12345)));
542+
# else
543+
EXPECT_EQ("12345", fmt::format("{:%j}", days(12345)));
544+
# endif
545+
EXPECT_EQ("12345", fmt::format("{:%j}", std::chrono::hours(12345*24+12)));
536546
EXPECT_EQ("03:25:45",
537547
fmt::format("{:%H:%M:%S}", std::chrono::seconds(12345)));
538548
EXPECT_EQ("03:25", fmt::format("{:%R}", std::chrono::seconds(12345)));

0 commit comments

Comments
 (0)