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:
Richard Frith-MacDonald 2001-01-30 12:05:02 +00:00
parent a1caa1d028
commit 0299d2c87e
4 changed files with 380 additions and 246 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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]];