microsoft / microsoft/STL

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

Open
#6,134 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.