]> err.no Git - sope/blob - sope-ical/NGiCal/iCalDateHolder.m
removed iCalSaxDriver project reference
[sope] / sope-ical / NGiCal / iCalDateHolder.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo 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
9   later version.
10
11   OGo 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.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "iCalDateHolder.h"
24 #include "iCalObject.h"
25 #include "common.h"
26
27 @interface NSTimeZone(iCalTimeZone)
28
29 + (NSTimeZone *)timeZoneWithICalId:(NSString *)_tz;
30
31 @end
32
33 @implementation iCalDateHolder
34
35 static NSTimeZone *gmt = nil;
36
37 + (void)initialize {
38   if (gmt == nil)
39     gmt = [[NSTimeZone timeZoneWithName:@"GMT"] retain];
40 }
41
42 - (void)dealloc {
43   [self->string release];
44   [self->tzid   release];
45   [self->tag    release];
46   [super dealloc];
47 }
48
49 /* accessors */
50
51 - (void)setString:(NSString *)_value {
52   ASSIGNCOPY(self->string, _value);
53 }
54 - (NSString *)string {
55   return self->string;
56 }
57
58 - (void)setTag:(NSString *)_value {
59   ASSIGNCOPY(self->tag, _value);
60 }
61 - (NSString *)tag {
62   return self->tag;
63 }
64
65 - (void)setTzid:(NSString *)_value {
66   ASSIGNCOPY(self->tzid, _value);
67 }
68 - (NSString *)tzid {
69   return self->tzid;
70 }
71
72 /* mapping to Foundation */
73
74 - (NSTimeZone *)timeZone {
75   // TODO: lookup tzid in iCalCalendar !
76   NSString *s;
77
78   s = [self tzid];
79   
80   /* a hack */
81   if ([s hasPrefix:@"/softwarestudio.org"]) {
82     NSRange r;
83     
84     r = [s rangeOfString:@"Europe/"];
85     if (r.length > 0)
86       s = [s substringFromIndex:r.location];
87   }
88   return [NSTimeZone timeZoneWithICalId:s];
89 }
90
91 /* decoding */
92
93 - (id)awakeAfterUsingSaxDecoder:(id)_decoder {
94   NSCalendarDate *date = nil;
95   NSString   *s;
96   NSTimeZone *tz;
97   
98   s = self->string;
99   if ([s length] < 5) {
100     [self logWithFormat:@"tag %@: got an weird date string '%@' ?!", 
101             self->tag, s];
102     return s;
103   }
104   
105   /* calculate timezone */
106   
107   if ([self->string hasSuffix:@"Z"]) {
108     /* zulu time, eg 20021009T094500Z */
109     tz = gmt;
110     s = [s substringToIndex:([s length] - 1)];
111   }
112   else
113     tz = [self timeZone];
114   
115   /* 
116      012345678901234
117      20021009T094500 - 15 chars 
118      20021009T0945   - 13 chars 
119      991009T0945     - 11 chars
120      
121      20031111        - 8 chars
122   */
123   if ([s rangeOfString:@"T"].length == 0 && [s length] == 8) {
124     /* hm, maybe a date without a time? like an allday event! */
125     int year, month, day;
126     unsigned char buf[16];
127     [s getCString:&(buf[0])];
128     
129     buf[9] = '\0';
130     day    = atoi(&(buf[6]));  buf[6] = '\0';
131     month  = atoi(&(buf[4]));  buf[4] = '\0';
132     year   = atoi(&(buf[0]));
133     
134     date = [NSCalendarDate dateWithYear:year month:month day:day
135                            hour:0 minute:0 second:0
136                            timeZone:tz];
137   }
138   else if ([s length] == 15) {
139     int year, month, day, hour, minute, second;
140     unsigned char buf[24];
141     [s getCString:&(buf[0])];
142       
143     second = atoi(&(buf[13])); buf[13] = '\0';
144     minute = atoi(&(buf[11])); buf[11] = '\0';
145     hour   = atoi(&(buf[9]));  buf[9] = '\0';
146     day    = atoi(&(buf[6]));  buf[6] = '\0';
147     month  = atoi(&(buf[4]));  buf[4] = '\0';
148     year   = atoi(&(buf[0]));
149       
150     date = [NSCalendarDate dateWithYear:year month:month day:day
151                            hour:hour minute:minute second:second
152                            timeZone:tz];
153   }
154   else
155     NSLog(@"%s: unknown date format (%@) ???", __PRETTY_FUNCTION__, s);
156     
157   if (date == nil)
158     NSLog(@"couldn't convert string '%@' to date (format '%@') ..", s);
159
160   return date;
161 }
162
163 /* description */
164
165 - (NSString *)description {
166   NSMutableString *ms;
167
168   ms = [NSMutableString stringWithCapacity:128];
169   [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
170   
171   if (self->tag)    [ms appendFormat:@" %@",  self->tag];
172   if (self->string) [ms appendFormat:@" '%@'",  self->string];
173   if (self->tzid)   [ms appendFormat:@" tz=%@", self->tzid];
174   
175   [ms appendString:@">"];
176   return ms;
177 }
178
179 @end /* iCalDateHolder */
180
181 @implementation NSTimeZone(iCalTimeZone)
182
183 static NSMutableDictionary *idToTz = nil; // THREAD
184
185 + (NSTimeZone *)timeZoneWithICalId:(NSString *)_tzid {
186   static NSString *iCalDefaultTZ = nil;
187   NSTimeZone *tz;
188   
189   if (idToTz == nil)
190     idToTz = [[NSMutableDictionary alloc] initWithCapacity:16];
191   
192   if ([_tzid length] == 0) {
193     
194     tz = [iCalObject iCalDefaultTimeZone];
195     if (tz != nil) return tz;
196
197     if (iCalDefaultTZ == nil) {
198       NSString *defTz;
199       NSUserDefaults *ud;
200       // TODO: take a default timeZone
201       ud = [NSUserDefaults standardUserDefaults];
202       defTz = [ud stringForKey:@"iCalTimeZoneName"];
203       if ([defTz length] == 0)
204         defTz = [ud stringForKey:@"TimeZoneName"];
205       if ([defTz length] == 0)
206         defTz = [ud stringForKey:@"TimeZone"];
207       if ([defTz length] == 0)
208         defTz = @"GMT";
209       iCalDefaultTZ = [defTz retain];
210     }
211     
212     _tzid = iCalDefaultTZ;
213     
214   }
215   
216   if ([_tzid length] == 0)
217     _tzid = @"GMT";
218   
219   tz = [idToTz objectForKey:_tzid];
220   if (tz == nil) tz = [NSTimeZone timeZoneWithName:_tzid];
221   if (tz == nil) tz = [NSTimeZone timeZoneWithAbbreviation:_tzid];
222   
223   if (tz == nil) {
224     NSLog(@"couldn't map timezone id %@", _tzid);
225   }
226   
227   if (tz) [idToTz setObject:tz forKey:_tzid];
228   return tz;
229 }
230
231 @end /* NSTimeZone(iCalTimeZone) */