Skip to content

Commit fbaaa59

Browse files
phprusvitaut
authored andcommitted
Improve week of the year formatter
1 parent cde44dd commit fbaaa59

File tree

1 file changed

+31
-36
lines changed

1 file changed

+31
-36
lines changed

include/fmt/chrono.h

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,7 @@ struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
14011401

14021402
template <typename FormatContext, typename OutputIt> struct tm_formatter {
14031403
using char_type = typename FormatContext::char_type;
1404+
static constexpr int daysperweek = 7;
14041405

14051406
FormatContext& ctx;
14061407
OutputIt out;
@@ -1415,8 +1416,7 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14151416
int upper;
14161417
int lower;
14171418
};
1418-
auto tm_split_year() const -> split_year {
1419-
auto year = tm_year();
1419+
auto tm_split_year(int year) const -> split_year {
14201420
auto q = year / 100;
14211421
auto r = year % 100;
14221422
if (r < 0) {
@@ -1429,8 +1429,9 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14291429
auto hour = tm.tm_hour % 12;
14301430
return hour == 0 ? 12 : hour;
14311431
}
1432-
static constexpr char digits1(size_t value) {
1433-
return detail::digits2(value)[1];
1432+
void write1(size_t value) { *out++ = detail::digits2(value)[1]; }
1433+
void write2(size_t value) {
1434+
out = std::copy_n(detail::digits2(value), 2, out);
14341435
}
14351436

14361437
explicit tm_formatter(FormatContext& ctx_, OutputIt out_, const std::tm& tm_)
@@ -1470,14 +1471,14 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14701471
void on_full_weekday() { format_localized('A'); }
14711472
void on_dec0_weekday(numeric_system ns) {
14721473
if (ns == numeric_system::standard) {
1473-
*out++ = digits1(detail::to_unsigned(tm.tm_wday));
1474+
write1(detail::to_unsigned(tm.tm_wday));
14741475
} else {
14751476
format_localized('w', 'O');
14761477
}
14771478
}
14781479
void on_dec1_weekday(numeric_system ns) {
14791480
if (ns == numeric_system::standard) {
1480-
*out++ = digits1(detail::to_unsigned(tm.tm_wday == 0 ? 7 : tm.tm_wday));
1481+
write1(detail::to_unsigned(tm.tm_wday == 0 ? daysperweek : tm.tm_wday));
14811482
} else {
14821483
format_localized('u', 'O');
14831484
}
@@ -1496,10 +1497,10 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
14961497
}
14971498
void on_us_date() {
14981499
char buf[8];
1499-
detail::write_digit2_separated(buf, detail::to_unsigned(tm.tm_mon + 1),
1500-
detail::to_unsigned(tm.tm_mday),
1501-
detail::to_unsigned(tm_split_year().lower),
1502-
'/');
1500+
detail::write_digit2_separated(
1501+
buf, detail::to_unsigned(tm.tm_mon + 1),
1502+
detail::to_unsigned(tm.tm_mday),
1503+
detail::to_unsigned(tm_split_year(tm_year()).lower), '/');
15031504
out = std::copy_n(buf, sizeof(buf), out);
15041505
}
15051506
void on_iso_date() {
@@ -1529,19 +1530,17 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
15291530
}
15301531
void on_last2_year(numeric_system ns) {
15311532
if (ns == numeric_system::standard) {
1532-
out = std::copy_n(
1533-
detail::digits2(detail::to_unsigned(tm_split_year().lower)), 2, out);
1533+
write2(detail::to_unsigned(tm_split_year(tm_year()).lower));
15341534
} else {
15351535
format_localized('y', 'O');
15361536
}
15371537
}
15381538
void on_offset_year() { format_localized('y', 'E'); }
15391539
void on_base_year(numeric_system ns) {
15401540
if (ns == numeric_system::standard) {
1541-
auto split = tm_split_year();
1541+
auto split = tm_split_year(tm_year());
15421542
if (split.upper >= 0 && split.upper < 100) {
1543-
out = std::copy_n(detail::digits2(detail::to_unsigned(split.upper)), 2,
1544-
out);
1543+
write2(detail::to_unsigned(split.upper));
15451544
} else {
15461545
out = detail::write<char_type>(out, split.upper);
15471546
}
@@ -1551,31 +1550,32 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
15511550
}
15521551
void on_dec_month(numeric_system ns) {
15531552
if (ns == numeric_system::standard) {
1554-
out = std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_mon + 1)), 2,
1555-
out);
1553+
write2(detail::to_unsigned(tm.tm_mon + 1));
15561554
} else {
15571555
format_localized('m', 'O');
15581556
}
15591557
}
15601558
void on_dec0_week_of_year(numeric_system ns) {
1561-
// TODO: Optimization
15621559
if (ns == numeric_system::standard) {
1563-
format_localized('U');
1560+
write2(detail::to_unsigned((tm.tm_yday + daysperweek - tm.tm_wday) /
1561+
daysperweek));
15641562
} else {
15651563
format_localized('U', 'O');
15661564
}
15671565
}
15681566
void on_dec1_week_of_year(numeric_system ns) {
1569-
// TODO: Optimization
15701567
if (ns == numeric_system::standard) {
1571-
format_localized('W');
1568+
write2(detail::to_unsigned(
1569+
(tm.tm_yday + daysperweek -
1570+
(tm.tm_wday == 0 ? (daysperweek - 1) : (tm.tm_wday - 1))) /
1571+
daysperweek));
15721572
} else {
15731573
format_localized('W', 'O');
15741574
}
15751575
}
15761576
void on_iso_week_of_year(numeric_system ns) {
1577-
// TODO: Optimization
15781577
if (ns == numeric_system::standard) {
1578+
// TODO: Optimization
15791579
format_localized('V');
15801580
} else {
15811581
format_localized('V', 'O');
@@ -1591,13 +1591,12 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
15911591
}
15921592
void on_day_of_year() {
15931593
auto yday = tm.tm_yday + 1;
1594-
*out++ = digits1(detail::to_unsigned(yday / 100));
1595-
out = std::copy_n(detail::digits2(detail::to_unsigned(yday % 100)), 2, out);
1594+
write1(detail::to_unsigned(yday / 100));
1595+
write2(detail::to_unsigned(yday % 100));
15961596
}
15971597
void on_day_of_month_zero(numeric_system ns) {
15981598
if (ns == numeric_system::standard) {
1599-
out =
1600-
std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_mday)), 2, out);
1599+
write2(detail::to_unsigned(tm.tm_mday));
16011600
} else {
16021601
format_localized('d', 'O');
16031602
}
@@ -1613,41 +1612,37 @@ template <typename FormatContext, typename OutputIt> struct tm_formatter {
16131612
}
16141613
void on_24_hour(numeric_system ns) {
16151614
if (ns == numeric_system::standard) {
1616-
out =
1617-
std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_hour)), 2, out);
1615+
write2(detail::to_unsigned(tm.tm_hour));
16181616
} else {
16191617
format_localized('H', 'O');
16201618
}
16211619
}
16221620
void on_12_hour(numeric_system ns) {
16231621
if (ns == numeric_system::standard) {
1624-
out = std::copy_n(detail::digits2(detail::to_unsigned(tm_hour12())), 2,
1625-
out);
1622+
write2(detail::to_unsigned(tm_hour12()));
16261623
} else {
16271624
format_localized('I', 'O');
16281625
}
16291626
}
16301627
void on_minute(numeric_system ns) {
16311628
if (ns == numeric_system::standard) {
1632-
out =
1633-
std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_min)), 2, out);
1629+
write2(detail::to_unsigned(tm.tm_min));
16341630
} else {
16351631
format_localized('M', 'O');
16361632
}
16371633
}
16381634
void on_second(numeric_system ns) {
16391635
if (ns == numeric_system::standard) {
1640-
out =
1641-
std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_sec)), 2, out);
1636+
write2(detail::to_unsigned(tm.tm_sec));
16421637
} else {
16431638
format_localized('S', 'O');
16441639
}
16451640
}
16461641
void on_12_hour_time() { format_localized('r'); }
16471642
void on_24_hour_time() {
1648-
out = std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_hour)), 2, out);
1643+
write2(detail::to_unsigned(tm.tm_hour));
16491644
*out++ = ':';
1650-
out = std::copy_n(detail::digits2(detail::to_unsigned(tm.tm_min)), 2, out);
1645+
write2(detail::to_unsigned(tm.tm_min));
16511646
}
16521647
void on_iso_time() {
16531648
char buf[8];

0 commit comments

Comments
 (0)