~ubuntu-branches/ubuntu/edgy/sope/edgy

« back to all changes in this revision

Viewing changes to libFoundation/Foundation/NSDate.m

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Ley
  • Date: 2005-08-19 16:53:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050819165331-hs683wz1osm708pw
Tags: upstream-4.4rc.2
ImportĀ upstreamĀ versionĀ 4.4rc.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   NSDate.m
 
3
 
 
4
   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
 
5
   All rights reserved.
 
6
 
 
7
   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
 
8
 
 
9
   This file is part of libFoundation.
 
10
 
 
11
   Permission to use, copy, modify, and distribute this software and its
 
12
   documentation for any purpose and without fee is hereby granted, provided
 
13
   that the above copyright notice appear in all copies and that both that
 
14
   copyright notice and this permission notice appear in supporting
 
15
   documentation.
 
16
 
 
17
   We disclaim all warranties with regard to this software, including all
 
18
   implied warranties of merchantability and fitness, in no event shall
 
19
   we be liable for any special, indirect or consequential damages or any
 
20
   damages whatsoever resulting from loss of use, data or profits, whether in
 
21
   an action of contract, negligence or other tortious action, arising out of
 
22
   or in connection with the use or performance of this software.
 
23
*/
 
24
 
 
25
#include "common.h"
 
26
 
 
27
#if HAVE_SYS_TIME_H
 
28
# include <sys/time.h>
 
29
#endif
 
30
#include <time.h>
 
31
 
 
32
#if HAVE_LIBC_H
 
33
# include <libc.h>
 
34
#else
 
35
# include <unistd.h>
 
36
#endif
 
37
 
 
38
#if HAVE_WINDOWS_H
 
39
# include <windows.h>
 
40
#endif
 
41
 
 
42
#include <Foundation/NSString.h>
 
43
#include <Foundation/NSDate.h>
 
44
#include <Foundation/NSCoder.h>
 
45
#include <Foundation/NSUtilities.h>
 
46
 
 
47
#include "NSConcreteDate.h"
 
48
#include "NSCalendarDate.h"
 
49
 
 
50
#if HAVE_GETLOCALTIME || defined(__MINGW32__)
 
51
static void Date2Long(int theMonth, int theDay, int theYear, long *theDate);
 
52
#define DATE_OFFSET 730486  /* Number of days from January 1, 1
 
53
                        to January 1, 2001 */
 
54
#endif
 
55
 
 
56
@implementation NSDate
 
57
 
 
58
static NSDate *distantFuture = nil, *distantPast = nil;
 
59
 
 
60
#if defined(__svr4__)
 
61
+ (void)initialize {
 
62
    tzset();
 
63
}
 
64
#endif
 
65
 
 
66
+ (id)allocWithZone:(NSZone *)zone
 
67
{
 
68
    return NSAllocateObject( (self == [NSDate class]) ? 
 
69
            [NSConcreteDate class] : self, 0, zone);
 
70
}
 
71
 
 
72
+ (NSDate *)date
 
73
{
 
74
    return AUTORELEASE([[self alloc] init]);
 
75
}
 
76
 
 
77
+ (NSDate *)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs
 
78
{
 
79
    return AUTORELEASE([[self alloc] initWithTimeIntervalSinceNow:secs]);
 
80
}
 
81
 
 
82
+ (NSDate *)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secs
 
83
{
 
84
    return AUTORELEASE([[self alloc]
 
85
                           initWithTimeIntervalSinceReferenceDate:secs]);
 
86
}
 
87
 
 
88
+ (NSDate *)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds
 
89
{
 
90
    return AUTORELEASE([[self alloc] initWithTimeIntervalSince1970:seconds]);
 
91
}
 
92
 
 
93
+ (NSDate *)distantFuture
 
94
{
 
95
    if (distantFuture == nil) {
 
96
        distantFuture = [[self alloc]
 
97
                       initWithTimeIntervalSinceReferenceDate:DISTANT_FUTURE];
 
98
    }
 
99
    return distantFuture;
 
100
}
 
101
 
 
102
+ (NSDate *)distantPast
 
