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"
|
modifier: "E" | "O"
|
||||||
chrono_type: "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" | "F" |
|
chrono_type: "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" | "F" |
|
||||||
: "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" | "n" | "p" |
|
: "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" | "n" | "p" |
|
||||||
: "q" | "Q" | "r" | "R" | "S" | "t" | "T" | "u" | "U" | "V" |
|
: "P" | "q" | "Q" | "r" | "R" | "S" | "t" | "T" | "u" | "U" |
|
||||||
: "w" | "W" | "x" | "X" | "y" | "Y" | "z" | "Z" | "%"
|
: "V" | "w" | "W" | "x" | "X" | "y" | "Y" | "z" | "Z" | "%"
|
||||||
|
|
||||||
Literal chars are copied unchanged to the output. Precision is valid only for
|
Literal chars are copied unchanged to the output. Precision is valid only for
|
||||||
``std::chrono::duration`` types with a floating-point representation type.
|
``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'`` | 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 unit suffix. |
|
||||||
+---------+--------------------------------------------------------------------+
|
+---------+--------------------------------------------------------------------+
|
||||||
| ``'Q'`` | The duration's numeric value (as if extracted via ``.count()``). |
|
| ``'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':
|
case 'p':
|
||||||
handler.on_am_pm();
|
handler.on_am_pm();
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
handler.on_am_pm_lower();
|
||||||
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
handler.on_duration_value();
|
handler.on_duration_value();
|
||||||
break;
|
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_24_hour_time() { unsupported(); }
|
||||||
FMT_CONSTEXPR void on_iso_time() { unsupported(); }
|
FMT_CONSTEXPR void on_iso_time() { unsupported(); }
|
||||||
FMT_CONSTEXPR void on_am_pm() { 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_value() { unsupported(); }
|
||||||
FMT_CONSTEXPR void on_duration_unit() { unsupported(); }
|
FMT_CONSTEXPR void on_duration_unit() { unsupported(); }
|
||||||
FMT_CONSTEXPR void on_utc_offset(numeric_system) { 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_24_hour_time() {}
|
||||||
FMT_CONSTEXPR void on_iso_time() {}
|
FMT_CONSTEXPR void on_iso_time() {}
|
||||||
FMT_CONSTEXPR void on_am_pm() {}
|
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_utc_offset(numeric_system) {}
|
||||||
FMT_CONSTEXPR void on_tz_name() {}
|
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.
|
// These apply to chrono durations but not tm.
|
||||||
void on_duration_value() {}
|
void on_duration_value() {}
|
||||||
void on_duration_unit() {}
|
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_24_hour_time() {}
|
||||||
FMT_CONSTEXPR void on_iso_time() {}
|
FMT_CONSTEXPR void on_iso_time() {}
|
||||||
FMT_CONSTEXPR void on_am_pm() {}
|
FMT_CONSTEXPR void on_am_pm() {}
|
||||||
|
FMT_CONSTEXPR void on_am_pm_lower() {}
|
||||||
FMT_CONSTEXPR void on_duration_value() const {
|
FMT_CONSTEXPR void on_duration_value() const {
|
||||||
if (has_precision_integral) {
|
if (has_precision_integral) {
|
||||||
FMT_THROW(format_error("precision not allowed for this argument type"));
|
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);
|
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() {
|
void on_duration_value() {
|
||||||
if (handle_nan_inf()) return;
|
if (handle_nan_inf()) return;
|
||||||
write_sign();
|
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");
|
||||||
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