1 /* iCalTimeZonePeriod.m - this file is part of SOPE
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSCalendarDate.h>
24 #import <Foundation/NSString.h>
25 #import <Foundation/NSTimeZone.h>
27 #import "iCalDateTime.h"
28 #import "iCalRecurrenceRule.h"
30 #import "iCalTimeZonePeriod.h"
32 @implementation iCalTimeZonePeriod
34 - (Class) classForTag: (NSString *) classTag
38 if ([classTag isEqualToString: @"RRULE"])
39 tagClass = [iCalRecurrenceRule class];
40 else if ([classTag isEqualToString: @"DTSTART"])
41 tagClass = [iCalDateTime class];
42 else if ([classTag isEqualToString: @"TZNAME"]
43 || [classTag isEqualToString: @"TZOFFSETFROM"]
44 || [classTag isEqualToString: @"TZOFFSETTO"])
45 tagClass = [CardElement class];
47 tagClass = [super classForTag: classTag];
52 - (int) _secondsOfOffset: (NSString *) offsetName
62 offsetTo = [[self uniqueChildWithTag: offsetName]
64 length = [offsetTo length];
65 negative = [offsetTo hasPrefix: @"-"];
69 cursor = NSMakeRange(1, 2);
71 else if ([offsetTo hasPrefix: @"+"])
74 cursor = NSMakeRange(1, 2);
77 cursor = NSMakeRange(0, 2);
79 seconds = 3600 * [[offsetTo substringWithRange: cursor] intValue];
81 seconds += 60 * [[offsetTo substringWithRange: cursor] intValue];
85 seconds += [[offsetTo substringWithRange: cursor] intValue];
88 return ((negative) ? -seconds : seconds);
91 - (unsigned int) dayOfWeekFromRruleDay: (iCalWeekDay) day
93 unsigned int dayOfWeek;
96 while (day >> dayOfWeek)
102 - (NSCalendarDate *) occurenceForDate: (NSCalendarDate *) refDate;
104 NSCalendarDate *tmpDate;
105 iCalRecurrenceRule *rrule;
107 int dayOfWeek, dateDayOfWeek, offset, pos;
109 rrule = (iCalRecurrenceRule *) [self uniqueChildWithTag: @"rrule"];
110 byDay = [rrule namedValue: @"byday"];
111 dayOfWeek = [self dayOfWeekFromRruleDay: [rrule byDayMask]];
112 pos = [[byDay substringToIndex: 2] intValue];
116 tmpDate = [NSCalendarDate
117 dateWithYear: [refDate yearOfCommonEra]
118 month: [[rrule namedValue: @"bymonth"] intValue]
119 day: 1 hour: 0 minute: 0 second: 0
120 timeZone: [NSTimeZone timeZoneWithName: @"GMT"]];
121 tmpDate = [tmpDate addYear: 0 month: ((pos > 0) ? 0 : 1)
122 day: 0 hour: 0 minute: 0
123 second: -[self _secondsOfOffset: @"tzoffsetfrom"]];
124 dateDayOfWeek = [tmpDate dayOfWeek];
125 offset = (dayOfWeek - dateDayOfWeek);
126 if (pos > 0 && offset < 0)
129 tmpDate = [tmpDate addYear: 0 month: 0 day: offset
130 hour: 0 minute: 0 second: 0];
135 - (int) secondsOffsetFromGMT
137 return [self _secondsOfOffset: @"tzoffsetto"];