mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
Move some way towards support of MacOS-X timezone compatibility.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8921 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a1caa1d028
commit
0299d2c87e
4 changed files with 380 additions and 246 deletions
|
@ -1,3 +1,11 @@
|
|||
2001-01-30 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSDate.h: Partial support added for MacOS-X
|
||||
* Source/NSTimeZone.m: Updates to encode all time zones as the
|
||||
abstract class, and added MacOS-X methods.
|
||||
* Source/NSCalendarDate.m: Use NSTimeZone rather than NSTimeZoneDetail
|
||||
throughout ... provide MacOS-X compatibility.
|
||||
|
||||
2001-01-29 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* configure.in: Remove check for alternate libobjc and Headers
|
||||
|
|
|
@ -115,19 +115,15 @@ NSTimeInterval GSTime(int d, int m, int y, int hh, int mm, int ss, int mil);
|
|||
@interface NSTimeZone : NSObject
|
||||
|
||||
//Creating and Initializing an NSTimeZone
|
||||
+ (NSTimeZoneDetail*) defaultTimeZone;
|
||||
+ (NSTimeZone*) localTimeZone;
|
||||
+ (NSTimeZone*) timeZoneForSecondsFromGMT: (int)seconds;
|
||||
+ (NSTimeZoneDetail*) timeZoneWithAbbreviation: (NSString*)abbreviation;
|
||||
+ (NSTimeZone*) timeZoneWithName: (NSString*)aTimeZoneName;
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date;
|
||||
|
||||
//Managing Time Zones
|
||||
+ (void) setDefaultTimeZone: (NSTimeZone*)aTimeZone;
|
||||
|
||||
// Getting Time Zone Information
|
||||
+ (NSDictionary*) abbreviationDictionary;
|
||||
- (NSString*) timeZoneName;
|
||||
|
||||
//Getting Arrays of Time Zones
|
||||
+ (NSArray*) timeZoneArray;
|
||||
|
@ -139,25 +135,40 @@ NSTimeInterval GSTime(int d, int m, int y, int hh, int mm, int ss, int mil);
|
|||
+ (NSDictionary*) abbreviationMap;
|
||||
#endif
|
||||
|
||||
#ifndef STRICT_OPENSTEP
|
||||
- (NSString*) abbreviation;
|
||||
- (NSString*) abbreviationForDate: (NSDate*)aDate;
|
||||
- (BOOL) isDaylightSavingTime;
|
||||
- (BOOL) isDaylightSavingTimeForDate: (NSDate*)aDate;
|
||||
- (BOOL) isEqualToTimeZone: (NSTimeZone*)aTimeZone;
|
||||
- (NSString*) name;
|
||||
- (int) secondsFromGMT;
|
||||
- (int) secondsFromGMTForDate: (NSDate*)aDate;
|
||||
#endif
|
||||
|
||||
#ifndef STRICT_MACOS_X
|
||||
+ (NSTimeZoneDetail*) defaultTimeZone;
|
||||
+ (NSTimeZoneDetail*) timeZoneWithAbbreviation: (NSString*)abbreviation;
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date;
|
||||
- (NSString*) timeZoneName;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#ifndef STRICT_MACOS_X
|
||||
@interface NSTimeZoneDetail : NSTimeZone
|
||||
|
||||
//Querying an NSTimeZoneDetail
|
||||
- (BOOL) isDaylightSavingTimeZone;
|
||||
- (NSString*) timeZoneAbbreviation;
|
||||
- (int) timeZoneSecondsFromGMT;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
||||
@interface NSCalendarDate : NSDate
|
||||
|
||||
{
|
||||
NSTimeInterval _seconds_since_ref;
|
||||
NSString *_calendar_format;
|
||||
NSTimeZoneDetail *_time_zone;
|
||||
NSTimeZone *_time_zone;
|
||||
}
|
||||
|
||||
// Getting an NSCalendar Date
|
||||
|
@ -222,7 +233,12 @@ NSTimeInterval GSTime(int d, int m, int y, int hh, int mm, int ss, int mil);
|
|||
|
||||
// Getting and Setting Time Zones
|
||||
- (void) setTimeZone: (NSTimeZone*)aTimeZone;
|
||||
#ifndef STRICT_OPENSTEP
|
||||
- (NSTimeZone*) timeZone;
|
||||
#endif
|
||||
#ifndef STRICT_MACOS_X
|
||||
- (NSTimeZoneDetail*) timeZoneDetail;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -931,19 +931,28 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
second: (unsigned int)second
|
||||
timeZone: (NSTimeZone *)aTimeZone
|
||||
{
|
||||
int c;
|
||||
NSTimeInterval s;
|
||||
int c;
|
||||
NSDate *d;
|
||||
NSTimeInterval s;
|
||||
NSTimeInterval oldOffset;
|
||||
|
||||
// Calculate date as GMT
|
||||
s = GSTime(day, month, year, hour, minute, second, 0);
|
||||
|
||||
// Assign time zone detail
|
||||
_time_zone = RETAIN([aTimeZone
|
||||
timeZoneDetailForDate:
|
||||
[NSDate dateWithTimeIntervalSinceReferenceDate: s]]);
|
||||
if (aTimeZone == nil)
|
||||
{
|
||||
_time_zone = RETAIN([NSTimeZone localTimeZone]);
|
||||
}
|
||||
else
|
||||
{
|
||||
_time_zone = RETAIN(aTimeZone);
|
||||
}
|
||||
d = [NSDate dateWithTimeIntervalSinceReferenceDate: s];
|
||||
|
||||
// Adjust date so it is correct for time zone.
|
||||
s -= [_time_zone timeZoneSecondsFromGMT];
|
||||
oldOffset = [_time_zone secondsFromGMTForDate: d];
|
||||
s -= oldOffset;
|
||||
self = [self initWithTimeIntervalSinceReferenceDate: s];
|
||||
|
||||
/* Now permit up to five cycles of adjustment to allow for daylight savings.
|
||||
|
@ -953,26 +962,19 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
for (c = 0; c < 5 && self != nil; c++)
|
||||
{
|
||||
int y, m, d, h, mm, ss;
|
||||
NSTimeZoneDetail *z;
|
||||
NSTimeInterval newOffset;
|
||||
|
||||
[self getYear: &y month: &m day: &d hour: &h minute: &mm second: &ss];
|
||||
if (y==year && m==month && d==day && h==hour && mm==minute && ss==second)
|
||||
return self;
|
||||
|
||||
/* Has the time-zone detail changed? If so - adjust time for it,
|
||||
/* Has the time-zone offset changed? If so - adjust time for it,
|
||||
other wise - try to adjust to the correct time. */
|
||||
z = [aTimeZone
|
||||
timeZoneDetailForDate:
|
||||
[NSDate dateWithTimeIntervalSinceReferenceDate: s]];
|
||||
if (z != _time_zone)
|
||||
newOffset = [_time_zone secondsFromGMTForDate: self];
|
||||
if (newOffset != oldOffset)
|
||||
{
|
||||
NSTimeInterval oldOffset;
|
||||
NSTimeInterval newOffset;
|
||||
|
||||
oldOffset = [_time_zone timeZoneSecondsFromGMT];
|
||||
ASSIGN(_time_zone, z);
|
||||
newOffset = [_time_zone timeZoneSecondsFromGMT];
|
||||
s += newOffset - oldOffset;
|
||||
oldOffset = newOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1011,11 +1013,10 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
|
||||
{
|
||||
_seconds_since_ref = seconds;
|
||||
if (!_calendar_format)
|
||||
if (_calendar_format == nil)
|
||||
_calendar_format = @"%Y-%m-%d %H:%M:%S %z";
|
||||
if (!_time_zone)
|
||||
_time_zone = RETAIN([[NSTimeZone localTimeZone]
|
||||
timeZoneDetailForDate: self]);
|
||||
if (_time_zone == nil)
|
||||
_time_zone = RETAIN([NSTimeZone localTimeZone]);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1037,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
// Calculate hour, minute, and seconds
|
||||
d -= GREGORIAN_REFERENCE;
|
||||
d *= 86400;
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone timeZoneSecondsFromGMT]));
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone secondsFromGMTForDate: self]));
|
||||
b = a / 3600;
|
||||
*hour = (int)b;
|
||||
h = *hour;
|
||||
|
@ -1056,7 +1057,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
int r;
|
||||
|
||||
// Get reference date in terms of days
|
||||
a = (_seconds_since_ref+[_time_zone timeZoneSecondsFromGMT]) / 86400.0;
|
||||
a = (_seconds_since_ref+[_time_zone secondsFromGMTForDate: self]) / 86400.0;
|
||||
// Offset by Gregorian reference
|
||||
a += GREGORIAN_REFERENCE;
|
||||
r = (int)a;
|
||||
|
@ -1107,7 +1108,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
double a, d = [self dayOfCommonEra];
|
||||
d -= GREGORIAN_REFERENCE;
|
||||
d *= 86400;
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone timeZoneSecondsFromGMT]));
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone secondsFromGMTForDate: self]));
|
||||
a = a / 3600;
|
||||
h = (int)a;
|
||||
|
||||
|
@ -1125,7 +1126,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
double a, b, d = [self dayOfCommonEra];
|
||||
d -= GREGORIAN_REFERENCE;
|
||||
d *= 86400;
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone timeZoneSecondsFromGMT]));
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone secondsFromGMTForDate: self]));
|
||||
b = a / 3600;
|
||||
h = (int)b;
|
||||
h = h * 3600;
|
||||
|
@ -1152,7 +1153,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
double a, b, c, d = [self dayOfCommonEra];
|
||||
d -= GREGORIAN_REFERENCE;
|
||||
d *= 86400;
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone timeZoneSecondsFromGMT]));
|
||||
a = abs(d - (_seconds_since_ref+[_time_zone secondsFromGMTForDate: self]));
|
||||
b = a / 3600;
|
||||
h = (int)b;
|
||||
h = h * 3600;
|
||||
|
@ -1328,7 +1329,8 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
|
||||
case 'F': // milliseconds
|
||||
s = ([self dayOfCommonEra] - GREGORIAN_REFERENCE) * 86400.0;
|
||||
s -= (_seconds_since_ref+[_time_zone timeZoneSecondsFromGMT]);
|
||||
s -= (_seconds_since_ref
|
||||
+ [_time_zone secondsFromGMTForDate: self]);
|
||||
s = abs(s);
|
||||
s -= floor(s);
|
||||
++i;
|
||||
|
@ -1429,13 +1431,13 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
case 'Z':
|
||||
++i;
|
||||
k = VSPRINTF_LENGTH(sprintf(&(buf[j]), "%s",
|
||||
[[_time_zone timeZoneAbbreviation] cString]));
|
||||
[[_time_zone abbreviationForDate: self] cString]));
|
||||
j += k;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
++i;
|
||||
z = [_time_zone timeZoneSecondsFromGMT];
|
||||
z = [_time_zone secondsFromGMTForDate: self];
|
||||
if (z < 0) {
|
||||
z = -z;
|
||||
z /= 60;
|
||||
|
@ -1511,14 +1513,18 @@ static inline int getDigits(const char *from, char *to, int limit)
|
|||
// Getting and Setting Time Zones
|
||||
- (void) setTimeZone: (NSTimeZone *)aTimeZone
|
||||
{
|
||||
NSTimeZoneDetail *detail = [aTimeZone timeZoneDetailForDate: self];
|
||||
ASSIGN(_time_zone, aTimeZone);
|
||||
}
|
||||
|
||||
ASSIGN(_time_zone, detail);
|
||||
- (NSTimeZone*) timeZone
|
||||
{
|
||||
return _time_zone;
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetail
|
||||
{
|
||||
return _time_zone;
|
||||
NSTimeZoneDetail *detail = [_time_zone timeZoneDetailForDate: self];
|
||||
return detail;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -107,7 +107,7 @@ struct ttinfo
|
|||
|
||||
|
||||
/* The local time zone. */
|
||||
static id localTimeZone;
|
||||
static id localTimeZone;
|
||||
|
||||
/* Dictionary for time zones. Each time zone must have a unique
|
||||
name. */
|
||||
|
@ -119,6 +119,7 @@ static NSDictionary *fake_abbrev_dict;
|
|||
/* Lock for creating time zones. */
|
||||
static NSRecursiveLock *zone_mutex;
|
||||
|
||||
static Class NSTimeZoneClass;
|
||||
|
||||
/* Decode the four bytes at PTR as a signed integer in network byte order.
|
||||
Based on code included in the GNU C Library 2.0.3. */
|
||||
|
@ -308,20 +309,6 @@ decode (const void *ptr)
|
|||
|
||||
@implementation NSConcreteTimeZone
|
||||
|
||||
- (id) initWithName: (NSString*)aName
|
||||
withTransitions: (NSArray*)trans
|
||||
withDetails: (NSArray*)zoneDetails
|
||||
{
|
||||
NSZone *z;
|
||||
|
||||
[super init];
|
||||
z = [self zone];
|
||||
name = [aName copyWithZone: z];
|
||||
transitions = RETAIN(trans);
|
||||
details = RETAIN(zoneDetails);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(name);
|
||||
|
@ -338,21 +325,30 @@ decode (const void *ptr)
|
|||
[aCoder encodeObject: name];
|
||||
}
|
||||
|
||||
- (id) awakeAfterUsingCoder: (NSCoder*)aCoder
|
||||
- (id) initWithName: (NSString*)aName
|
||||
withTransitions: (NSArray*)trans
|
||||
withDetails: (NSArray*)zoneDetails
|
||||
{
|
||||
if ([name isEqual: @"NSLocalTimeZone"])
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
return localTimeZone;
|
||||
name = [aName copyWithZone: [self zone]];
|
||||
transitions = RETAIN(trans);
|
||||
details = RETAIN(zoneDetails);
|
||||
}
|
||||
return [NSTimeZone timeZoneWithName: name];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
[aDecoder decodeValueOfObjCType: @encode(id) at: &name];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString*) name
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
- (NSArray*) timeZoneDetailArray
|
||||
{
|
||||
return details;
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
{
|
||||
unsigned index;
|
||||
|
@ -388,16 +384,6 @@ decode (const void *ptr)
|
|||
return [details objectAtIndex: index];
|
||||
}
|
||||
|
||||
- (NSArray*) timeZoneDetailArray
|
||||
{
|
||||
return details;
|
||||
}
|
||||
|
||||
- (NSString*) timeZoneName
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -414,32 +400,6 @@ static NSMapTable *absolutes = 0;
|
|||
}
|
||||
}
|
||||
|
||||
- (id) initWithOffset: (int)anOffset
|
||||
{
|
||||
NSConcreteAbsoluteTimeZone *z;
|
||||
|
||||
[zone_mutex lock];
|
||||
z = (NSConcreteAbsoluteTimeZone*)NSMapGet(absolutes, (void*)(gsaddr)anOffset);
|
||||
if (z)
|
||||
{
|
||||
IF_NO_GC(RETAIN(z));
|
||||
RELEASE(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
[super init];
|
||||
name = [[NSString alloc] initWithFormat: @"%d", anOffset];
|
||||
detail = [[NSConcreteTimeZoneDetail alloc]
|
||||
initWithTimeZone: self withAbbrev: name
|
||||
withOffset: anOffset withDST: NO];
|
||||
offset = anOffset;
|
||||
z = self;
|
||||
NSMapInsert(absolutes, (void*)(gsaddr)anOffset, (void*)z);
|
||||
}
|
||||
[zone_mutex unlock];
|
||||
return z;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[zone_mutex lock];
|
||||
|
@ -455,49 +415,53 @@ static NSMapTable *absolutes = 0;
|
|||
[aCoder encodeObject: name];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
- (id) initWithOffset: (int)anOffset
|
||||
{
|
||||
[aDecoder decodeValueOfObjCType: @encode(id) at: &name];
|
||||
offset = [name intValue];
|
||||
detail = [[NSConcreteTimeZoneDetail alloc]
|
||||
initWithTimeZone: self withAbbrev: name
|
||||
withOffset: offset withDST: NO];
|
||||
return self;
|
||||
NSConcreteAbsoluteTimeZone *z;
|
||||
|
||||
[zone_mutex lock];
|
||||
z = (NSConcreteAbsoluteTimeZone*)NSMapGet(absolutes, (void*)(gsaddr)anOffset);
|
||||
if (z)
|
||||
{
|
||||
IF_NO_GC(RETAIN(z));
|
||||
RELEASE(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
[super init];
|
||||
name = [[NSString alloc] initWithFormat: @"NSAbsoluteTimeZone:%d",
|
||||
anOffset];
|
||||
detail = [[NSConcreteTimeZoneDetail alloc]
|
||||
initWithTimeZone: self withAbbrev: name
|
||||
withOffset: anOffset withDST: NO];
|
||||
offset = anOffset;
|
||||
z = self;
|
||||
NSMapInsert(absolutes, (void*)(gsaddr)anOffset, (void*)z);
|
||||
}
|
||||
[zone_mutex unlock];
|
||||
return z;
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
{
|
||||
return detail;
|
||||
}
|
||||
|
||||
- (NSString*) timeZoneName
|
||||
- (NSString*) name
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) timeZoneDetailArray
|
||||
{
|
||||
return [NSArray arrayWithObject: detail];
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
{
|
||||
return detail;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSConcreteTimeZoneDetail
|
||||
|
||||
- (id) initWithTimeZone: (NSTimeZone*)aZone
|
||||
withAbbrev: (NSString*)anAbbrev
|
||||
withOffset: (int)anOffset
|
||||
withDST: (BOOL)isDST
|
||||
{
|
||||
[super init];
|
||||
timeZone = RETAIN(aZone);
|
||||
abbrev = RETAIN(anAbbrev);
|
||||
offset = anOffset;
|
||||
is_dst = isDST;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(timeZone);
|
||||
|
@ -519,48 +483,123 @@ static NSMapTable *absolutes = 0;
|
|||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &is_dst];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithTimeZone: (NSTimeZone*)aZone
|
||||
withAbbrev: (NSString*)anAbbrev
|
||||
withOffset: (int)anOffset
|
||||
withDST: (BOOL)isDST
|
||||
{
|
||||
[super init];
|
||||
timeZone = RETAIN(aZone);
|
||||
abbrev = RETAIN(anAbbrev);
|
||||
offset = anOffset;
|
||||
is_dst = isDST;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
{
|
||||
return [timeZone timeZoneDetailForDate: date];
|
||||
}
|
||||
|
||||
- (NSString*) timeZoneName
|
||||
{
|
||||
return [timeZone timeZoneName];
|
||||
}
|
||||
|
||||
- (NSArray*) timeZoneDetailArray
|
||||
{
|
||||
return [timeZone timeZoneDetailArray];
|
||||
}
|
||||
|
||||
- (BOOL) isDaylightSavingTimeZone
|
||||
{
|
||||
return is_dst;
|
||||
}
|
||||
|
||||
- (NSString*) name
|
||||
{
|
||||
return [timeZone name];
|
||||
}
|
||||
|
||||
- (NSString*) timeZoneAbbreviation
|
||||
{
|
||||
return abbrev;
|
||||
}
|
||||
|
||||
- (NSArray*) timeZoneDetailArray
|
||||
{
|
||||
return [timeZone timeZoneDetailArray];
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
{
|
||||
return [timeZone timeZoneDetailForDate: date];
|
||||
}
|
||||
|
||||
- (int) timeZoneSecondsFromGMT
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
- (int) timeZoneSecondsFromGMTForDate: (NSDate*)aDate
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSTimeZone
|
||||
|
||||
+ (NSDictionary*) abbreviationDictionary
|
||||
{
|
||||
return fake_abbrev_dict;
|
||||
}
|
||||
|
||||
+ (NSDictionary*) abbreviationMap
|
||||
{
|
||||
/* Instead of creating the abbreviation dictionary when the class is
|
||||
initialized, we create it when we first need it, since the
|
||||
dictionary can be potentially very large, considering that it's
|
||||
almost never used. */
|
||||
|
||||
static NSMutableDictionary *abbreviationDictionary = nil;
|
||||
FILE *file; // For the file containing the abbreviation dictionary
|
||||
char abbrev[80], name[80];
|
||||
NSString *fileName;
|
||||
|
||||
if (abbreviationDictionary != nil)
|
||||
return abbreviationDictionary;
|
||||
|
||||
/* Read dictionary from file. */
|
||||
abbreviationDictionary = [[NSMutableDictionary alloc] init];
|
||||
fileName = [NSTimeZone getAbbreviationFile];
|
||||
#if defined(__WIN32__)
|
||||
file = fopen([fileName fileSystemRepresentation], "rb");
|
||||
#else
|
||||
file = fopen([fileName fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone abbreviation dictionary."];
|
||||
while (fscanf(file, "%79s %79s", abbrev, name) == 2)
|
||||
{
|
||||
id a, the_name, the_abbrev;
|
||||
|
||||
the_name = [NSString stringWithCString: name];
|
||||
the_abbrev = [NSString stringWithCString: abbrev];
|
||||
a = [abbreviationDictionary objectForKey: the_abbrev];
|
||||
if (a == nil)
|
||||
{
|
||||
a = [[NSMutableArray alloc] init];
|
||||
[abbreviationDictionary setObject: a forKey: the_abbrev];
|
||||
}
|
||||
[a addObject: the_name];
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
return abbreviationDictionary;
|
||||
}
|
||||
|
||||
+ (NSTimeZoneDetail*) defaultTimeZone
|
||||
{
|
||||
return [localTimeZone timeZoneDetailForDate: [NSDate date]];
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSTimeZone class])
|
||||
{
|
||||
id localZoneString = nil;
|
||||
id localZoneString = nil;
|
||||
|
||||
NSTimeZoneClass = self;
|
||||
zone_mutex = [NSRecursiveLock new];
|
||||
zoneDictionary = [[NSMutableDictionary alloc] init];
|
||||
|
||||
|
@ -579,7 +618,7 @@ static NSMapTable *absolutes = 0;
|
|||
/*
|
||||
* Try to get timezone from LOCAL_TIME_FILE.
|
||||
*/
|
||||
NSString *f = [NSTimeZone getLocalTimeFile];
|
||||
NSString *f = [NSTimeZoneClass getLocalTimeFile];
|
||||
char zone_name[80];
|
||||
FILE *fp;
|
||||
|
||||
|
@ -608,7 +647,7 @@ static NSMapTable *absolutes = 0;
|
|||
}
|
||||
if (localZoneString != nil)
|
||||
{
|
||||
localTimeZone = [NSTimeZone timeZoneWithName: localZoneString];
|
||||
localTimeZone = [NSTimeZoneClass timeZoneWithName: localZoneString];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -623,7 +662,7 @@ static NSMapTable *absolutes = 0;
|
|||
if (localTimeZone == nil)
|
||||
{
|
||||
NSLog(@"Using time zone with absolute offset 0.");
|
||||
localTimeZone = [NSTimeZone timeZoneForSecondsFromGMT: 0];
|
||||
localTimeZone = [NSTimeZoneClass timeZoneForSecondsFromGMT: 0];
|
||||
}
|
||||
IF_NO_GC(RETAIN(localTimeZone));
|
||||
|
||||
|
@ -631,21 +670,53 @@ static NSMapTable *absolutes = 0;
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [self timeZoneName];
|
||||
}
|
||||
|
||||
+ (NSTimeZoneDetail*) defaultTimeZone
|
||||
{
|
||||
return [localTimeZone timeZoneDetailForDate: [NSDate date]];
|
||||
}
|
||||
|
||||
+ (NSTimeZone*) localTimeZone
|
||||
{
|
||||
return localTimeZone;
|
||||
}
|
||||
|
||||
+ (void) setDefaultTimeZone: (NSTimeZone*)aTimeZone
|
||||
{
|
||||
if (aTimeZone == nil)
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Nil time zone specified."];
|
||||
ASSIGN(localTimeZone, aTimeZone);
|
||||
}
|
||||
|
||||
+ (NSArray*) timeZoneArray
|
||||
{
|
||||
/* We create the array only when we need it to reduce overhead. */
|
||||
|
||||
static NSArray *regionsArray = nil;
|
||||
int index, i;
|
||||
char name[80];
|
||||
FILE *file;
|
||||
id temp_array[24];
|
||||
NSString *fileName;
|
||||
|
||||
if (regionsArray != nil)
|
||||
return regionsArray;
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
temp_array[i] = [NSMutableArray array];
|
||||
|
||||
fileName = [NSTimeZoneClass getRegionsFile];
|
||||
#if defined(__WIN32__)
|
||||
file = fopen([fileName fileSystemRepresentation], "rb");
|
||||
#else
|
||||
file = fopen([fileName fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone regions array file."];
|
||||
while (fscanf(file, "%d %s", &index, name) == 2)
|
||||
[temp_array[index] addObject: [NSString stringWithCString: name]];
|
||||
fclose(file);
|
||||
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
|
||||
return regionsArray;
|
||||
}
|
||||
|
||||
+ (NSTimeZone*) timeZoneForSecondsFromGMT: (int)seconds
|
||||
{
|
||||
/* We simply return the following because an existing time zone with
|
||||
|
@ -702,23 +773,42 @@ static NSMapTable *absolutes = 0;
|
|||
return zone;
|
||||
}
|
||||
|
||||
/* Make sure that only time zone files are accessed.
|
||||
FIXME: Make this more robust. */
|
||||
if ([aTimeZoneName length] == 0
|
||||
|| ([aTimeZoneName cString])[0] == '/'
|
||||
|| strchr([aTimeZoneName cString], '.') != NULL)
|
||||
i = [aTimeZoneName length];
|
||||
if (i == 0)
|
||||
{
|
||||
NSLog(@"Disallowed time zone name `%@'.", aTimeZoneName);
|
||||
NSLog(@"Disallowed null time zone name");
|
||||
[zone_mutex unlock];
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *str = [aTimeZoneName lossyCString];
|
||||
|
||||
if ([aTimeZoneName hasPrefix: @"NSAbsoluteTimeZone:"] == YES)
|
||||
{
|
||||
i = atoi(&str[19]);
|
||||
[zone_mutex unlock];
|
||||
zone = [[NSConcreteAbsoluteTimeZone alloc] initWithOffset: i];
|
||||
AUTORELEASE(zone);
|
||||
return zone;
|
||||
}
|
||||
|
||||
/* Make sure that only time zone files are accessed.
|
||||
FIXME: Make this more robust. */
|
||||
if ((str)[0] == '/' || strchr(str, '.') != NULL)
|
||||
{
|
||||
NSLog(@"Disallowed time zone name `%@'.", aTimeZoneName);
|
||||
[zone_mutex unlock];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
zone = [NSConcreteTimeZone alloc];
|
||||
|
||||
/* Open file. */
|
||||
fileName = [NSTimeZone getTimeZoneFile: aTimeZoneName];
|
||||
fileName = [NSTimeZoneClass getTimeZoneFile: aTimeZoneName];
|
||||
#if defined(__WIN32__)
|
||||
file = fopen([fileName fileSystemRepresentation], "rb");
|
||||
#else
|
||||
|
@ -799,7 +889,7 @@ static NSMapTable *absolutes = 0;
|
|||
[zone initWithName: aTimeZoneName
|
||||
withTransitions: transArray
|
||||
withDetails: detailsArray];
|
||||
[zoneDictionary setObject: zone forKey: [zone timeZoneName]];
|
||||
[zoneDictionary setObject: zone forKey: [zone name]];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
|
@ -820,107 +910,111 @@ static NSMapTable *absolutes = 0;
|
|||
return zone;
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
|
||||
- (NSString*) abbreviation
|
||||
{
|
||||
return [self subclassResponsibility: _cmd];
|
||||
return [self abbreviationForDate: [NSDate date]];
|
||||
}
|
||||
|
||||
+ (void) setDefaultTimeZone: (NSTimeZone*)aTimeZone
|
||||
- (NSString*) abbreviationForDate: (NSDate*)when
|
||||
{
|
||||
if (aTimeZone == nil)
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Nil time zone specified."];
|
||||
ASSIGN(localTimeZone, aTimeZone);
|
||||
NSTimeZoneDetail *detail;
|
||||
|
||||
detail = [self timeZoneDetailForDate: when];
|
||||
return [detail timeZoneAbbreviation];
|
||||
}
|
||||
|
||||
+ (NSDictionary*) abbreviationDictionary
|
||||
- (Class) classForCoder
|
||||
{
|
||||
return fake_abbrev_dict;
|
||||
return NSTimeZoneClass;
|
||||
}
|
||||
|
||||
+ (NSDictionary*) abbreviationMap
|
||||
- (id) copyWithZone: (NSZone*)z
|
||||
{
|
||||
/* Instead of creating the abbreviation dictionary when the class is
|
||||
initialized, we create it when we first need it, since the
|
||||
dictionary can be potentially very large, considering that it's
|
||||
almost never used. */
|
||||
return RETAIN(self);
|
||||
}
|
||||
|
||||
static NSMutableDictionary *abbreviationDictionary = nil;
|
||||
FILE *file; // For the file containing the abbreviation dictionary
|
||||
char abbrev[80], name[80];
|
||||
NSString *fileName;
|
||||
- (NSString*) description
|
||||
{
|
||||
return [self name];
|
||||
}
|
||||
|
||||
if (abbreviationDictionary != nil)
|
||||
return abbreviationDictionary;
|
||||
|
||||
/* Read dictionary from file. */
|
||||
abbreviationDictionary = [[NSMutableDictionary alloc] init];
|
||||
fileName = [NSTimeZone getAbbreviationFile];
|
||||
#if defined(__WIN32__)
|
||||
file = fopen([fileName fileSystemRepresentation], "rb");
|
||||
#else
|
||||
file = fopen([fileName fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone abbreviation dictionary."];
|
||||
while (fscanf(file, "%79s %79s", abbrev, name) == 2)
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
if (self == localTimeZone)
|
||||
{
|
||||
id a, the_name, the_abbrev;
|
||||
|
||||
the_name = [NSString stringWithCString: name];
|
||||
the_abbrev = [NSString stringWithCString: abbrev];
|
||||
a = [abbreviationDictionary objectForKey: the_abbrev];
|
||||
if (a == nil)
|
||||
{
|
||||
a = [[NSMutableArray alloc] init];
|
||||
[abbreviationDictionary setObject: a forKey: the_abbrev];
|
||||
}
|
||||
[a addObject: the_name];
|
||||
[aCoder encodeObject: @"NSLocalTimeZone"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aCoder encodeObject: [self name]];
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
return abbreviationDictionary;
|
||||
}
|
||||
|
||||
- (NSString*) timeZoneName
|
||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
NSString *name;
|
||||
|
||||
[aDecoder decodeValueOfObjCType: @encode(id) at: &name];
|
||||
RELEASE(self);
|
||||
if ([name isEqual: @"NSLocalTimeZone"])
|
||||
{
|
||||
self = RETAIN(localTimeZone);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = RETAIN([NSTimeZoneClass timeZoneWithName: name]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isDaylightSavingTime
|
||||
{
|
||||
return [self isDaylightSavingTimeForDate: [NSDate date]];
|
||||
}
|
||||
|
||||
- (BOOL) isDaylightSavingTimeForDate: (NSDate*)aDate
|
||||
{
|
||||
NSTimeZoneDetail *detail;
|
||||
|
||||
detail = [self timeZoneDetailForDate: aDate];
|
||||
return [detail isDaylightSavingTimeZone];
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
if (other == self)
|
||||
return YES;
|
||||
if ([other isKindOfClass: NSTimeZoneClass] == NO)
|
||||
return NO;
|
||||
return [self isEqualToTimeZone: other];
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToTimeZone: (NSTimeZone*)aTimeZone
|
||||
{
|
||||
if (aTimeZone == self)
|
||||
return YES;
|
||||
if ([[self name] isEqual: [aTimeZone name]] == YES)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString*) name
|
||||
{
|
||||
return [self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
+ (NSArray*) timeZoneArray
|
||||
- (int) secondsFromGMT
|
||||
{
|
||||
/* We create the array only when we need it to reduce overhead. */
|
||||
return [self secondsFromGMTForDate: [NSDate date]];
|
||||
}
|
||||
|
||||
static NSArray *regionsArray = nil;
|
||||
int index, i;
|
||||
char name[80];
|
||||
FILE *file;
|
||||
id temp_array[24];
|
||||
NSString *fileName;
|
||||
- (int) secondsFromGMTForDate: (NSDate*)when
|
||||
{
|
||||
NSTimeZoneDetail *detail;
|
||||
|
||||
if (regionsArray != nil)
|
||||
return regionsArray;
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
temp_array[i] = [NSMutableArray array];
|
||||
|
||||
fileName = [NSTimeZone getRegionsFile];
|
||||
#if defined(__WIN32__)
|
||||
file = fopen([fileName fileSystemRepresentation], "rb");
|
||||
#else
|
||||
file = fopen([fileName fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone regions array file."];
|
||||
while (fscanf(file, "%d %s", &index, name) == 2)
|
||||
[temp_array[index] addObject: [NSString stringWithCString: name]];
|
||||
fclose(file);
|
||||
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
|
||||
return regionsArray;
|
||||
detail = [self timeZoneDetailForDate: when];
|
||||
return [detail timeZoneSecondsFromGMT];
|
||||
}
|
||||
|
||||
- (NSArray*) timeZoneDetailArray
|
||||
|
@ -928,6 +1022,16 @@ static NSMapTable *absolutes = 0;
|
|||
return [self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||
{
|
||||
return [self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (NSString*) timeZoneName
|
||||
{
|
||||
return [self name];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -937,7 +1041,7 @@ static NSMapTable *absolutes = 0;
|
|||
{
|
||||
return [NSString
|
||||
stringWithFormat: @"%@(%@, %s%d)",
|
||||
[self timeZoneName],
|
||||
[self name],
|
||||
[self timeZoneAbbreviation],
|
||||
([self isDaylightSavingTimeZone]? "IS_DST, ": ""),
|
||||
[self timeZoneSecondsFromGMT]];
|
||||
|
|
Loading…
Reference in a new issue