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

Reply via email to