Skip to content

<xloctime>: Fix time_put::do_put to correctly handle %c and %r formatting in "C" locale#6299

Open
ferhatgec wants to merge 2 commits into
microsoft:mainfrom
ferhatgec:fix/gh-6134
Open

<xloctime>: Fix time_put::do_put to correctly handle %c and %r formatting in "C" locale#6299
ferhatgec wants to merge 2 commits into
microsoft:mainfrom
ferhatgec:fix/gh-6134

Conversation

@ferhatgec
Copy link
Copy Markdown
Contributor

Fixes #6134.

Description
The C standard requires the %c and %r specifiers to be equivalent to %a %b %e %T %Y and %I:%M:%S %p respectively in the "C" locale (N3220 § 7.29.3.5/7). While the standard C strftime might handle this correctly, the internal UCRT functions _Strftime and _Wcsftime used by <xloctime> do not provide this expected output. This causes a mismatch when using std::time_put::do_put.

This PR introduces a workaround in time_put::do_put. When _Iosbase.getloc() == locale::classic(), it explicitly overrides the format strings for the %c and %r specifiers with the standard-mandated sequences before passing them to _Strftime / _Wcsftime. Since this problem only occurs in "C" locale, this workaround resolves the issue without affecting others.

Testing

  • The workaround allows the failing libcxx test to pass.
  • Removed std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp from tests/libcxx/expected_results.txt.

Copilot AI review requested due to automatic review settings May 28, 2026 03:25
@ferhatgec ferhatgec requested a review from a team as a code owner May 28, 2026 03:25
@github-project-automation github-project-automation Bot moved this to Initial Review in STL Code Reviews May 28, 2026
@StephanTLavavej StephanTLavavej added the bug Something isn't working label May 28, 2026
@StephanTLavavej
Copy link
Copy Markdown
Member

This needs to be clang-formatted with the current version of Clang shipping in VS Insiders (currently Clang 22.1.3). We recommend configuring your editor to use clang-format; if you use VSCode, our repo will enable format-on-save for C++ files. The configuration setting for the C/C++ Extension to hook up clang-format is "C_Cpp.clang_format_path": "C:/Program Files/Microsoft Visual Studio/18/Insiders/VC/Tools/Llvm/x64/bin/clang-format.exe", with the default path.

@ferhatgec ferhatgec force-pushed the fix/gh-6134 branch 2 times, most recently from 4660c77 to 7d07670 Compare May 28, 2026 23:11
@ferhatgec
Copy link
Copy Markdown
Contributor Author

Sorry, my bad. Didn't realize my IDE was using my own .clang-format.

@ferhatgec
Copy link
Copy Markdown
Contributor Author

It seems the CI is failing because P0355R7_calendars_and_time_zones_formatting contains test cases that are affected by our changes.
Replacing:

assert(format(STR("{:%c, %x, %X}"), ltf) == STR("04/19/21 01:02:03, 04/19/21, 01:02:03"));

with:

assert(format(STR("{:%c, %x, %X}"), ltf) == STR("Mon Apr 19 01:02:03 2021, 04/19/21, 01:02:03"));

and replacing:

assert(format(STR("{:%c, %x, %X}"), zt) == STR("04/19/21 08:16:17, 04/19/21, 08:16:17"));

with:

assert(format(STR("{:%c, %x, %X}"), zt) == STR("Mon Apr 19 08:16:17 2021, 04/19/21, 08:16:17"));

Doing these seems to resolve the issue, at least on my PC.

Comment thread stl/inc/xloctime
_Fmt_ptr = "!%a %b %e %T %Y";
} else if (_Specifier == 'r' && _Modifier == '\0') {
_Fmt_ptr = "!%I:%M:%S %p";
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C Standard (N3685 7.31.3.6/7) and the informative "Application Usage" part of the POSIX spec both say that
"In the C [or POSIX] locale, the E and O modifiers are ignored". The UCRT is actually doing the opposite of this PR; it unconditionally replaces %r in the C locale but only replaces non-alternative %c (I don't have a link for this but you can find it in the UCRT expand_time source).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch. I've made some changes, now in C locale, %r, %Er and %Or are treated in the same way.

@MattStephanson
Copy link
Copy Markdown
Contributor

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Initial Review

Development

Successfully merging this pull request may close these issues.

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

3 participants