Skip to content

Commit

Permalink
(fix) handle flattened timezone definitions (fixes #2690)
Browse files Browse the repository at this point in the history
  • Loading branch information
extrafu committed Jun 9, 2016
1 parent b51d866 commit 49a6046
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 18 deletions.
54 changes: 36 additions & 18 deletions SOPE/NGCards/iCalTimeZone.m
Expand Up @@ -186,60 +186,78 @@ - (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
specified, but let's say it won't happen often... */

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;
Expand Down
42 changes: 42 additions & 0 deletions SOPE/NGCards/iCalTimeZonePeriod.m
Expand Up @@ -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"]
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 49a6046

Please sign in to comment.