103
{
 
104
    if (distantPast == nil) {
 
105
        distantPast = [[self alloc] 
 
106
                         initWithTimeIntervalSinceReferenceDate:DISTANT_PAST];
 
107
    }
 
108
    return distantPast;
 
109
}
 
110
 
 
111
- (id)init
 
112
{
 
113
    return [super init];
 
114
}
 
115
 
 
116
- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secsToBeAdded
 
117
{
 
118
    [self subclassResponsibility:_cmd];
 
119
    return self;
 
120
}
 
121
 
 
122
- (id)initWithString:(NSString *)description
 
123
{
 
124
    id cal = [[NSCalendarDate alloc] initWithString:description];
 
125
    [self initWithTimeIntervalSinceReferenceDate:
 
126
            [cal timeIntervalSinceReferenceDate]];
 
127
    RELEASE(cal); cal = nil;
 
128
    return self;
 
129
}
 
130
 
 
131
- (NSDate *)initWithTimeInterval:(NSTimeInterval)secsToBeAdded 
 
132
        sinceDate:(NSDate *)anotherDate
 
133
{
 
134
    return [self initWithTimeIntervalSinceReferenceDate:
 
135
            (secsToBeAdded + [anotherDate timeIntervalSinceReferenceDate])];
 
136
}
 
137
 
 
138
- (NSDate *)initWithTimeIntervalSinceNow:(NSTimeInterval)secsToBeAddedToNow
 
139
{
 
140
    [self initWithTimeIntervalSinceReferenceDate:
 
141
        (secsToBeAddedToNow + [NSDate timeIntervalSinceReferenceDate])];
 
142
    return self;
 
143
}
 
144
 
 
145
- (id)initWithTimeIntervalSince1970:(NSTimeInterval)seconds
 
146
{
 
147
    [self initWithTimeIntervalSinceReferenceDate: seconds + UNIX_OFFSET];
 
148
    return self;
 
149
}
 
150
 
 
151
/* Copying */
 
152
 
 
153
- (id)copyWithZone:(NSZone *)zone
 
154
{
 
155
    if (NSShouldRetainWithZone(self, zone))
 
156
        return RETAIN(self);
 
157
    else
 
158
        return [[[self class] alloc] initWithTimeIntervalSinceReferenceDate:
 
159
                [self timeIntervalSinceReferenceDate]];
 
160
}
 
161
 
 
162
/* Representing Dates */
 
163
 
 
164
- (NSString *)propertyListStringWithLocale:(NSDictionary *)_locale
 
165
  indent:(unsigned int)_indent
 
166
{
 
167
    return [[self descriptionWithLocale:_locale] stringRepresentation];
 
168
}
 
169
 
 
170
- (NSString *)stringRepresentation {
 
171
    return [[self description] stringRepresentation];
 
172
}
 
173
 
 
174
- (NSString *)description
 
175
{
 
176
    return [[NSCalendarDate dateWithTimeIntervalSinceReferenceDate:
 
177
                [self timeIntervalSinceReferenceDate]] description];
 
178
}       
 
179
 
 
180
- (NSString *)descriptionWithCalendarFormat:(NSString *)formatString
 
181
        timeZone:(NSTimeZone *)aTimeZone
 
182
        locale:(NSDictionary *)locale   
 
183
{
 
184
    id calendar = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate:
 
185
        [self timeIntervalSinceReferenceDate]];
 
186
    [calendar setTimeZone:aTimeZone];
 
187
    return [calendar descriptionWithCalendarFormat:formatString
 
188
        timeZone:aTimeZone locale:locale];
 
189
 
190
 
 
191
- (NSString *)descriptionWithLocale:(NSDictionary *)locale
 
192
{
 
193
    id calendar = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate:
 
194
        [self timeIntervalSinceReferenceDate]];
 
195
    return [calendar descriptionWithLocale:locale];
 
196
}
 
197
 
 
198
/* Adding and Getting Intervals */
 
199
 
 
200
+ (NSTimeInterval)timeIntervalSinceReferenceDate
 
