Skip to content

<xloctime>: time_put::do_put does not match strftime for the %c and %r specifiers in the "C" locale #6134

@cpplearner

Description

@cpplearner

Describe the bug

The C standard says strftime's %Ec and %c are equivalent to %a %b %e %T %Y and %r is equivalent to %I:%M:%S %p in the "C" locale. UCRT's strftime does something special to meet this requirement, but this magic doesn't extend to time_put::do_put.

[locale.time.put.virtuals]/1 is extremely vague regarding locale-dependent formatting:

the sequence of characters produced for those specifiers that are described as depending on the C locale are instead implementation-defined.

The libcxx test std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp expects do_put to match strftime for these specifiers.

Command-line test case

D:\test>type test-time-put.cpp
#include <cassert>
#include <ctime>
#include <iostream>
#include <locale>

class my_facet : public std::time_put<char, char*>
{
public:
    explicit my_facet(std::size_t refs = 0)
        : time_put(refs) {}
};

int main() {
    const my_facet f(1);
    std::tm t = {};
    t.tm_sec = 6;
    t.tm_min = 3;
    t.tm_hour = 13;
    t.tm_mday = 2;
    t.tm_mon = 4;
    t.tm_year = 109;
    t.tm_wday = 6;
    t.tm_yday = 121;
    t.tm_isdst = 1;
    std::ios str(nullptr);

    {
        char buf[200];
        char* iter = f.put(buf, str, '*', &t, 'c');
        std::string ex(buf, iter);
        std::cout << ex << '\n';
    }
    {
        char buf[200];
        strftime(buf, 200, "%c", &t);
        std::cout << buf << '\n';
    }
    {
        char buf[200];
        char* iter = f.put(buf, str, '*', &t, 'r');
        std::string ex(buf, iter);
        std::cout << ex << '\n';
    }
    {
        char buf[200];
        strftime(buf, 200, "%r", &t);
        std::cout << buf << '\n';
    }
}
D:\test>cl /EHsc test-time-put.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.50.35725 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test-time-put.cpp
Microsoft (R) Incremental Linker Version 14.50.35725.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test-time-put.exe
test-time-put.obj
D:\test>test-time-put.exe
05/02/09 13:03:06
Sat May  2 13:03:06 2009
13:03:06
01:03:06 PM

Expected behavior

do_put has the same output as strftime.

STL version

117ca96

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions