Imported Upstream version 1.0.0
[platform/upstream/libical.git] / src / libical / icaltz-util.c
index 4c19213..adf7598 100644 (file)
@@ -188,43 +188,6 @@ zname_from_stridx (char *str, long int idx)
        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)
 {
@@ -266,32 +229,6 @@ calculate_pos (icaltimetype icaltime)
        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)
 {
@@ -300,12 +237,12 @@ 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;
@@ -409,11 +346,6 @@ icaltzutil_fetch_timezone (const char *location)
        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 */
@@ -426,94 +358,54 @@ icaltzutil_fetch_timezone (const char *location)
        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)