]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Improve handling of !ok() weekday index in formatting [PR121929]
authorTomasz Kamiński <tkaminsk@redhat.com>
Thu, 9 Oct 2025 12:38:54 +0000 (14:38 +0200)
committerTomasz Kamiński <tkaminsk@redhat.com>
Fri, 10 Oct 2025 05:03:49 +0000 (07:03 +0200)
commitb9a2dfbd3914d23c2e2284ce03decb0be19fa2cb
treedc51d509057a37eb0eee6a61694e8468a58d6917
parentea7fa6bf4876ad0b66a7cb92324f6f8f9b646038
libstdc++: Improve handling of !ok() weekday index in formatting [PR121929]

Previously, formatting a year_month_weekday with the weekday index equal to
0, 6, or 7 (which are !ok() values in the supported range) produced a
seemingly correct day output. For example %Y-%m-%d produced:
 * 2024-09-06 for 2024y/September/Sunday[6] (2024-10-06)
 * 2024-09-25 for 2024y/September/Sunday[0] (2023-08-25)

This patch changes how the internal _M_day value is computed for
year_month_weekday. Instead of converting to local_days then to year_month_day,
_M_day is now set as the number of days since ymd.year()/ymd.month()/0. If this
difference is negative (which occurs when index() is 0), _M_day is set to 0 to
avoid handling negative days of the month.

This change yields identical results for all ok() values. However, for !ok() dates,
it now consistently produces invalid dates, ensuring the formatted output clearly
reflects the !ok input state:
 * 2024-09-36 for 2024y/September/Sunday[6]
 * 2024-09-00 for 2024y/September/Sunday[0]

For consistency, _M_day is computed in the same manner for year_month_weekday_last.

Finally, for year_month_day_last, we fill _M_day directly with ymd.day().
This provides a more efficient implementation and avoids the need to compute
local_days for %Y-%m-%d, %F and similar specifiers.

PR libstdc++/121929

libstdc++-v3/ChangeLog:

* include/bits/chrono_io.h (_ChronoData::_M_fill_aux)
(_ChronoData::_M_fill_aux): Add comment documenting precondition.
(formatter<chrono::year_month_day, _CharT>::format): Compute
local_days inline.
(formatter<chrono::year_month_day_last, _CharT>::format)
(formatter<chrono::year_month_weekday, _CharT>::format)
(formatter<chrono::year_month_weekday_last, _CharT>::format):
Change how the _M_day field is computed.
* testsuite/std/time/year_month_weekday/io.cc: Adjust tests.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
libstdc++-v3/include/bits/chrono_io.h
libstdc++-v3/testsuite/std/time/year_month_weekday/io.cc