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;
}
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]]);
}
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;
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))) {
/* 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;
}