2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #import <Foundation/NSDate.h>
23 #import <Foundation/NSDictionary.h>
24 #import <Foundation/NSString.h>
25 #import <Foundation/NSTimeZone.h>
26 #import <Foundation/NSUserDefaults.h>
28 #import <NGExtensions/NSCalendarDate+misc.h>
29 #import <NGExtensions/NSObject+Logs.h>
31 #import "iCalDateHolder.h"
32 #import "iCalObject.h"
34 @interface NSTimeZone(iCalTimeZone)
36 + (NSTimeZone *)timeZoneWithICalId:(NSString *)_tz;
40 @implementation iCalDateHolder
42 static NSTimeZone *gmt = nil;
46 gmt = [[NSTimeZone timeZoneWithName:@"GMT"] retain];
51 [self->string release];
58 - (void)setString:(NSString *)_value {
59 ASSIGNCOPY(self->string, _value);
61 - (NSString *)string {
65 - (void)setTag:(NSString *)_value {
66 ASSIGNCOPY(self->tag, _value);
72 - (void)setTzid:(NSString *)_value {
73 ASSIGNCOPY(self->tzid, _value);
79 /* mapping to Foundation */
81 - (NSTimeZone *)timeZone {
82 // TODO: lookup tzid in iCalCalendar !
88 if ([s hasPrefix:@"/softwarestudio.org"]) {
91 r = [s rangeOfString:@"Europe/"];
93 s = [s substringFromIndex:r.location];
95 return [NSTimeZone timeZoneWithICalId:s];
100 - (id)awakeAfterUsingSaxDecoder:(id)_decoder {
101 NSCalendarDate *date = nil;
106 if ([s length] < 5) {
107 [self logWithFormat:@"tag %@: got an weird date string '%@' ?!",
112 /* calculate timezone */
114 if ([self->string hasSuffix:@"Z"]) {
115 /* zulu time, eg 20021009T094500Z */
117 s = [s substringToIndex:([s length] - 1)];
120 tz = [self timeZone];
124 20021009T094500 - 15 chars
125 20021009T0945 - 13 chars
126 991009T0945 - 11 chars
130 if ([s rangeOfString:@"T"].length == 0 && [s length] == 8) {
131 /* hm, maybe a date without a time? like an allday event! */
132 int year, month, day;
134 [s getCString:&(buf[0])];
137 day = atoi(&(buf[6])); buf[6] = '\0';
138 month = atoi(&(buf[4])); buf[4] = '\0';
139 year = atoi(&(buf[0]));
141 date = [NSCalendarDate dateWithYear:year month:month day:day
142 hour:0 minute:0 second:0
145 else if ([s length] == 15) {
146 int year, month, day, hour, minute, second;
148 [s getCString:&(buf[0])];
150 second = atoi(&(buf[13])); buf[13] = '\0';
151 minute = atoi(&(buf[11])); buf[11] = '\0';
152 hour = atoi(&(buf[9])); buf[9] = '\0';
153 day = atoi(&(buf[6])); buf[6] = '\0';
154 month = atoi(&(buf[4])); buf[4] = '\0';
155 year = atoi(&(buf[0]));
157 date = [NSCalendarDate dateWithYear:year month:month day:day
158 hour:hour minute:minute second:second
162 NSLog(@"%s: unknown date format (%@) ???", __PRETTY_FUNCTION__, s);
165 NSLog(@"couldn't convert string '%@' to date (format '%@') ..", s);
172 - (void)appendAttributesToDescription:(NSMutableString *)ms {
173 if (self->tag) [ms appendFormat:@" %@", self->tag];
174 if (self->string) [ms appendFormat:@" '%@'", self->string];
175 if (self->tzid) [ms appendFormat:@" tz=%@", self->tzid];
178 - (NSString *)description {
181 ms = [NSMutableString stringWithCapacity:128];
182 [ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])];
183 [self appendAttributesToDescription:ms];
184 [ms appendString:@">"];
188 @end /* iCalDateHolder */
190 @implementation NSTimeZone(iCalTimeZone)
192 static NSMutableDictionary *idToTz = nil; // THREAD
194 + (NSTimeZone *)timeZoneWithICalId:(NSString *)_tzid {
195 static NSString *iCalDefaultTZ = nil;
199 idToTz = [[NSMutableDictionary alloc] initWithCapacity:16];
201 if ([_tzid length] == 0) {
203 tz = [iCalObject iCalDefaultTimeZone];
204 if (tz != nil) return tz;
206 if (iCalDefaultTZ == nil) {
209 // TODO: take a default timeZone
210 ud = [NSUserDefaults standardUserDefaults];
211 defTz = [ud stringForKey:@"iCalTimeZoneName"];
212 if ([defTz length] == 0)
213 defTz = [ud stringForKey:@"TimeZoneName"];
214 if ([defTz length] == 0)
215 defTz = [ud stringForKey:@"TimeZone"];
216 if ([defTz length] == 0)
218 iCalDefaultTZ = [defTz retain];
221 _tzid = iCalDefaultTZ;
225 if ([_tzid length] == 0)
228 tz = [idToTz objectForKey:_tzid];
229 if (tz == nil) tz = [NSTimeZone timeZoneWithName:_tzid];
230 if (tz == nil) tz = [NSTimeZone timeZoneWithAbbreviation:_tzid];
233 NSLog(@"couldn't map timezone id %@", _tzid);
236 if (tz) [idToTz setObject:tz forKey:_tzid];
240 @end /* NSTimeZone(iCalTimeZone) */