[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 via Gcc-bugs" <[email protected]>
| Newsgroups | gmane.comp.gcc.bugs |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
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 <[email protected]>: https://gcc.gnu.org/g:5f4d61e1436a38db30c3dff0b12e59d670078010 commit r16-9431-g5f4d61e1436a38db30c3dff0b12e59d670078010 Author: Tomasz KamiÅski <[email protected]> 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 <[email protected]> Co-authored-by: Álvaro Begué <[email protected]> Signed-off-by: Álvaro Begué <[email protected]> Signed-off-by: Tomasz KamiÅski <[email protected]> (cherry picked from commit ce236336c8416fcdb47975dfebbeb5d9a40c609d)