]> err.no Git - sope/blob - sope-ical/NGiCal/NSCalendarDate+ICal.m
minor bugfix for gmtcalfmt
[sope] / sope-ical / NGiCal / NSCalendarDate+ICal.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "NSCalendarDate+ICal.h"
23 #include "iCalDateHolder.h"
24 #include "common.h"
25
26 static NSTimeZone *gmt = nil;
27 static inline void _setupGMT(void) {
28   if (gmt == nil)
29     gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
30 }
31
32 @interface iCalDateHolder (PrivateAPI)
33 - (id)awakeAfterUsingSaxDecoder:(id)_decoder;
34 @end
35
36 @implementation NSCalendarDate(iCalRepresentation)
37
38 /* represention */
39
40 static NSString *gmtcalfmt = @"%Y%m%dT%H%M%SZ";
41
42 + (id)calendarDateWithICalRepresentation:(NSString *)_iCalRep {
43   iCalDateHolder *dh;
44   NSCalendarDate *date;
45   
46   dh = [[iCalDateHolder alloc] init];
47   [dh setString:_iCalRep];
48   date = [dh awakeAfterUsingSaxDecoder:nil];
49   [dh release];
50   return date;
51 }
52
53 - (NSString *)icalStringInGMT {
54   NSTimeZone *oldtz;
55   NSString   *s;
56   _setupGMT();
57   
58   /* set GMT as timezone */
59   oldtz = [[self timeZone] retain];
60   if (oldtz == gmt) {
61     [oldtz release];
62     oldtz = nil;
63   }
64   else {
65     [self setTimeZone:gmt];
66   }
67   
68   /* calc string */
69   s = [self descriptionWithCalendarFormat:gmtcalfmt];
70   
71   /* restore old timezone */
72   if (oldtz) {
73     [self setTimeZone:oldtz];
74     [oldtz release];
75   }
76   
77   return s;
78 }
79
80 - (NSString *)icalStringWithTimeZone:(NSTimeZone *)_tz {
81   _setupGMT();
82   
83   if (_tz == gmt || _tz == nil)
84     return [self icalStringInGMT];
85   else if ([_tz isEqual:gmt])
86     return [self icalStringInGMT];
87   else {
88     /* not in GMT */
89     NSLog(@"WARNING(%s): arbitary timezones not supported yet: %@",
90           __PRETTY_FUNCTION__, _tz);
91     return [self icalStringInGMT];
92   }
93 }
94
95 - (NSString *)icalString {
96   _setupGMT();
97   return [self icalStringWithTimeZone:gmt];
98 }
99
100 @end /* NSDate(ICalValue) */
101
102
103 #ifndef ABS
104 #define ABS(a) ((a) < 0 ? -(a) : (a))
105 #endif
106
107 @implementation NSCalendarDate (iCalRecurrenceCalculatorExtensions)
108
109 - (unsigned)yearsBetweenDate:(NSCalendarDate *)_date {
110   return ABS([self yearOfCommonEra] - [_date yearOfCommonEra]);
111 }
112
113 - (unsigned)monthsBetweenDate:(NSCalendarDate *)_date {
114   NSCalendarDate     *start, *end;
115   NSComparisonResult order;
116   int                yDiff;
117   
118   order = [self compare:_date];
119   if (order == NSOrderedSame)
120     return 0;
121   else if (order == NSOrderedAscending) {
122     start = self;
123     end   = _date;
124   }
125   else {
126     start = _date;
127     end   = self;
128   }
129   yDiff = [end yearOfCommonEra] - [start yearOfCommonEra];
130   if (yDiff > 0) {
131     unsigned monthsRemaining, monthsToGo;
132     
133     monthsRemaining = 12 - [start monthOfYear];
134     monthsToGo      = [end monthOfYear];
135     yDiff          -= 1;
136     return monthsRemaining + monthsToGo + (12 * yDiff);
137   }
138   /* start and end in same year, calculate plain diff */
139   return [end monthOfYear] - [start monthOfYear];
140 }
141
142 - (unsigned)daysBetweenDate:(NSCalendarDate *)_date {
143   return ABS([self julianNumber] - [_date julianNumber]);
144 }
145 @end /* NSCalendarDate (iCalRecurrenceCalculatorExtensions) */