201
{
 
202
#if HAVE_GETTIMEOFDAY
 
203
    /* eg: used on SuSE Linux */
 
204
    NSTimeInterval  theTime = UNIX_OFFSET;
 
205
    struct timeval  tp;
 
206
    struct timezone tzp = { 0, 0 };
 
207
 
 
208
    gettimeofday(&tp, &tzp);
 
209
 
 
210
    /* theTime contains 1970 (Unix ref time) and gets added seconds and micros */
 
211
    theTime += tp.tv_sec;
 
212
    theTime += (double)tp.tv_usec / 1000000.0;
 
213
 
 
214
#if 0 && defined(__svr4__)
 
215
    {
 
216
        extern time_t timezone, altzone;
 
217
        theTime -= (double)altzone;
 
218
    }
 
219
#else
 
220
#  if !defined(__linux__)
 
221
    /* this is not to be used on Linux, see 'gettimeofday' man page */
 
222
    theTime -= tzp.tz_minuteswest * 60 + (tzp.tz_dsttime ? 3600 : 0);
 
223
#  endif
 
224
#endif
 
225
 
 
226
    return theTime;
 
227
 
 
228
#elif HAVE_GETLOCALTIME
 
229
 
 
230
    NSTimeInterval  theTime = 0;
 
231
    SYSTEMTIME      tp;
 
232
    long            date;
 
233
 
 
234
    GetLocalTime(&tp);
 
235
    Date2Long(tp.wMonth, tp.wDay, tp.wYear, &date);
 
236
 
 
237
    theTime = ((NSTimeInterval)date - DATE_OFFSET) * 86400 +
 
238
        tp.wHour * 3600 + tp.wMinute * 60 + tp.wSecond +
 
239
        tp.wMilliseconds / 1000.0 ;
 
240
    return theTime;
 
241
 
 
242
#elif defined(__MINGW32__)
 
243
    NSTimeInterval theTime = 0;
 
244
    SYSTEMTIME     tp;
 
245
    long           date;
 
246
 
 
247
    GetSystemTime(&tp);
 
248
    Date2Long(tp.wMonth, tp.wDay, tp.wYear, &date);
 
249
 
 
250
    theTime = ((NSTimeInterval)date - DATE_OFFSET) * 86400 +
 
251
        tp.wHour * 3600 + tp.wMinute * 60 + tp.wSecond +
 
252
        tp.wMilliseconds / 1000.0 ;
 
253
    return theTime;
 
254
#else
 
255
#error no time function
 
256
#endif
 
257
}
 
258
 
 
259
- (NSTimeInterval)timeIntervalSinceReferenceDate
 
260
{
 
261
    [self subclassResponsibility:_cmd];
 
262
    return 0;
 
263
}
 
264
 
 
265
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate;
 
266
{
 
267
    return [self timeIntervalSinceReferenceDate] -
 
268
            [anotherDate timeIntervalSinceReferenceDate];
 
269
}
 
270
 
 
271
- (NSTimeInterval)timeIntervalSinceNow
 
272
{
 
273
    return [self timeIntervalSinceReferenceDate] -
 
274
            [NSDate timeIntervalSinceReferenceDate];
 
275
}
 
276
 
 
277
- (id)addTimeInterval:(NSTimeInterval)seconds
 
278
{
 
279
    return AUTORELEASE([[[self class] alloc]
 
280
                           initWithTimeInterval:seconds sinceDate:self]);
 
281
}
 
282
 
 
283
- (NSTimeInterval)timeIntervalSince1970
 
284
{
 
285
    return [self timeIntervalSinceReferenceDate] - UNIX_OFFSET;
 
286
}
 
287
 
 
288
/* Comparing Dates */
 
289
 
 
290
- (NSDate *)earlierDate:(NSDate *)anotherDate
 
291
{
 
292
    if (!anotherDate) return self;
 
293
 
 
294
    return [self compare:anotherDate] == NSOrderedAscending?
 
295
            self : anotherDate;
 
296
}
 
297
 
 
298
- (NSDate *)laterDate:(NSDate *)anotherDate
 
299
{
 
300
    if (!anotherDate) return self;
 
301
 
 
302
    return [self compare:anotherDate] == NSOrderedAscending ?
 
303
            anotherDate : self;
 
304
}
 
