public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Paul Eggert <eggert@sourceware.org>
To: glibc-cvs@sourceware.org
Subject: [glibc] mktime: improve heuristic for ca-1986 Indiana DST
Date: Fri,  9 Sep 2022 03:56:20 +0000 (GMT)	[thread overview]
Message-ID: <20220909035620.3F7B13858436@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=83859e1115269cf56d21669361d4ddbe2687831c

commit 83859e1115269cf56d21669361d4ddbe2687831c
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Thu Sep 8 20:08:32 2022 -0500

    mktime: improve heuristic for ca-1986 Indiana DST
    
    This patch syncs mktime.c from Gnulib, fixing a
    problem reported by Mark Krenz <https://bugs.gnu.org/48085>,
    and it should fix BZ#29035 too.
    * time/mktime.c (__mktime_internal): Be more generous about
    accepting arguments with the wrong value of tm_isdst, by falling
    back to a one-hour DST difference if we find no nearby DST that is
    unusual.  This fixes a problem where "1986-04-28 00:00 EDT" was
    rejected when TZ="America/Indianapolis" because the nearest DST
    timestamp occurred in 1970, a temporal distance too great for the
    old heuristic.  This also also narrows the search a bit, which
    is a minor performance win.

Diff:
---
 time/mktime.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/time/mktime.c b/time/mktime.c
index aa12e28e16..7dc9d67ef9 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp,
 	 time with the right value, and use its UTC offset.
 
 	 Heuristic: probe the adjacent timestamps in both directions,
-	 looking for the desired isdst.  This should work for all real
-	 time zone histories in the tz database.  */
+	 looking for the desired isdst.  If none is found within a
+	 reasonable duration bound, assume a one-hour DST difference.
+	 This should work for all real time zone histories in the tz
+	 database.  */
+
+      /* +1 if we wanted standard time but got DST, -1 if the reverse.  */
+      int dst_difference = (isdst == 0) - (tm.tm_isdst == 0);
 
       /* Distance between probes when looking for a DST boundary.  In
 	 tzdata2003a, the shortest period of DST is 601200 seconds
@@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp,
 	 periods when probing.  */
       int stride = 601200;
 
-      /* The longest period of DST in tzdata2003a is 536454000 seconds
-	 (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
-	 period of non-DST is much longer, but it makes no real sense
-	 to search for more than a year of non-DST, so use the DST
-	 max.  */
-      int duration_max = 536454000;
+      /* In TZDB 2021e, the longest period of DST (or of non-DST), in
+	 which the DST (or adjacent DST) difference is not one hour,
+	 is 457243209 seconds: e.g., America/Cambridge_Bay with leap
+	 seconds, starting 1965-10-31 00:00 in a switch from
+	 double-daylight time (-05) to standard time (-07), and
+	 continuing to 1980-04-27 02:00 in a switch from standard time
+	 (-07) to daylight time (-06).  */
+      int duration_max = 457243209;
 
       /* Search in both directions, so the maximum distance is half
 	 the duration; add the stride to avoid off-by-1 problems.  */
@@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp,
 	      }
 	  }
 
+      /* No unusual DST offset was found nearby.  Assume one-hour DST.  */
+      t += 60 * 60 * dst_difference;
+      if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm))
+	goto offset_found;
+
       __set_errno (EOVERFLOW);
       return -1;
     }

                 reply	other threads:[~2022-09-09  3:56 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220909035620.3F7B13858436@sourceware.org \
    --to=eggert@sourceware.org \
    --cc=glibc-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).