From cc2651ddacc6187339bad7f7f8c90806a0a657ff Mon Sep 17 00:00:00 2001 From: Elnar Dakeshov <55715127+eldakesh-ms@users.noreply.github.com> Date: Tue, 20 Apr 2021 16:28:22 -0700 Subject: [PATCH] : Fix hh_mm_ss subsecond formatting for floats (#1866) * : Fix hh_mm_ss subsecond formatting for floats Before, the same formatting string was used for floats and integrals. This meant that large floats were formatted using exponent notaion and small floats were not, and it also meant there was an extra period in a time, as the subseconds could be fractions of a subsecond (say .4 nanoseconds). Now if the subseconds are floats, we force fixed formatting to get the right number of leading zeroes and a precision of 0 to round off fractions of subseconds. * Floor subseconds --- stl/inc/chrono | 11 ++++++++--- .../test.cpp | 8 ++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index ef8d383e0a..0035ee7102 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -5469,9 +5469,14 @@ namespace chrono { void _Write_seconds(basic_ostream<_CharT, _Traits>& _Os, const hh_mm_ss<_Duration>& _Val) { _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:02}"), _Val.seconds().count()); if constexpr (hh_mm_ss<_Duration>::fractional_width > 0) { - _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{0}{1:0{2}}"), - _STD use_facet>(_Os.getloc()).decimal_point(), _Val.subseconds().count(), - _Val.fractional_width); + _Os << _STD use_facet>(_Os.getloc()).decimal_point(); + if constexpr (treat_as_floating_point_v::precision::rep>) { + _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), _STD floor(_Val.subseconds().count()), + _Val.fractional_width); + } else { + _Os << _STD format( + _STATICALLY_WIDEN(_CharT, "{:0{}}"), _Val.subseconds().count(), _Val.fractional_width); + } } } diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp index 0305df6786..4cdaac2844 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp @@ -593,6 +593,14 @@ void test_hh_mm_ss_formatter() { empty_braces_helper(hh_mm_ss{4083007ms}, STR("01:08:03.007")); empty_braces_helper(hh_mm_ss{65745123ms}, STR("18:15:45.123")); empty_braces_helper(hh_mm_ss{65745s}, STR("18:15:45")); + empty_braces_helper(hh_mm_ss{0.1ns}, STR("00:00:00.000000000")); + empty_braces_helper(hh_mm_ss{1.45ns}, STR("00:00:00.000000001")); + empty_braces_helper(hh_mm_ss{1.56ns}, STR("00:00:00.000000001")); + empty_braces_helper(hh_mm_ss{1e+8ns}, STR("00:00:00.100000000")); + empty_braces_helper(hh_mm_ss{999'999.9us}, STR("00:00:00.999999")); + empty_braces_helper(hh_mm_ss{59'999'999.9us}, STR("00:00:59.999999")); + empty_braces_helper(hh_mm_ss{3'599'999'999.9us}, STR("00:59:59.999999")); + empty_braces_helper(hh_mm_ss{86'399'999'999.9us}, STR("23:59:59.999999")); assert(format(STR("{:%H %I %M %S %r %R %T %p}"), hh_mm_ss{13h + 14min + 15351ms}) == STR("13 01 14 15.351 01:14:15 PM 13:14 13:14:15.351 PM"));