305
 
 
306
- (NSComparisonResult)compare:(NSDate *)other
 
307
{
 
308
    [self subclassResponsibility:_cmd];
 
309
    return NSOrderedSame;
 
310
}
 
311
 
 
312
- (BOOL)isEqual:other
 
313
{
 
314
    return [other isKindOfClass:[NSDate class]] &&
 
315
           [self isEqualToDate:other];
 
316
}
 
317
 
 
318
- (BOOL)isEqualToDate:other
 
319
{
 
320
    return [self compare:other] == NSOrderedSame;
 
321
}
 
322
 
 
323
/* Converting to an NSCalendar Object */
 
324
- (NSCalendarDate *)dateWithCalendarFormat:(NSString *)aFormatString
 
325
        timeZone:(NSTimeZone *)aTimeZone
 
326
{
 
327
    id new = AUTORELEASE([[NSCalendarDate alloc] 
 
328
                             initWithTimeIntervalSinceReferenceDate:
 
329
                                 [self timeIntervalSinceReferenceDate]]);
 
330
    [new setCalendarFormat:aFormatString];
 
331
    [new setTimeZone:aTimeZone];
 
332
    return new;
 
333
}
 
334
 
 
335
/* new in MacOSX */
 
336
+ (id)dateWithNaturalLanguageString:(NSString *)_string
 
337
{
 
338
    return [self dateWithNaturalLanguageString:_string
 
339
                 locale:nil];
 
340
}
 
341
 
 
342
+ (id)dateWithNaturalLanguageString:(NSString *)_string
 
343
  locale:(NSDictionary *)_locale
 
344
{
 
345
    return [self notImplemented:_cmd];
 
346
}
 
347
 
 
348
/* Encoding */
 
349
- (Class)classForCoder
 
350
{
 
351
    return [NSDate class];
 
352
}
 
353
 
 
354
- (void)encodeWithCoder:(NSCoder *)aCoder
 
355
{
 
356
    NSTimeInterval timeDiff = [self timeIntervalSinceReferenceDate];
 
357
 
 
358
    [aCoder encodeValueOfObjCType:@encode(NSTimeInterval) at:&timeDiff];
 
359
}
 
360
 
 
361
- (id)initWithCoder:(NSCoder *)aDecoder
 
362
{
 
363
    NSTimeInterval timeDiff;
 
364
 
 
365
    [aDecoder decodeValueOfObjCType:@encode(NSTimeInterval) at:&timeDiff];
 
366
    [self initWithTimeIntervalSinceReferenceDate:timeDiff];
 
367
    return self;
 
368
}
 
369
 
 
370
@end /* NSDate */
 
371
 
 
372
#if HAVE_GETLOCALTIME || defined(__MINGW32__)
 
373
 
 
374
static int nDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
375
#define bisect(a)   ((a) % 4 == 0 && ((a) % 400 == 0 || (a) % 100 ))
 
376
#define nr_bisect(a)    ((a - 1) / 4 - nr_nebisect(a - 1))
 
377
 
 
378
static int nr_nebisect(int a)
 
379
{
 
380
    int i;
 
381
    int ret = 0;
 
382
 
 
383
    for(i = 100; i <= a; i += 100)
 
384
    ret += (i % 400 != 0);
 
385
    return ret;
 
386
}
 
387
 
 
388
static void Date2Long(int theMonth, int theDay, int theYear, long *theDate)
 
389
{
 
390
    long base, offset = 0;
 
391
    int i;
 
392
 
 
393
    base = ((long)theYear - 1) * 365 + nr_bisect(theYear);
 
394
    for (i = 1; i < theMonth; i++)
 
395
    offset += nDays[i - 1];
 
396
    offset += theDay;
 
397
    if (theMonth > 2 && bisect(theYear))
 
398
    offset++;
 
399
    *theDate = base + offset;
 
400
}
 
401
#endif
 
402
/*
 
403
  Local Variables:
 
404
  c-basic-offset: 4
 
405
  tab-width: 8
 
406
  End:
 
407
*/
 
408