mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-25 15:21:54 +00:00
More chrono formatting
This commit is contained in:
parent
aa3b5aba41
commit
628f830583
@ -31,6 +31,7 @@ inline null<> gmtime_s(...) { return null<>(); }
|
|||||||
|
|
||||||
enum class numeric_system {
|
enum class numeric_system {
|
||||||
standard,
|
standard,
|
||||||
|
// Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.
|
||||||
alternative
|
alternative
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,10 +65,10 @@ FMT_CONSTEXPR const Char *parse_chrono_format(
|
|||||||
handler.on_full_weekday();
|
handler.on_full_weekday();
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
handler.on_dec0_weekday();
|
handler.on_dec0_weekday(numeric_system::standard);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
handler.on_dec1_weekday();
|
handler.on_dec1_weekday(numeric_system::standard);
|
||||||
break;
|
break;
|
||||||
// Month:
|
// Month:
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -95,6 +96,12 @@ FMT_CONSTEXPR const Char *parse_chrono_format(
|
|||||||
throw format_error("invalid format");
|
throw format_error("invalid format");
|
||||||
c = *ptr++;
|
c = *ptr++;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'w':
|
||||||
|
handler.on_dec0_weekday(numeric_system::alternative);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
handler.on_dec1_weekday(numeric_system::alternative);
|
||||||
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
handler.on_24_hour(numeric_system::alternative);
|
handler.on_24_hour(numeric_system::alternative);
|
||||||
break;
|
break;
|
||||||
@ -123,8 +130,8 @@ struct chrono_format_checker {
|
|||||||
void on_text(const Char *, const Char *) {}
|
void on_text(const Char *, const Char *) {}
|
||||||
void on_abbr_weekday() {}
|
void on_abbr_weekday() {}
|
||||||
void on_full_weekday() {}
|
void on_full_weekday() {}
|
||||||
void on_dec0_weekday() {}
|
void on_dec0_weekday(numeric_system) {}
|
||||||
void on_dec1_weekday() {}
|
void on_dec1_weekday(numeric_system) {}
|
||||||
void on_abbr_month() {}
|
void on_abbr_month() {}
|
||||||
void on_full_month() {}
|
void on_full_month() {}
|
||||||
void on_24_hour(numeric_system) {}
|
void on_24_hour(numeric_system) {}
|
||||||
@ -158,8 +165,8 @@ struct chrono_formatter {
|
|||||||
|
|
||||||
void write(int value, int width) {
|
void write(int value, int width) {
|
||||||
typedef typename int_traits<int>::main_type main_type;
|
typedef typename int_traits<int>::main_type main_type;
|
||||||
main_type n = value;
|
main_type n = to_unsigned(value);
|
||||||
int num_digits = internal::count_digits(n);
|
int num_digits = static_cast<int>(internal::count_digits(n));
|
||||||
if (width > num_digits)
|
if (width > num_digits)
|
||||||
out = std::fill_n(out, width - num_digits, '0');
|
out = std::fill_n(out, width - num_digits, '0');
|
||||||
out = format_decimal<char_type>(out, n, num_digits);
|
out = format_decimal<char_type>(out, n, num_digits);
|
||||||
@ -182,8 +189,8 @@ struct chrono_formatter {
|
|||||||
|
|
||||||
void on_abbr_weekday() {}
|
void on_abbr_weekday() {}
|
||||||
void on_full_weekday() {}
|
void on_full_weekday() {}
|
||||||
void on_dec0_weekday() {}
|
void on_dec0_weekday(numeric_system) {}
|
||||||
void on_dec1_weekday() {}
|
void on_dec1_weekday(numeric_system) {}
|
||||||
void on_abbr_month() {}
|
void on_abbr_month() {}
|
||||||
void on_full_month() {}
|
void on_full_month() {}
|
||||||
|
|
||||||
@ -211,16 +218,23 @@ struct chrono_formatter {
|
|||||||
if (ns == numeric_system::standard)
|
if (ns == numeric_system::standard)
|
||||||
return write(minute, 2);
|
return write(minute, 2);
|
||||||
auto time = tm();
|
auto time = tm();
|
||||||
time.tm_minute = minute;
|
time.tm_min = minute;
|
||||||
format_localized(time, 'M');
|
format_localized(time, 'M');
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_second(numeric_system) {
|
void on_second(numeric_system ns) {
|
||||||
write(to_int(s.count() % 60), 2);
|
auto second = to_int(s.count() % 60);
|
||||||
if (ms != std::chrono::milliseconds()) {
|
if (ns == numeric_system::standard) {
|
||||||
*out++ = '.';
|
write(second, 2);
|
||||||
write(to_int(ms.count()), 3);
|
if (ms != std::chrono::milliseconds()) {
|
||||||
|
*out++ = '.';
|
||||||
|
write(to_int(ms.count()), 3);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
auto time = tm();
|
||||||
|
time.tm_sec = second;
|
||||||
|
format_localized(time, 'S');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -82,6 +82,22 @@ TEST(TimeTest, Chrono) {
|
|||||||
fmt::format("{:%H:%M:%S}", std::chrono::seconds(12345)));
|
fmt::format("{:%H:%M:%S}", std::chrono::seconds(12345)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string format_tm(const std::tm &time, const char *spec,
|
||||||
|
const std::locale &loc) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os.imbue(loc);
|
||||||
|
os << std::put_time(&time, spec);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPECT_TIME(spec, field, value, duration) { \
|
||||||
|
auto time = std::tm(); \
|
||||||
|
time.field = value; \
|
||||||
|
std::locale("ja_JP.utf8"); \
|
||||||
|
EXPECT_EQ(format_tm(time, spec, loc), \
|
||||||
|
fmt::format(loc, "{:" spec "}", std::chrono::duration(value))); \
|
||||||
|
}
|
||||||
|
|
||||||
TEST(TimeTest, ChronoLocale) {
|
TEST(TimeTest, ChronoLocale) {
|
||||||
const char *loc_name = "ja_JP.utf8";
|
const char *loc_name = "ja_JP.utf8";
|
||||||
bool has_locale = false;
|
bool has_locale = false;
|
||||||
@ -94,21 +110,9 @@ TEST(TimeTest, ChronoLocale) {
|
|||||||
fmt::print("{} locale is missing.\n", loc_name);
|
fmt::print("{} locale is missing.\n", loc_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::ostringstream os;
|
EXPECT_TIME("%OH", tm_hour, 14, hours);
|
||||||
auto str = [&] {
|
EXPECT_TIME("%OI", tm_hour, 14, hours);
|
||||||
auto s = os.str();
|
EXPECT_TIME("%OM", tm_min, 42, minutes);
|
||||||
os.str("");
|
EXPECT_TIME("%OS", tm_min, 42, seconds);
|
||||||
return s;
|
|
||||||
};
|
|
||||||
os.imbue(loc);
|
|
||||||
auto time = std::tm();
|
|
||||||
time.tm_hour = 14;
|
|
||||||
os << std::put_time(&time, "%OH");
|
|
||||||
EXPECT_EQ(str(), fmt::format(loc, "{:%OH}", std::chrono::hours(14)));
|
|
||||||
os << std::put_time(&time, "%OI");
|
|
||||||
EXPECT_EQ(str(), fmt::format(loc, "{:%OI}", std::chrono::hours(14)));
|
|
||||||
time.tm_minute = 42;
|
|
||||||
os << std::put_time(&time, "%OM");
|
|
||||||
EXPECT_EQ(str(), fmt::format(loc, "{:%OM}", std::chrono::minutes(42)));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user