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;
135 buf = strdup([s cStringUsingEncoding: NSASCIIStringEncoding]);
139 month = atoi(buf + 4);
144 date = [NSCalendarDate dateWithYear:year month:month day:day
145 hour:0 minute:0 second:0
148 else if ([s length] == 15) {
149 int year, month, day, hour, minute, second;
151 [s getCString:&(buf[0])];
153 second = atoi(&(buf[13])); buf[13] = '\0';
154 minute = atoi(&(buf[11])); buf[11] = '\0';
155 hour = atoi(&(buf[9])); buf[9] = '\0';
156 day = atoi(&(buf[6])); buf[6] = '\0';
157 month = atoi(&(buf[4])); buf[4] = '\0';
158 year = atoi(&(buf[0]));
160 date = [NSCalendarDate dateWithYear:year month:month day:day
161 hour:hour minute:minute second:second
165 NSLog(@"%s: unknown date format (%@) ???", __PRETTY_FUNCTION__, s);
168 NSLog(@"couldn't convert string '%@' to date (format '%@') ..", s);
175 - (void)appendAttributesToDescription:(NSMutableString *)ms {
176 if (self->tag) [ms appendFormat:@" %@", self->tag];
177 if (self->string) [ms appendFormat:@" '%@'", self->string];
178 if (self->tzid) [ms appendFormat:@" tz=%@", self->tzid];
181 - (NSString *)description {
184 ms = [NSMutableString stringWithCapacity:128];
185 [ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])];
186 [self appendAttributesToDescription:ms];
187 [ms appendString:@">"];
191 @end /* iCalDateHolder */
193 @implementation NSTimeZone(iCalTimeZone)
195 static NSMutableDictionary *idToTz = nil; // THREAD
197 + (NSTimeZone *)timeZoneWithICalId:(NSString *)_tzid {
198 static NSString *iCalDefaultTZ = nil;
202 idToTz = [[NSMutableDictionary alloc] initWithCapacity:16];
204 if ([_tzid length] == 0) {
206 tz = [iCalObject iCalDefaultTimeZone];
207 if (tz != nil) return tz;
209 if (iCalDefaultTZ == nil) {
212 // TODO: take a default timeZone
213 ud = [NSUserDefaults standardUserDefaults];
214 defTz = [ud stringForKey:@"iCalTimeZoneName"];
215 if ([defTz length] == 0)
216 defTz = [ud stringForKey:@"TimeZoneName"];
217 if ([defTz length] == 0)
218 defTz = [ud stringForKey:@"TimeZone"];
219 if ([defTz length] == 0)
221 iCalDefaultTZ = [defTz retain];
224 _tzid = iCalDefaultTZ;
228 if ([_tzid length] == 0)
231 tz = [idToTz objectForKey:_tzid];
232 if (tz == nil) tz = [NSTimeZone timeZoneWithName:_tzid];
233 if (tz == nil) tz = [NSTimeZone timeZoneWithAbbreviation:_tzid];
236 NSLog(@"couldn't map timezone id %@", _tzid);
239 if (tz) [idToTz setObject:tz forKey:_tzid];
243 @end /* NSTimeZone(iCalTimeZone) */