https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117214

            Bug ID: 117214
           Summary: chrono format error for time point using %c: D_T_FMT
                    cannot be directly used as chrono-specs
           Product: gcc
           Version: 14.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xu2k3l4 at outlook dot com
  Target Milestone: ---

test code:

```cpp
#include <chrono>
#include <locale>
#include <print>
int main(int argc, char **argv)
{
        auto timepoint = std::chrono::sys_seconds();
        for (int i = 1; i < argc; ++i)
        {
                const char *localename = argv[i];
                std::locale::global(std::locale(localename));
                try
                {
                        std::println("{}: {:L%c}", localename, timepoint);
                }
                catch (std::format_error &e)
                {
                        std::println(stderr, "ERROR {}: {}", localename,
e.what());
                }
        }
}
```

`locale-gen` many locales, and run the program with these locales. The program
shows 4 kinds of outputs (x86_64-pc-linux-gnu gcc 14.2.1):
1. "(some normal time point)", which is good.
2. "chrono format error: invalid  specifier in chrono-specs", e.g. aa_DJ (uses
%l), ar_SA (uses %k), ca_AD (uses %-d).
3. "chrono format error: no '%' at start of chrono-specs", e.g. az_IR (starts
with U+202B <RIGHT-TO-LEFT EMBEDDING>).
4. "chrono format error: invalid  modifier in chrono-specs", e.g. my_MM (uses
%OC).

#3 is easier to fix. C++ standard [time.format] says chrono-specs must starts
with a '%' (probably to seperate chrono-specs with fill-and-align & width &
precision). libstdc++ should output characters before any '%' and have the
sub-`vformat_to`'s format string start with '%' in `__formatter_chrono::_M_c`.

#2 and #4 are somehow tougher. chrono-specs follows strftime's format, but
D_T_FMT from glibc contains glibc extensions which are considered invalid by
chrono-specs. Maybe libstdc++ can directly use `strftime` in libc, or just
filter out these extension (e.g. substitude %l as %I, %k as %H, %-* as %*)?

Reply via email to