sogo/SOPE/NGCards/iCalDateHolder.m
Wolfgang Sourdeau cd510f7473 Monotone-Parent: 61d11066e0e001f91446e76044b712194a177089
Monotone-Revision: 4e643e3e8f08c6cdd2abe4483bdb2cdb7dc15066

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2007-06-07T16:17:51
Monotone-Branch: ca.inverse.sogo
2007-06-07 16:17:51 +00:00

241 lines
5.9 KiB
Objective-C

/*
Copyright (C) 2000-2005 SKYRIX Software AG
This file is part of SOPE.
SOPE is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with SOPE; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <Foundation/NSDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSUserDefaults.h>
#import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import "iCalDateHolder.h"
#import "iCalObject.h"
@interface NSTimeZone(iCalTimeZone)
+ (NSTimeZone *)timeZoneWithICalId:(NSString *)_tz;
@end
@implementation iCalDateHolder
static NSTimeZone *gmt = nil;
+ (void)initialize {
if (gmt == nil)
gmt = [[NSTimeZone timeZoneWithName:@"GMT"] retain];
}
- (void)dealloc {
[self->tzid release];
[self->string release];
[self->tag release];
[super dealloc];
}
/* accessors */
- (void)setString:(NSString *)_value {
ASSIGNCOPY(self->string, _value);
}
- (NSString *)string {
return self->string;
}
- (void)setTag:(NSString *)_value {
ASSIGNCOPY(self->tag, _value);
}
- (NSString *)tag {
return self->tag;
}
- (void)setTzid:(NSString *)_value {
ASSIGNCOPY(self->tzid, _value);
}
- (NSString *)tzid {
return self->tzid;
}
/* mapping to Foundation */
- (NSTimeZone *)timeZone {
// TODO: lookup tzid in iCalCalendar !
NSString *s;
s = [self tzid];
/* a hack */
if ([s hasPrefix:@"/softwarestudio.org"]) {
NSRange r;
r = [s rangeOfString:@"Europe/"];
if (r.length > 0)
s = [s substringFromIndex:r.location];
}
return [NSTimeZone timeZoneWithICalId:s];
}
/* decoding */
- (id)awakeAfterUsingSaxDecoder:(id)_decoder {
NSCalendarDate *date = nil;
NSString *s;
NSTimeZone *tz;
s = self->string;
if ([s length] < 5) {
[self logWithFormat:@"tag %@: got an weird date string '%@' ?!",
self->tag, s];
return s;
}
/* calculate timezone */
if ([self->string hasSuffix:@"Z"]) {
/* zulu time, eg 20021009T094500Z */
tz = gmt;
s = [s substringToIndex:([s length] - 1)];
}
else
tz = [self timeZone];
/*
012345678901234
20021009T094500 - 15 chars
20021009T0945 - 13 chars
991009T0945 - 11 chars
20031111 - 8 chars
*/
if ([s rangeOfString:@"T"].length == 0 && [s length] == 8) {
/* hm, maybe a date without a time? like an allday event! */
int year, month, day;
char buf[16];
[s getCString:&(buf[0])];
buf[9] = '\0';
day = atoi(&(buf[6])); buf[6] = '\0';
month = atoi(&(buf[4])); buf[4] = '\0';
year = atoi(&(buf[0]));
date = [NSCalendarDate dateWithYear:year month:month day:day
hour:0 minute:0 second:0
timeZone:tz];
}
else if ([s length] == 15) {
int year, month, day, hour, minute, second;
char buf[24];
[s getCString:&(buf[0])];
second = atoi(&(buf[13])); buf[13] = '\0';
minute = atoi(&(buf[11])); buf[11] = '\0';
hour = atoi(&(buf[9])); buf[9] = '\0';
day = atoi(&(buf[6])); buf[6] = '\0';
month = atoi(&(buf[4])); buf[4] = '\0';
year = atoi(&(buf[0]));
date = [NSCalendarDate dateWithYear:year month:month day:day
hour:hour minute:minute second:second
timeZone:tz];
}
else
NSLog(@"%s: unknown date format (%@) ???", __PRETTY_FUNCTION__, s);
if (date == nil)
NSLog(@"couldn't convert string '%@' to date (format '%@') ..", s);
return date;
}
/* description */
- (void)appendAttributesToDescription:(NSMutableString *)ms {
if (self->tag) [ms appendFormat:@" %@", self->tag];
if (self->string) [ms appendFormat:@" '%@'", self->string];
if (self->tzid) [ms appendFormat:@" tz=%@", self->tzid];
}
- (NSString *)description {
NSMutableString *ms;
ms = [NSMutableString stringWithCapacity:128];
[ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])];
[self appendAttributesToDescription:ms];
[ms appendString:@">"];
return ms;
}
@end /* iCalDateHolder */
@implementation NSTimeZone(iCalTimeZone)
static NSMutableDictionary *idToTz = nil; // THREAD
+ (NSTimeZone *)timeZoneWithICalId:(NSString *)_tzid {
static NSString *iCalDefaultTZ = nil;
NSTimeZone *tz;
if (idToTz == nil)
idToTz = [[NSMutableDictionary alloc] initWithCapacity:16];
if ([_tzid length] == 0) {
tz = [iCalObject iCalDefaultTimeZone];
if (tz != nil) return tz;
if (iCalDefaultTZ == nil) {
NSString *defTz;
NSUserDefaults *ud;
// TODO: take a default timeZone
ud = [NSUserDefaults standardUserDefaults];
defTz = [ud stringForKey:@"iCalTimeZoneName"];
if ([defTz length] == 0)
defTz = [ud stringForKey:@"TimeZoneName"];
if ([defTz length] == 0)
defTz = [ud stringForKey:@"TimeZone"];
if ([defTz length] == 0)
defTz = @"GMT";
iCalDefaultTZ = [defTz retain];
}
_tzid = iCalDefaultTZ;
}
if ([_tzid length] == 0)
_tzid = @"GMT";
tz = [idToTz objectForKey:_tzid];
if (tz == nil) tz = [NSTimeZone timeZoneWithName:_tzid];
if (tz == nil) tz = [NSTimeZone timeZoneWithAbbreviation:_tzid];
if (tz == nil) {
NSLog(@"couldn't map timezone id %@", _tzid);
}
if (tz) [idToTz setObject:tz forKey:_tzid];
return tz;
}
@end /* NSTimeZone(iCalTimeZone) */