[PATCH] libstdc++: Fix condition for stopping lazy zone expansion [PR116110]
Jonathan Wakely
jwakely.gcc@gmail.com
Sat Jul 18 10:28:17 GMT 2026
On Fri, 17 Jul 2026, 20:37 Tomasz Kamiński, <tkaminsk@redhat.com> wrote:
> At indicated by the pre-existing comment, the lazy zone expansion can be
> only resumed from STD (save == 0) zone. However, the current condition
> for stopping on DST (save != 0) doesn't ensure that, as some rule specify
> transitions between DST zones. For example Y rule used by America/Dawson
> August 1945 transion only change letters:
> Y 1942 o - F 9 2 1 W
> Y 1945 o - Au 14 23u 1 P
>
> This patch correct the condition, by using next_rule (i.e. one applying
> after last expanded zone): either there is no zone (we default to STD)
> or it have save zero.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/116110
> * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Correct
> condition for stopping zone geration before STD zone.
> * testsuite/std/time/time_zone/116110.cc (test_dawson):
> Add test for America/Dawson August 1945 transition.
> ---
> This addresses the root cause and provides much more targeted solution
> for the problem described "Always seed info.offset and info.save from
> the active rule." in Alvaro 5/5 patch:
> https://gcc.gnu.org/pipermail/libstdc++/2026-May/066526.html.
>
> As this change is very minimal and affect only cases of sequence of
> DST zones (we expand more zones), I think this is very safe to backport.
>
Yes, this is a nice simple fix.
> Testing on x86_64-linux. *time_zone* test passed, in all standard modes
> and -m32/debug. OK for trunk and GCC-16.
>
OK for both, thanks
> libstdc++-v3/src/c++20/tzdb.cc | 4 +-
> .../testsuite/std/time/time_zone/116110.cc | 41 +++++++++++++++++++
> 2 files changed, 43 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/src/c++20/tzdb.cc
> b/libstdc++-v3/src/c++20/tzdb.cc
> index 460a242fed1..99b3ed58d95 100644
> --- a/libstdc++-v3/src/c++20/tzdb.cc
> +++ b/libstdc++-v3/src/c++20/tzdb.cc
> @@ -1231,10 +1231,10 @@ namespace std::chrono
> result_index = new_infos.size() - 1;
> else if (result_index >= 0 && !merged)
> {
> - // Finish on a DST sys_info if possible, so that if we resume
> + // Finish before a STD sys_info if possible, so that if we
> resume
> // generating sys_info objects after this time point, save=0
> // should be correct for the next sys_info.
> - if (num_after > 1 || info.save != 0min)
> + if (num_after > 1 || !next_rule || next_rule->save == 0s)
> --num_after;
> }
>
> diff --git a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc
> b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc
> index 1ec01d35955..45daed8c050 100644
> --- a/libstdc++-v3/testsuite/std/time/time_zone/116110.cc
> +++ b/libstdc++-v3/testsuite/std/time/time_zone/116110.cc
> @@ -78,9 +78,50 @@ test_apia()
> VERIFY( info.abbrev == "+14" );
> }
>
> +void
> +test_dawson()
> +{
> + /* 1945 August rule change changes letters (abbrev)
> + and remains in DST:
> + R Y 1942 o - F 9 2 1 W
> + R Y 1945 o - Au 14 23u 1 P
> + R Y 1945 o - S 30 2 0 S
> + Z America/Dawson -9:17:40 - LMT 1900 Au 20
> + -9 Y Y%sT 1965
> + -9 Yu Y%sT 1973 O 28
> + */
> +
> + auto* tz = locate_zone("America/Dawson");
> +
> + // Triggers rule transitions from the start.
> + sys_info info = tz->get_info(sys_days(1900y/August/20) + 10h);
> + VERIFY( info.offset == -9h );
> + VERIFY( info.save == 0min );
> + VERIFY( info.abbrev == "YST" );
> +
> + // Check YWT transition at 02:00 + 9h UT, that is DST
> + info = tz->get_info(sys_days(1942y/February/9) + 11h);
> + VERIFY( info.offset == -8h );
> + VERIFY( info.save == 60min );
> + VERIFY( info.abbrev == "YWT" );
> +
> + // Check YPT transition at 23:00 UT, remains DST
> + info = tz->get_info(sys_days(1945y/August/14) + 23h);
> + VERIFY( info.offset == -8h );
> + VERIFY( info.save == 60min );
> + VERIFY( info.abbrev == "YPT" );
> +
> + // Check YST transition at 02:00 + 8h UT, switches to STD
> + info = tz->get_info(sys_days(1945y/September/30) + 10h);
> + VERIFY( info.offset == -9h );
> + VERIFY( info.save == 0min );
> + VERIFY( info.abbrev == "YST" );
> +}
> +
> int main()
> {
> test_broken_hill();
> test_kiritimati();
> test_apia();
> + test_dawson();
> }
> --
> 2.55.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260718/7e49802d/attachment-0001.htm>
More information about the Libstdc++
mailing list