mirror of
https://github.com/fmtlib/fmt.git
synced 2026-09-14 06:42:24 +08:00
Fix width and alignment for calendar types (#4935)
This commit is contained in:
parent
56fcd0b945
commit
2012961e3e
@ -1908,11 +1908,8 @@ struct formatter<weekday, Char> : private formatter<std::tm, Char> {
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
this->set_format(detail::string_literal<Char, '%', 'a'>());
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
if (it != end && *it == 'L') {
|
||||
++it;
|
||||
this->set_localized();
|
||||
}
|
||||
use_tm_formatter_ = it != end && *it != '}';
|
||||
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
|
||||
}
|
||||
@ -1922,7 +1919,7 @@ struct formatter<weekday, Char> : private formatter<std::tm, Char> {
|
||||
auto time = std::tm();
|
||||
time.tm_wday = static_cast<int>(wd.c_encoding());
|
||||
if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
|
||||
detail::get_locale loc(this->localized(), ctx.locale());
|
||||
detail::get_locale loc(false, ctx.locale());
|
||||
auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
|
||||
w.on_abbr_weekday();
|
||||
return w.out();
|
||||
@ -1936,6 +1933,7 @@ struct formatter<day, Char> : private formatter<std::tm, Char> {
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
this->set_format(detail::string_literal<Char, '%', 'd'>());
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
use_tm_formatter_ = it != end && *it != '}';
|
||||
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
|
||||
@ -1960,11 +1958,8 @@ struct formatter<month, Char> : private formatter<std::tm, Char> {
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
this->set_format(detail::string_literal<Char, '%', 'b'>());
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
if (it != end && *it == 'L') {
|
||||
++it;
|
||||
this->set_localized();
|
||||
}
|
||||
use_tm_formatter_ = it != end && *it != '}';
|
||||
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
|
||||
}
|
||||
@ -1974,7 +1969,7 @@ struct formatter<month, Char> : private formatter<std::tm, Char> {
|
||||
auto time = std::tm();
|
||||
time.tm_mon = static_cast<int>(static_cast<unsigned>(m)) - 1;
|
||||
if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
|
||||
detail::get_locale loc(this->localized(), ctx.locale());
|
||||
detail::get_locale loc(false, ctx.locale());
|
||||
auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
|
||||
w.on_abbr_month();
|
||||
return w.out();
|
||||
@ -1988,6 +1983,7 @@ struct formatter<year, Char> : private formatter<std::tm, Char> {
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
this->set_format(detail::string_literal<Char, '%', 'Y'>());
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
use_tm_formatter_ = it != end && *it != '}';
|
||||
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
|
||||
@ -2012,6 +2008,7 @@ struct formatter<year_month_day, Char> : private formatter<std::tm, Char> {
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
this->set_format(detail::string_literal<Char, '%', 'F'>());
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
use_tm_formatter_ = it != end && *it != '}';
|
||||
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
|
||||
@ -2106,8 +2103,7 @@ template <typename Char> struct formatter<std::tm, Char> {
|
||||
detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
|
||||
|
||||
protected:
|
||||
auto localized() const -> bool { return specs_.localized(); }
|
||||
FMT_CONSTEXPR void set_localized() { specs_.set_localized(); }
|
||||
FMT_CONSTEXPR void set_format(basic_string_view<Char> fmt) { fmt_ = fmt; }
|
||||
|
||||
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx, bool has_timezone)
|
||||
-> const Char* {
|
||||
|
||||
@ -994,6 +994,57 @@ TEST(chrono_test, out_of_range) {
|
||||
EXPECT_THROW((void)fmt::format("{:%j}", fd), fmt::format_error);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void check_calendar_padding(T value, const char* expected,
|
||||
const char* chrono_format) {
|
||||
EXPECT_EQ(expected, fmt::format("{}", value));
|
||||
EXPECT_EQ(expected, fmt::format("{:}", value));
|
||||
EXPECT_EQ(fmt::format("{:15}", expected), fmt::format("{:15}", value));
|
||||
EXPECT_EQ(fmt::format("{:<15}", expected), fmt::format("{:<15}", value));
|
||||
EXPECT_EQ(fmt::format("{:>15}", expected), fmt::format("{:>15}", value));
|
||||
EXPECT_EQ(fmt::format("{:*^15}", expected), fmt::format("{:*^15}", value));
|
||||
EXPECT_EQ(fmt::format("{:%>15}", expected), fmt::format("{:%>15}", value));
|
||||
EXPECT_EQ(fmt::format("{:L>15}", expected), fmt::format("{:L>15}", value));
|
||||
EXPECT_EQ(fmt::format("{:>15}", expected), fmt::format("{:>{}}", value, 15));
|
||||
EXPECT_EQ(expected, fmt::format("{:1}", value));
|
||||
auto explicit_format = fmt::format("{{:*^15{}}}", chrono_format);
|
||||
auto unpadded_format = fmt::format("{{:{}}}", chrono_format);
|
||||
EXPECT_EQ(fmt::format("{:*^15}",
|
||||
fmt::format(runtime(unpadded_format), value)),
|
||||
fmt::format(runtime(explicit_format), value));
|
||||
EXPECT_THROW((void)fmt::format(runtime("{:>{}}"), value, -1),
|
||||
fmt::format_error);
|
||||
}
|
||||
|
||||
TEST(chrono_test, calendar_padding) {
|
||||
check_calendar_padding(fmt::day(5), "05", "%d");
|
||||
check_calendar_padding(fmt::month(1), "Jan", "%B");
|
||||
check_calendar_padding(fmt::year(2024), "2024", "%y");
|
||||
check_calendar_padding(fmt::weekday(6), "Sat", "%A");
|
||||
check_calendar_padding(
|
||||
fmt::year_month_day(fmt::year(2024), fmt::month(1), fmt::day(5)),
|
||||
"2024-01-05", "%Y/%m/%d");
|
||||
}
|
||||
|
||||
template <typename T> void check_localized_calendar_padding(T value) {
|
||||
auto loc = get_locale("es_ES.UTF-8");
|
||||
auto expected = fmt::format(loc, "{:L}", value);
|
||||
EXPECT_EQ(fmt::format("{:*>15}", expected),
|
||||
fmt::format(loc, "{:*>15L}", value));
|
||||
EXPECT_EQ(fmt::format("{:>15}", expected),
|
||||
fmt::format(loc, "{:>{}L}", value, 15));
|
||||
}
|
||||
|
||||
TEST(chrono_test, localized_calendar_padding) {
|
||||
check_localized_calendar_padding(fmt::month(1));
|
||||
check_localized_calendar_padding(fmt::weekday(6));
|
||||
auto loc = get_locale("es_ES.UTF-8");
|
||||
EXPECT_EQ(fmt::format("{:>15}", fmt::format(loc, "{:L%B}", fmt::month(1))),
|
||||
fmt::format(loc, "{:>15L%B}", fmt::month(1)));
|
||||
EXPECT_EQ(fmt::format("{:>15}", fmt::format(loc, "{:L%A}", fmt::weekday(6))),
|
||||
fmt::format(loc, "{:>15L%A}", fmt::weekday(6)));
|
||||
}
|
||||
|
||||
TEST(chrono_test, year_month_day) {
|
||||
auto loc = get_locale("es_ES.UTF-8");
|
||||
std::locale::global(loc);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user