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