Support %P (lowercase am/pm) glibc extension
Fun fact: in glibc you can also spell %P %#p, # meaning “swap case”. I haven’t implemented glibc’s ^ or # flags.
This commit is contained in:
parent
3a69529e8b
commit
b242b8f326
@ -315,8 +315,8 @@ Format specifications for chrono duration and time point types as well as
|
||||
modifier: "E" | "O"
|
||||
chrono_type: "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" | "F" |
|
||||
: "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" | "n" | "p" |
|
||||
: "q" | "Q" | "r" | "R" | "S" | "t" | "T" | "u" | "U" | "V" |
|
||||
: "w" | "W" | "x" | "X" | "y" | "Y" | "z" | "Z" | "%"
|
||||
: "P" | "q" | "Q" | "r" | "R" | "S" | "t" | "T" | "u" | "U" |
|
||||
: "V" | "w" | "W" | "x" | "X" | "y" | "Y" | "z" | "Z" | "%"
|
||||
|
||||
Literal chars are copied unchanged to the output. Precision is valid only for
|
||||
``std::chrono::duration`` types with a floating-point representation type.
|
||||
@ -396,6 +396,8 @@ The available presentation types (*chrono_type*) are:
|
||||
+---------+--------------------------------------------------------------------+
|
||||
| ``'p'`` | The AM/PM designations associated with a 12-hour clock. |
|
||||
+---------+--------------------------------------------------------------------+
|
||||
| ``'P'`` | ``%p``, but lowercase (am/pm). (GNU/glibc extension.) |
|
||||
+---------+--------------------------------------------------------------------+
|
||||
| ``'q'`` | The duration's unit suffix. |
|
||||
+---------+--------------------------------------------------------------------+
|
||||
| ``'Q'`` | The duration's numeric value (as if extracted via ``.count()``). |
|
||||
|
||||
@ -838,6 +838,9 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin,
|
||||
case 'p':
|
||||
handler.on_am_pm();
|
||||
break;
|
||||
case 'P':
|
||||
handler.on_am_pm_lower();
|
||||
break;
|
||||
case 'Q':
|
||||
handler.on_duration_value();
|
||||
break;
|
||||
@ -976,6 +979,7 @@ template <typename Derived> struct null_chrono_spec_handler {
|
||||
FMT_CONSTEXPR void on_24_hour_time() { unsupported(); }
|
||||
FMT_CONSTEXPR void on_iso_time() { unsupported(); }
|
||||
FMT_CONSTEXPR void on_am_pm() { unsupported(); }
|
||||
FMT_CONSTEXPR void on_am_pm_lower() { unsupported(); }
|
||||
FMT_CONSTEXPR void on_duration_value() { unsupported(); }
|
||||
FMT_CONSTEXPR void on_duration_unit() { unsupported(); }
|
||||
FMT_CONSTEXPR void on_utc_offset(numeric_system) { unsupported(); }
|
||||
@ -1019,6 +1023,7 @@ struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
|
||||
FMT_CONSTEXPR void on_24_hour_time() {}
|
||||
FMT_CONSTEXPR void on_iso_time() {}
|
||||
FMT_CONSTEXPR void on_am_pm() {}
|
||||
FMT_CONSTEXPR void on_am_pm_lower() {}
|
||||
FMT_CONSTEXPR void on_utc_offset(numeric_system) {}
|
||||
FMT_CONSTEXPR void on_tz_name() {}
|
||||
};
|
||||
@ -1636,6 +1641,15 @@ class tm_writer {
|
||||
}
|
||||
}
|
||||
|
||||
void on_am_pm_lower() {
|
||||
if (is_classic_) {
|
||||
*out_++ = tm_hour() < 12 ? 'a' : 'p';
|
||||
*out_++ = 'm';
|
||||
} else {
|
||||
format_localized('P');
|
||||
}
|
||||
}
|
||||
|
||||
// These apply to chrono durations but not tm.
|
||||
void on_duration_value() {}
|
||||
void on_duration_unit() {}
|
||||
@ -1656,6 +1670,7 @@ struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
|
||||
FMT_CONSTEXPR void on_24_hour_time() {}
|
||||
FMT_CONSTEXPR void on_iso_time() {}
|
||||
FMT_CONSTEXPR void on_am_pm() {}
|
||||
FMT_CONSTEXPR void on_am_pm_lower() {}
|
||||
FMT_CONSTEXPR void on_duration_value() const {
|
||||
if (has_precision_integral) {
|
||||
FMT_THROW(format_error("precision not allowed for this argument type"));
|
||||
@ -2011,6 +2026,11 @@ struct chrono_formatter {
|
||||
format_tm(time(), &tm_writer_type::on_am_pm);
|
||||
}
|
||||
|
||||
void on_am_pm_lower() {
|
||||
if (handle_nan_inf()) return;
|
||||
format_tm(time(), &tm_writer_type::on_am_pm_lower);
|
||||
}
|
||||
|
||||
void on_duration_value() {
|
||||
if (handle_nan_inf()) return;
|
||||
write_sign();
|
||||
|
||||
@ -973,4 +973,12 @@ TEST(chrono_test, glibc_extensions) {
|
||||
EXPECT_EQ(fmt::format("{:%_S}", d), " 3.140000");
|
||||
EXPECT_EQ(fmt::format("{:%-S}", d), "3.140000");
|
||||
}
|
||||
|
||||
{
|
||||
// %p is standard, %P is glibc
|
||||
const auto tm_am = make_tm(1970, 1, 1, 0, 0, 0);
|
||||
const auto tm_pm = make_tm(1970, 1, 1, 12, 0, 0);
|
||||
EXPECT_EQ(fmt::format("{:%p,%P}", tm_am), "AM,am");
|
||||
EXPECT_EQ(fmt::format("{:%p,%P}", tm_pm), "PM,pm");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user