]> granicus.if.org Git - php/commitdiff
- Fixed bug in tm2unixtime where the wanted date was in the transition time
authorDerick Rethans <derick@php.net>
Sat, 18 Jun 2005 19:23:58 +0000 (19:23 +0000)
committerDerick Rethans <derick@php.net>
Sat, 18 Jun 2005 19:23:58 +0000 (19:23 +0000)
  between two zones.
#- In this case the wanted date actually didn't exist, and that wasn't
#  handled correctly.

ext/date/lib/parse_tz.c
ext/date/lib/timelib_structs.h
ext/date/lib/tm2unixtime.c

index f0feff03527d59fd31106d4f76c24efd938fbf3d..831ae734057c12b1c0cc76c5c0cb44e394570b92 100644 (file)
@@ -220,7 +220,7 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone)
        return tmp;
 }
 
-static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts)
+static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib_sll *transition_time)
 {
        uint32_t i;
 
@@ -229,13 +229,16 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts)
        }
 
        if (ts < tz->trans[0]) {
+               *transition_time = 0;
                return &(tz->type[tz->trans_idx[tz->timecnt - 1]]);
        }
        for (i = 0; i < tz->timecnt; i++) {
                if (ts < tz->trans[i]) {
+                       *transition_time = tz->trans[i - 1];
                        return &(tz->type[tz->trans_idx[i - 1]]);
                }
        }
+       *transition_time = tz->trans[tz->timecnt - 1];
        return &(tz->type[tz->trans_idx[tz->timecnt - 1]]);
 }
 
@@ -258,7 +261,9 @@ static tlinfo* fetch_leaptime_offset(timelib_tzinfo *tz, timelib_sll ts)
 int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz)
 {
        ttinfo *to;
-       if ((to = fetch_timezone_offset(tz, ts))) {
+       timelib_sll dummy;
+       
+       if ((to = fetch_timezone_offset(tz, ts, &dummy))) {
                return to->isdst;
        }
        return -1;
@@ -271,14 +276,17 @@ timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *
        int32_t offset = 0, leap_secs = 0;
        char *abbr;
        timelib_time_offset *tmp = timelib_time_offset_ctor();
+       timelib_sll                transistion_time;
 
-       if ((to = fetch_timezone_offset(tz, ts))) {
+       if ((to = fetch_timezone_offset(tz, ts, &transistion_time))) {
                offset = to->offset;
                abbr = &(tz->timezone_abbr[to->abbr_idx]);
                tmp->is_dst = to->isdst;
+               tmp->transistion_time = transistion_time;
        } else {
                abbr = tz->timezone_abbr;
                tmp->is_dst = 0;
+               tmp->transistion_time = 0;
        }
 
        if ((tl = fetch_leaptime_offset(tz, ts))) {
index 9edcb2113d0a0ba284b780d1d09ee56caac99101..068f8b8a65415b29df64059dad2c70cef276bb05 100644 (file)
@@ -119,6 +119,7 @@ typedef struct timelib_time_offset {
        unsigned int leap_secs;
        unsigned int is_dst;
        char        *abbr;
+       timelib_sll  transistion_time;
 } timelib_time_offset;
 
 typedef struct timelib_time {
index c6d9cff3f2dcb861f9d12bdcac1556311e3d1de4..22b739708b1c85c19cd9347ca6dbf229f22862c5 100644 (file)
@@ -209,14 +209,21 @@ static timelib_sll do_adjust_timezone(timelib_time *tz, timelib_tzinfo *tzi)
                        /* No timezone in struct, fallback to reference if possible */
                        if (tzi) {
                                timelib_time_offset *before, *after;
-                               timelib_sll tmp;
+                               timelib_sll          tmp;
+                               int                  in_transistion;
                                
                                tz->is_localtime = 1;
                                before = timelib_get_time_zone_info(tz->sse, tzi);
                                after = timelib_get_time_zone_info(tz->sse - before->offset, tzi);
                                timelib_set_timezone(tz, tzi);
-                               if (before->is_dst != after->is_dst) {
-                                       tmp = -tz->z + (before->offset - after->offset);
+
+                               in_transistion = (
+                                       ((tz->sse - after->offset) >= (after->transistion_time + (before->offset - after->offset))) &&
+                                       ((tz->sse - after->offset) < after->transistion_time)
+                               );
+                               
+                               if ((before->offset != after->offset) && !in_transistion) {
+                                       tmp = -after->offset;
                                } else {
                                        tmp = -tz->z;
                                }