Index: ChangeLog
===================================================================
--- ChangeLog	(revision 662)
+++ ChangeLog	(working copy)
@@ -1,3 +1,15 @@
+2009-02-24  Suman Manjunath  <msuman@novell.com>
+
+	** Fix for bug #572516
+
+	* src/libical/icaltz-util.c (find_transidx),
+	(adjust_dtstart_day_to_rrule), (icaltzutil_fetch_timezone): Use the 
+	correct transitions to determine the RRULEs for the DAYLIGHT and 
+	STANDARD components. Extrapolate if an appropriate transition is not
+	found for the present year.
+	* src/test/timezones.c (main): Check the correctness of the timezone 
+	information for	the current year.
+
 2009-01-12  Tor Lillqvist  <tml@novell.com>
 
 	Merge from trunk:
Index: src/libical/icaltz-util.c
===================================================================
--- src/libical/icaltz-util.c	(revision 662)
+++ src/libical/icaltz-util.c	(working copy)
@@ -140,33 +140,37 @@
 static void 
 find_transidx (time_t *transitions, ttinfo *types, int *trans_idx, long int num_trans, int *stdidx, int *dstidx) 
 {
-	time_t now = time (NULL);
-	int i, found = 0, idx;
+	time_t now, year_start;
+	int i, found = 0;
+	struct icaltimetype itime;
 
-	for (i = 0; i < num_trans; i++)	{
-		if (now < transitions [i]) {
-			found = 1;	
-			break;
+	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 time is not found, it means the timezone does not have the dst changes */
-	if (!found) {
-		*stdidx = i-1;
-		return;
+	/* 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);
 	}
 
-	idx = trans_idx [i];
-	types [idx].isdst ? (*dstidx = i) : (*stdidx = i);
-	
-	if (i < num_trans - 1) 
-		i++;
-	else 
-		return;
-
-	idx = trans_idx [i];
-	types [idx].isdst ? (*dstidx = i) : (*stdidx = i);
-
 	return;
 }
 
@@ -214,6 +218,32 @@
 	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)
 {
@@ -371,6 +401,8 @@
 			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);
 		} else {
@@ -409,6 +441,8 @@
 		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);
 
Index: src/test/timezones.c
===================================================================
--- src/test/timezones.c	(revision 662)
+++ src/test/timezones.c	(working copy)
@@ -56,13 +56,15 @@
 
         /*
          * determine current local time and date: always use midday in
-         * the current zone
+         * the current zone and first day of first month in the year
          */
         start_time = time(NULL);
         localtime_r(&start_time, &start_tm);
         start_tm.tm_hour = 12;
         start_tm.tm_min = 0;
         start_tm.tm_sec = 0;
+	start_tm.tm_mday = 1;
+	start_tm.tm_mon = 0;
         start_time = mktime(&start_tm);
 
         /* check time conversion for the next 365 days */
