]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Fix localized %c formatting for non-UTC times [PR117214]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 19 Mar 2025 22:05:28 +0000 (22:05 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 21 Mar 2025 10:28:16 +0000 (10:28 +0000)
commit778c28c70f8573f8256c810ff0d9e143ff75dec3
tree70d19d39ad99cf360ce02cb4f64620fcf32b2c5d
parentc24a1d58bc02daabafd5c94fca0984b70db811c8
libstdc++: Fix localized %c formatting for non-UTC times [PR117214]

The previous commit fixed most cases of %c formatting, but it
incorrectly prints times using the system's local time zone. This only
matters if the locale's %c format includes %Z, but some do.

To print a correct value for %Z we can set tm.tm_zone to either "UTC" or
the abbreviation passed to the formatter in the local-time-format-t
structure.

For local times with no info and for systems that don't support tm_zone
(which is new in POSIX.1-2024) we just set tm_isdst = -1 so that no zone
name is printed.

In theory, a locale's %c format could use %z which should print a +hhmm
offset from UTC. I'm unsure how to control that though. The new
tm_gmtoff field in combination with tm_isdst != -1 seems like it should
work, but using that without also setting tm_zone causes the system zone
to be used for %Z again. That means local_time_format(lt, nullptr, &off)
might work for a locale that uses %z but prints the wrong thing for %Z.
This commit doesn't set tm_gmtoff even if _M_offset_sec is provided for
a local-time-format-t value.

libstdc++-v3/ChangeLog:

PR libstdc++/117214
* configure.ac: Use AC_STRUCT_TIMEZONE.
* config.h.in: Regenerate.
* configure: Regenerate.
* include/bits/chrono_io.h (__formatter_chrono::_M_c): Set
tm_isdst and tm_zone.
* testsuite/std/time/format/pr117214.cc: Check %c formatting of
zoned_time and local time.
libstdc++-v3/config.h.in
libstdc++-v3/configure
libstdc++-v3/configure.ac
libstdc++-v3/include/bits/chrono_io.h
libstdc++-v3/testsuite/std/time/format/pr117214.cc