(fix) handle flattened timezone definitions (fixes #2690)
parent
658cb956d9
commit
f607cb03c5
|
@ -183,29 +183,44 @@ static NSArray *knownTimeZones;
|
|||
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]))
|
||||
while ((period = (iCalTimeZonePeriod *) [periodsList nextObject]))
|
||||
{
|
||||
if ([periods count] > 1 && ([[period startDate] yearOfCommonEra] > [aDate yearOfCommonEra]))
|
||||
continue;
|
||||
|
||||
occurrence = [period occurrenceForDate: aDate];
|
||||
|
||||
return occurrence;
|
||||
if (occurrence && (!periodDict || [occurrence earlierDate: [periodDict objectForKey: @"occurrence"]] == [periodDict objectForKey: @"occurrence"]))
|
||||
{
|
||||
periodDict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
period, @"period",
|
||||
occurrence, @"occurrence",nil];
|
||||
occurrence = nil;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -213,30 +228,33 @@ static NSArray *knownTimeZones;
|
|||
|
||||
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;
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
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"]
|
||||
|
@ -247,19 +249,59 @@
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue