`<xloctime>`: `time_put::do_put` does not match `strftime` for the `%c` and `%r` specifiers in the "C" locale
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
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
https://github.com/microsoft/STL/commit/117ca965fe2f7157540edd9df5a62b0e42d7ece2
Additional context
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp and compare time_put::do_put with strftime for %c and %r in the C locale. Trace the do_put entry point and make the implementation produce the same output as strftime, then verify the existing libcxx test and the command-line case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- localization
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100