return ret;
}
-static void
-find_transidx (time_t *transitions, ttinfo *types, int *trans_idx, long int num_trans, int *stdidx, int *dstidx)
-{
- time_t now, year_start;
- int i, found = 0;
- struct icaltimetype itime;
-
- now = time (NULL);
- itime = icaltime_from_timet (now, 0);
- itime.month = itime.day = 1;
- itime.hour = itime.minute = itime.second = 0;
- year_start = icaltime_as_timet(itime);
-
- /* Set this by default */
- *stdidx = (num_trans - 1);
-
- for (i = (num_trans - 1); i >= 0; --i)
- if (year_start < transitions [i]) {
- int idx;
- found = 1;
- idx = trans_idx [i];
- (types [idx].isdst) ? (*dstidx = i) : (*stdidx = i);
- }
-
- /* If the transition found is the last among the list, prepare to use the last two transtions.
- * Using this will most likely throw the DTSTART of the resulting component off by 1 or 2 days
- * but it would set right by the adjustment made.
- * NOTE: We need to use the last two transitions only because there is no data for the future
- * transitions.
- */
- if (found && (*dstidx == -1)) {
- *dstidx = ((*stdidx) - 1);
- }
-
- return;
-}
-
static void
set_zonedir (void)
{
return r_pos [pos];
}
-static void
-adjust_dtstart_day_to_rrule (icalcomponent *comp, struct icalrecurrencetype rule)
-{
- time_t now, year_start;
- struct icaltimetype start, comp_start, iter_start, itime;
- icalrecur_iterator *iter;
-
- now = time (NULL);
- itime = icaltime_from_timet (now, 0);
- itime.month = itime.day = 1;
- itime.hour = itime.minute = itime.second = 0;
- year_start = icaltime_as_timet(itime);
-
- comp_start = icalcomponent_get_dtstart (comp);
- start = icaltime_from_timet (year_start, 0);
-
- iter = icalrecur_iterator_new (rule, start);
- iter_start = icalrecur_iterator_next (iter);
- icalrecur_iterator_free (iter);
-
- if (iter_start.day != comp_start.day) {
- comp_start.day = iter_start.day;
- icalcomponent_set_dtstart (comp, comp_start);
- }
-}
-
icalcomponent*
icaltzutil_fetch_timezone (const char *location)
{
tzinfo type_cnts;
unsigned int i, num_trans, num_types, num_chars, num_leaps, num_isstd, num_isgmt;
time_t *transitions = NULL;
- time_t trans;
- int *trans_idx = NULL, dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx;
+ time_t trans, start, end;
+ int *trans_idx = NULL, pos, sign, zidx, zp_idx, idx, prev_idx;
ttinfo *types = NULL;
char *znames = NULL, *full_path, *tzid, *r_trans, *temp;
leap *leaps = NULL;
- icalcomponent *tz_comp = NULL, *dst_comp = NULL, *std_comp = NULL;
+ icalcomponent *tz_comp = NULL, *comp = NULL;
icalproperty *icalprop;
icaltimetype dtstart, icaltime;
struct icalrecurrencetype ical_recur;
for (i = 0; i < num_types; i++)
types [i].zname = zname_from_stridx (znames, types [i].abbr);
- if (num_trans != 0)
- find_transidx (transitions, types, trans_idx, num_trans, &stdidx, &dstidx);
- else
- stdidx = 0;
-
tz_comp = icalcomponent_new (ICAL_VTIMEZONE_COMPONENT);
/* Add tzid property */
icalprop = icalproperty_new_x (location);
icalproperty_set_x_name (icalprop, "X-LIC-LOCATION");
icalcomponent_add_property (tz_comp, icalprop);
-
- if (stdidx != -1) {
- if (num_trans != 0)
- zidx = trans_idx [stdidx];
- else
- zidx = 0;
-
- std_comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT);
- icalprop = icalproperty_new_tzname (types [zidx].zname);
- icalcomponent_add_property (std_comp, icalprop);
-
- if (dstidx != -1)
- zp_idx = trans_idx [stdidx-1];
- else
- zp_idx = zidx;
- /* DTSTART localtime uses TZOFFSETFROM UTC offset */
- if (num_trans != 0)
- trans = transitions [stdidx] + types [zp_idx].gmtoff;
- else
- trans = types [zp_idx].gmtoff;
- icaltime = icaltime_from_timet (trans, 0);
- dtstart = icaltime;
- dtstart.year = 1970;
- dtstart.minute = dtstart.second = 0;
- icalprop = icalproperty_new_dtstart (dtstart);
- icalcomponent_add_property (std_comp, icalprop);
-
- /* If DST changes are present use RRULE */
- if (dstidx != -1) {
- icalrecurrencetype_clear (&ical_recur);
- ical_recur.freq = ICAL_YEARLY_RECURRENCE;
- ical_recur.by_month [0] = icaltime.month;
- pos = calculate_pos (icaltime);
- pos < 0 ? (sign = -1): (sign = 1);
- ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime));
- icalprop = icalproperty_new_rrule (ical_recur);
- icalcomponent_add_property (std_comp, icalprop);
-
- adjust_dtstart_day_to_rrule (std_comp, ical_recur);
- }
- icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff);
- icalcomponent_add_property (std_comp, icalprop);
- icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff);
- icalcomponent_add_property (std_comp, icalprop);
-
- icalcomponent_add_component (tz_comp, std_comp);
- } else
- icalerror_set_errno (ICAL_MALFORMEDDATA_ERROR);
-
- if (dstidx != -1) {
- zidx = trans_idx [dstidx];
- zp_idx = trans_idx [dstidx-1];
- dst_comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT);
- icalprop = icalproperty_new_tzname (types [zidx].zname);
- icalcomponent_add_property (dst_comp, icalprop);
-
- /* DTSTART localtime uses TZOFFSETFROM UTC offset */
- if (num_trans != 0)
- trans = transitions [dstidx] + types [zp_idx].gmtoff;
+ prev_idx = 0;
+ if (num_trans == 0) {
+ prev_idx = idx = 0;
+
+ } else {
+ idx = trans_idx[0];
+ }
+ start = 0;
+ for (i = 1; i < num_trans; i++, start = end) {
+ prev_idx = idx;
+ idx = trans_idx [i];
+ end = transitions [i] + types [prev_idx].gmtoff;
+ /* don't bother starting until the epoch */
+ if (0 > end)
+ continue;
+
+ if (types [prev_idx].isdst)
+ comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT);
else
- trans = types [zp_idx].gmtoff;
- icaltime = icaltime_from_timet (trans, 0);
- dtstart = icaltime;
- dtstart.year = 1970;
- dtstart.minute = dtstart.second = 0;
+ comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT);
+ icalprop = icalproperty_new_tzname (types [prev_idx].zname);
+ icalcomponent_add_property (comp, icalprop);
+ dtstart = icaltime_from_timet(start, 0);
icalprop = icalproperty_new_dtstart (dtstart);
- icalcomponent_add_property (dst_comp, icalprop);
-
- icalrecurrencetype_clear (&ical_recur);
- ical_recur.freq = ICAL_YEARLY_RECURRENCE;
- ical_recur.by_month [0] = icaltime.month;
- pos = calculate_pos (icaltime);
- pos < 0 ? (sign = -1): (sign = 1);
- ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime));
- icalprop = icalproperty_new_rrule (ical_recur);
- icalcomponent_add_property (dst_comp, icalprop);
-
- adjust_dtstart_day_to_rrule (dst_comp, ical_recur);
-
- icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff);
- icalcomponent_add_property (dst_comp, icalprop);
-
- icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff);
- icalcomponent_add_property (dst_comp, icalprop);
-
- icalcomponent_add_component (tz_comp, dst_comp);
+ icalcomponent_add_property (comp, icalprop);
+ icalprop = icalproperty_new_tzoffsetfrom (types [idx].gmtoff);
+ icalcomponent_add_property (comp, icalprop);
+ icalprop = icalproperty_new_tzoffsetto (types [prev_idx].gmtoff);
+ icalcomponent_add_property (comp, icalprop);
+ icalcomponent_add_component (tz_comp, comp);
}
+ /* finally, add a last zone with no end date */
+ if (types [idx].isdst)
+ comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT);
+ else
+ comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT);
+ icalprop = icalproperty_new_tzname (types [idx].zname);
+ icalcomponent_add_property (comp, icalprop);
+ dtstart = icaltime_from_timet(start, 0);
+ icalprop = icalproperty_new_dtstart (dtstart);
+ icalcomponent_add_property (comp, icalprop);
+ icalprop = icalproperty_new_tzoffsetfrom (types [prev_idx].gmtoff);
+ icalcomponent_add_property (comp, icalprop);
+ icalprop = icalproperty_new_tzoffsetto (types [idx].gmtoff);
+ icalcomponent_add_property (comp, icalprop);
+ icalcomponent_add_component (tz_comp, comp);
+
error:
if (f)