https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120481
Bug ID: 120481 Summary: Incorrect format result for using specifier with multi-digit month, day or weekday Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tkaminsk at gcc dot gnu.org Target Milestone: --- When formatting a month of day or month value with tree digits using '%m' or '%d' specifier, the implementation prints two digit value, not equal to source: ``` using namespace std::chrono; std::cout << std::format("{:%m}", month(120)) << std::endl; // prints 99 std::cout << std::format("{:%d}", day(167)) << std::endl; // prints 39 ``` https://godbolt.org/z/zf8Wbjdfd The standard specifies that both month and day are capable of storing values of [0, 255] (https://eel.is/c++draft/time#cal.month.members-1 and https://eel.is/c++draft/time.cal#day.members-1), and the https://eel.is/c++draft/tab:time.format.spec table specifies that: %d The day of month as a decimal number. If the result is a single decimal digit, it is prefixed with 0. The modified command %Od produces the locale's alternative representation. %m The month as a decimal number. Jan is 01. If the result is a single digit, it is prefixed with 0. The modified command %Om produces the locale's alternative representation. This yields to not suprising results, were !ok() year_month_day is formatted with empty format spec '%F', where we print '2024-99-99 is not a valid date' for both of above: ``` std::cout << std::format("{}", year(2024)/month(120)/day(100)) << std::endl; std::cout << year(2024)/month(120)/day(100) << std::endl; ``` https://godbolt.org/z/5rzq147q9 We also produce inconsistent result for negative years when using %F and %Y-%m-%d, where using %F does not properly pad year to 4 digits. ``` using namespace std::chrono; std::cout << std::format("{:}", year(-2)/month(1)/day(2)) << std::endl; std::cout << std::format("{:%F}", year(-2)/month(1)/day(2)) << std::endl; std::cout << std::format("{:%Y-%m-%d}", year(-2)/month(1)/day(2)) << std::endl; ``` https://godbolt.org/z/1o94ezhv6