[Bug libstdc++/124854] std::chrono::time_zone emits a brief incorrect sys_info at certain zone-line boundaries where zic.c's writezone merges a rule firing with the boundary
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jul 29 12:09:42 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124854
--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Tomasz Kaminski
<tkaminsk@gcc.gnu.org>:
https://gcc.gnu.org/g:5f4d61e1436a38db30c3dff0b12e59d670078010
commit r16-9431-g5f4d61e1436a38db30c3dff0b12e59d670078010
Author: Tomasz KamiÅski <tkaminsk@redhat.com>
Date: Mon Jul 20 09:15:28 2026 +0200
libstdc++: Implement zic writezone merge optimization [PR124854]
When two adjacent Zone lines have different total offsets and the
new line's rule set has a rule firing within jump of the boundary
(where jump = old_total - new_total > 0, i.e. local time goes
backward at the boundary), zic folds that rule into the boundary
itself: the single transition emitted has the rule's save value
already applied, so the new line begins with the post-rule save
rather than briefly using the pre-rule save and then transitioning
again moments later.
Canonical examples handled by the new merge block:
* America/Argentina/Buenos_Aires 1999-10-03: lines change
stdoff -3 â -4 with an Argentina DST rule firing on the same
day. Without the merge, chrono emits a 1-hour stretch of
offset=-4 save=0 and then transitions to offset=-3 save=1;
with the merge, the boundary itself is at offset=-3 save=1.
* Europe/Berlin 1945-05-24: lines split a rule set, with the
So 1945-May-24 rule (save=2, "CEMT") firing at 01:00 UTC in
the new frame, inside the 1h backward window.
Similarly, when the zone expansion algorithm is resumed after DST
span (save = 1h), we will revisit the corresponding STD transition,
for example: given offset +2h, the transition happening at 12:00
local time, will be considered twice:
* 09:00 UT (2h + 1h) - proper ending of DST span
* 10:00 UT (2h) - after re-entry.
Previously this transition were rejected using the (now removed)
rule_start - t < days(1) check, preventing us from emitting the one
hour STD time range followed by rest of same range. In this patch,
we reuse same merge logic, as such STD transition happens during
backward jump from boundary introduced by previous expansion.
This patch address both of the above by computing length of the
backward jump (merge_window) at the start of the expansion (regardless
if initial or re-entry), and then considering initial rule transition
happening in [info.begin + merge_window] to apply at info.begin.
libstdc++-v3/ChangeLog:
PR libstdc++/124854
* src/c++20/tzdb.cc (ZoneInfo::save): Define.
(time_zone::_M_get_sys_info): Fold initial transition if they
occurs in duplicated local time window (merge_window) due move
from DST to STD zone.
* testsuite/std/time/time_zone/wall_cascade.cc (test_next_year):
Test that 1945 Pacific/Auckland transition is properly handled.
(test_negative): Adjust test to avoid zone merge.
* testsuite/std/time/time_zone/zone_merge.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Co-authored-by: Álvaro Begué <alvaro.begue@gmail.com>
Signed-off-by: Álvaro Begué <alvaro.begue@gmail.com>
Signed-off-by: Tomasz KamiÅski <tkaminsk@redhat.com>
(cherry picked from commit ce236336c8416fcdb47975dfebbeb5d9a40c609d)
More information about the Gcc-bugs
mailing list