From 9f2283b8a0799ca7bda97e9fec124a8ca9fe1dfa Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Sat, 18 Jun 2005 19:23:58 +0000 Subject: [PATCH] - Fixed bug in tm2unixtime where the wanted date was in the transition time 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 | 14 +++++++++++--- ext/date/lib/timelib_structs.h | 1 + ext/date/lib/tm2unixtime.c | 13 ++++++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c index f0feff0352..831ae73405 100644 --- a/ext/date/lib/parse_tz.c +++ b/ext/date/lib/parse_tz.c @@ -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))) { diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h index 9edcb2113d..068f8b8a65 100644 --- a/ext/date/lib/timelib_structs.h +++ b/ext/date/lib/timelib_structs.h @@ -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 { diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c index c6d9cff3f2..22b739708b 100644 --- a/ext/date/lib/tm2unixtime.c +++ b/ext/date/lib/tm2unixtime.c @@ -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; } -- 2.40.0