diff --git a/SOPE/NGCards/iCalTimeZone.m b/SOPE/NGCards/iCalTimeZone.m index 21fbbb22f6..23f9e8bae4 100644 --- a/SOPE/NGCards/iCalTimeZone.m +++ b/SOPE/NGCards/iCalTimeZone.m @@ -186,29 +186,44 @@ - (NSString *) tzId return [[self uniqueChildWithTag: @"tzid"] flattenedValuesForKey: @""]; } -- (NSCalendarDate *) _occurrenceForPeriodNamed: (NSString *) pName +- (NSDictionary *) _occurrenceForPeriodNamed: (NSString *) pName forDate: (NSCalendarDate *) aDate { NSArray *periods; NSEnumerator *periodsList; iCalTimeZonePeriod *period; NSCalendarDate *occurrence; + NSDictionary *periodDict; occurrence = nil; + periodDict = nil; periods = [[self childrenWithTag: pName] sortedArrayUsingSelector: @selector (compare:)]; periodsList = [periods reverseObjectEnumerator]; - while (!occurrence - && (period = (iCalTimeZonePeriod *) [periodsList nextObject])) - occurrence = [period occurrenceForDate: aDate]; + while ((period = (iCalTimeZonePeriod *) [periodsList nextObject])) + { + if ([periods count] > 1 && ([[period startDate] yearOfCommonEra] > [aDate yearOfCommonEra])) + continue; + + occurrence = [period occurrenceForDate: aDate]; + + if (occurrence && (!periodDict || [occurrence earlierDate: [periodDict objectForKey: @"occurrence"]] == [periodDict objectForKey: @"occurrence"])) + { + periodDict = [NSDictionary dictionaryWithObjectsAndKeys: + period, @"period", + occurrence, @"occurrence",nil]; + occurrence = nil; + } + } - return occurrence; + return periodDict; } - (iCalTimeZonePeriod *) periodForDate: (NSCalendarDate *) date { - NSCalendarDate *daylightOccurence, *standardOccurence; + //NSCalendarDate *daylightOccurence, *standardOccurence; + NSDictionary *daylightOccurence, *standardOccurence; iCalTimeZonePeriod *period; /* FIXME, this could cause crashes when timezones are not properly @@ -216,30 +231,33 @@ - (iCalTimeZonePeriod *) periodForDate: (NSCalendarDate *) date daylightOccurence = [self _occurrenceForPeriodNamed: @"daylight" forDate: date]; + standardOccurence = [self _occurrenceForPeriodNamed: @"standard" forDate: date]; - if (!standardOccurence) + if (!standardOccurence && !daylightOccurence) + period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"standard"]; + else if (!standardOccurence) period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"daylight"]; else if (!daylightOccurence) period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"standard"]; - else if ([date earlierDate: daylightOccurence] == date) + else if ([date earlierDate: [daylightOccurence objectForKey: @"occurrence"]] == date) { - if ([date earlierDate: standardOccurence] == date - && ([standardOccurence earlierDate: daylightOccurence] - == standardOccurence)) - period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"daylight"]; + if ([date earlierDate: [standardOccurence objectForKey: @"occurrence"]] == date + && ([[standardOccurence objectForKey: @"occurrence"] earlierDate: [daylightOccurence objectForKey: @"occurrence"]] + == [standardOccurence objectForKey: @"occurrence"])) + period = (iCalTimeZonePeriod *) [daylightOccurence objectForKey: @"period"]; else - period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"standard"]; + period = (iCalTimeZonePeriod *) [standardOccurence objectForKey: @"period"]; } else { - if ([standardOccurence earlierDate: date] == standardOccurence - && ([daylightOccurence earlierDate: standardOccurence] - == daylightOccurence)) - period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"standard"]; + if ([[standardOccurence objectForKey: @"occurrence"] earlierDate: date] == [standardOccurence objectForKey: @"occurrence"] + && ([[daylightOccurence objectForKey: @"occurrence"] earlierDate: [standardOccurence objectForKey: @"occurrence"]] + == [daylightOccurence objectForKey: @"occurrence"] )) + period = (iCalTimeZonePeriod *) [standardOccurence objectForKey: @"period"]; else - period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"daylight"]; + period = (iCalTimeZonePeriod *) [daylightOccurence objectForKey: @"period"]; } return period; diff --git a/SOPE/NGCards/iCalTimeZonePeriod.m b/SOPE/NGCards/iCalTimeZonePeriod.m index b7a8b23da3..3184789b21 100644 --- a/SOPE/NGCards/iCalTimeZonePeriod.m +++ b/SOPE/NGCards/iCalTimeZonePeriod.m @@ -38,6 +38,8 @@ - (Class) classForTag: (NSString *) classTag if ([classTag isEqualToString: @"RRULE"]) tagClass = [iCalRecurrenceRule class]; + else if ([classTag isEqualToString: @"RDATE"]) + tagClass = [iCalDateTime class]; else if ([classTag isEqualToString: @"DTSTART"]) tagClass = [iCalDateTime class]; else if ([classTag isEqualToString: @"TZOFFSETFROM"] @@ -248,19 +250,59 @@ - (NSCalendarDate *) _occurrenceForDate: (NSCalendarDate *) refDate return tmpDate; } +- (NSCalendarDate *) _occurrenceFromRdate: (NSCalendarDate *) refDate + rDates: (NSArray *) rDatesIn; +{ + NSArray *rDates; + NSEnumerator *dateList; + NSCalendarDate *rDateCur, *rDateOut; + NSString *dateString; + unsigned i; + + rDateCur = nil; + rDateOut = nil; + + dateList = [rDatesIn objectEnumerator]; + + while ((dateString = [dateList nextObject])) + { + rDates = [(iCalDateTime*) dateString dateTimes]; + + for (i = 0; i < [rDates count]; i++) + { + rDateCur = [rDates objectAtIndex: i]; + if (!rDateOut || ([rDateCur yearOfCommonEra] > [rDateOut yearOfCommonEra] && [refDate yearOfCommonEra] >= [rDateCur yearOfCommonEra])) + rDateOut = rDateCur; + } + } + + return rDateOut; +} + + - (NSCalendarDate *) occurrenceForDate: (NSCalendarDate *) refDate; { NSCalendarDate *tmpDate; iCalRecurrenceRule *rrule; + NSArray *rDates; tmpDate = nil; rrule = (iCalRecurrenceRule *) [self uniqueChildWithTag: @"rrule"]; + rDates = (NSArray *) [self childrenWithTag: @"rdate"]; + + if ([rDates count]) + { + tmpDate = [self _occurrenceFromRdate: refDate rDates: rDates]; + return tmpDate; + } if ([rrule isVoid]) tmpDate = [(iCalDateTime *) [self uniqueChildWithTag: @"dtstart"] dateTime]; else if ([rrule untilDate] == nil || [refDate compare: [rrule untilDate]] == NSOrderedAscending) tmpDate = [self _occurrenceForDate: refDate byRRule: rrule]; + else if ([refDate compare: [rrule untilDate]] == NSOrderedDescending) + tmpDate = [rrule untilDate]; return tmpDate; }