microsoft / microsoft/STL

`<xloctime>`: `get_time("%x")` can't parse what `put_time("%x")` generates with imbued locale

Open
#2,641 3 comments 1 reaction 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

C:\Temp>type meow.cpp
#include <ctime>
#include <iomanip>
#include <iostream>
#include <locale>
#include <sstream>
using namespace std;

string getDate() {
    tm t{};
    t.tm_mon  = 3; // April
    t.tm_mday = 1; // 1st
    t.tm_year = 122; // 2022
    ostringstream oss;
    oss.imbue(locale{"en-US"});
    oss << put_time(&t, "%x");
    return oss.str();
}

void parseDate(const string& date) {
    tm t{};
    istringstream iss(date);
    iss.imbue(locale{"en-US"});
    iss >> get_time(&t, "%x");

    cout << R"(get_time(&t, "%x") returned:)" << endl;
    cout << "months since January, [0, 11]: " << t.tm_mon << endl;
    cout << "    day of the month, [1, 31]: " << t.tm_mday << endl;
    cout << "             years since 1900: " << t.tm_year << endl;
}

int main() {
    const string s = getDate();
    cout << R"(put_time(&t, "%x"): )" << s << endl;
    parseDate(s);
}
C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp
meow.cpp

C:\Temp>meow
put_time(&t, "%x"): 4/1/2022
get_time(&t, "%x") returned:
months since January, [0, 11]: 0
    day of the month, [1, 31]: 4
             years since 1900: 120

Root cause:

https://github.com/microsoft/STL/blob/52505b9d3249c50b33eb22152a1f18f208ea2959/stl/inc/xloctime#L475-L477

This is always using "%d / %m / %y" regardless of the locale. In addition to swapping the month and the day for the en-US locale, note that %y is a 2-digit year, so "2022" (t.tm_year = 122) is being parsed as "20" (t.tm_year = 120).

Originally reported as DevCom-1359934 (internal VSO-1289317 / AB#1289317 ) and DevCom-10002862 (internal VSO-1513676 / AB#1513676 ) - as Lewis Pringle noted, "This is a long-standing bug - not a regression."

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 with the linked stl/inc/xloctime lines 475-477 and run the provided MSVC reproduction using an en-US locale. The fix is complete when get_time("%x") correctly parses the string produced by put_time("%x"), including the month/day order and four-digit year shown in the report.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.