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