Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid (local) %Z and %z with std::chrono::time_point<system_clock> but correct UTC Timestamp (%T) on MSVC #3815

Open
wbitesi opened this issue Jan 18, 2024 · 4 comments

Comments

@wbitesi
Copy link

wbitesi commented Jan 18, 2024

Printing with MSVC does not work properly using the Timezone.

When running this example with MSVC

fmt::print("Got now as {:%FT%T%z}\n",
std::chrono::time_pointstd::chrono::system_clock::clock::now());

I get the output:
Got now as 2024-01-18T07:09:51.3559309+0100

The timestamp is UTC (local time was 08:09) and UTC time is indeed 07:09, but my time zone (+0100) is printed instead of the correct +0000. On GCC (12.2 on debian) I get the correct time and timezone.

Tested with fmt 10.2.1 and current master. Minimum sample is here:
minimum sample.zip

Changing CXX_STANDARD from 20 to 11 does not lead to different results.

@zivshek
Copy link
Contributor

zivshek commented Mar 26, 2024

What's the expected behavior? It should just print the UTC time with (+0000) or UTC appended? Or it should print the local time with (+0100)?

@wbitesi
Copy link
Author

wbitesi commented Mar 26, 2024

System clock is normally UTC as far as i know (https://en.cppreference.com/w/cpp/chrono/system_clock), so it should print UTC time +0000. This is done on my gcc 12.2 on debian.
I got the weird behavior with timestamp in fact as within UTC but local timezone (+0100) instead of UTC Timezone (+0000) appended.

@zivshek
Copy link
Contributor

zivshek commented Mar 26, 2024

yes, I was able to repro it on Visual Studio, UTC time + EST

@zivshek
Copy link
Contributor

zivshek commented Mar 27, 2024

the issue seems to lie in

const auto& facet = std::use_facet<std::time_put<Char>>(loc);
auto end = facet.put(os, os, Char(' '), &time, format, modifier);

in do_write in chrono.h, after calling facet.put, we get the local timezone for Z/z.

Edit:
It does look it's getting the localized timezone, since there is no info about what the timezone actually is in this function, I am suprised it works fine on GCC.

https://stackoverflow.com/questions/58288964/why-does-stdput-timestdgmtime-with-the-z-format-give-back-0100-for-utc
based on this answer, it's not advised to use 'z'/'Z' to get the timezone other than local timezone from std::put_time, I have repro the same result using std::put_time, there is no timezone info once the tm is produced.

my guess is that on GCC, it always prints the UTC timezone, even you pass in a local time.

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

No branches or pull requests

3 participants