Cleans up code and adds documentation.
--- ../core/base/Source/NSTimeZone.m.cvs 2003-11-19 17:39:06.000000000 +0800
+++ ../core/base/Source/NSTimeZone.m 2003-12-14 12:30:54.000000000 +0800
@@ -39,13 +39,45 @@
eventually have to change the implementation to prevent the year
2038 problem.)
- The local time zone can be specified with the user defaults
- database, the GNUSTEP_TZ environment variable, the file LOCAL_TIME_FILE,
- the TZ environment variable, or the fallback time zone (which is UTC),
+ The local time zone can be specified with:
+ 1) the user defaults database
+ 2) the GNUSTEP_TZ environment variable
+ 3) the file LOCAL_TIME_FILE in _time_zone_path()
+ 4) the TZ environment variable
+ 5) or the fallback time zone (which is UTC)
with the ones listed first having precedence.
Any time zone must be a file name in ZONES_DIR.
+ Files & File System Heirarchy info:
+ ===================================
+
+ Default place for the NSTimeZone directory is _time_zone_path():
+ {$(GNUSTEP_SYSTEM_ROOT)Libary/Libraries/Resources/TIME_ZONE_DIR}
+
+ LOCAL_TIME_FILE is a text file with the name of the time zone file.
+
+ ZONES_DIR is a sub-directory under TIME_ZONE_DIR
+
+ (dir) ../System/Library/Libraries/Resources/..
+ (dir) NSTimeZone
+ (file) localtime {text; time zone eg Australia/Perth}
+ (dir) zones
+
+ Since NSTimeZone gets the name from LOCAL_TIME_FILE it's sufficient
+ to symlink this to the time zone name used elsewhere. For example:
+ Debian uses "/etc/timezone"
+
+ A number of POSIX systems have the zone files already installed.
+ For these systems it is sufficient to symlink ZONES_DIR to the
+ platform specific location.
+ For (g)libc6 this is /usr/share/zoneinfo
+ For Solaris this is /usr/share/lib/zoneinfo
+
+ Note that full zone info is required, especially the various "GMT"
+ files which are created especially for OPENSTEP compatibility.
+ Zone info comes from the Olson time database.
+
FIXME?: use leap seconds? */
#include "config.h"
@@ -87,7 +119,8 @@
/* Key for local time zone in user defaults. */
#define LOCALDBKEY @"Local Time Zone"
-/* Directory that contains the time zone data. */
+/* Directory that contains the time zone data.
+ Expected in Resources directory for library bundle. */
#define TIME_ZONE_DIR @"NSTimeZones"
/* Location of time zone abbreviation dictionary. It is a text file
@@ -113,13 +146,13 @@
@class GSTimeZoneDetail;
@class GSAbsTimeZoneDetail;
[EMAIL PROTECTED] GSPlaceholderTimeZone;
[EMAIL PROTECTED] GSPlaceholderTimeZone;
/*
* Information for abstract placeholder class.
*/
-static GSPlaceholderTimeZone *defaultPlaceholderTimeZone;
-static NSMapTable *placeholderMap;
+static GSPlaceholderTimeZone *defaultPlaceholderTimeZone;
+static NSMapTable *placeholderMap;
/*
* Temporary structure for holding time zone details.
@@ -127,8 +160,8 @@
*/
struct ttinfo
{
- char offset[4]; // Seconds east of UTC
- unsigned char isdst; // Daylight savings time?
+ char offset[4]; // Seconds east of UTC
+ unsigned char isdst; // Daylight savings time?
unsigned char abbr_idx; // Index into time zone abbreviations string
};
@@ -136,30 +169,30 @@
* And this is the structure used in the time zone instances.
*/
typedef struct {
- gss32 offset;
- BOOL isdst;
- unsigned char abbr_idx;
- char pad[2];
- NSString *abbreviation;
+ gss32 offset;
+ BOOL isdst;
+ unsigned char abbr_idx;
+ char pad[2];
+ NSString *abbreviation;
} TypeInfo;
[EMAIL PROTECTED] GSTimeZone : NSTimeZone
[EMAIL PROTECTED] GSTimeZone : NSTimeZone
{
@public
- NSString *timeZoneName;
- NSData *timeZoneData;
- unsigned int n_trans;
- unsigned int n_types;
- gss32 *trans;
- TypeInfo *types;
- unsigned char *idxs;
+ NSString *timeZoneName;
+ NSData *timeZoneData;
+ unsigned int n_trans;
+ unsigned int n_types;
+ gss32 *trans;
+ TypeInfo *types;
+ unsigned char *idxs;
}
@end
-static NSTimeZone *defaultTimeZone = nil;
-static NSTimeZone *localTimeZone = nil;
-static NSTimeZone *systemTimeZone = nil;
+static NSTimeZone *defaultTimeZone = nil;
+static NSTimeZone *localTimeZone = nil;
+static NSTimeZone *systemTimeZone = nil;
/* Dictionary for time zones. Each time zone must have a unique
name. */
@@ -171,8 +204,8 @@
/* Lock for creating time zones. */
static NSRecursiveLock *zone_mutex = nil;
-static Class NSTimeZoneClass;
-static Class GSPlaceholderTimeZoneClass;
+static Class NSTimeZoneClass;
+static Class GSPlaceholderTimeZoneClass;
/* 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. */
@@ -205,8 +238,8 @@
NSBundle *gbundle;
gbundle = [NSBundle bundleForLibrary: @"gnustep-base"];
return [gbundle pathForResource: subpath
- ofType: @""
- inDirectory: TIME_ZONE_DIR];
+ ofType: @""
+ inDirectory: TIME_ZONE_DIR];
}
/* Object enumerator for NSInternalAbbrevDict. */
@@ -230,9 +263,9 @@
@interface GSAbsTimeZone : NSTimeZone
{
@public
- NSString *name;
- id detail;
- int offset; // Offset from UTC in seconds.
+ NSString *name;
+ id detail;
+ int offset; // Offset from UTC in seconds.
}
- (id) initWithOffset: (int)anOffset;
@@ -243,21 +276,21 @@
@interface GSTimeZoneDetail : NSTimeZoneDetail
{
- NSTimeZone *timeZone; // Time zone which created this object.
- NSString *abbrev; // Abbreviation for time zone detail.
- int offset; // Offset from UTC in seconds.
- BOOL is_dst; // Is it daylight savings time?
+ NSTimeZone *timeZone; // Time zone which created this object.
+ NSString *abbrev; // Abbreviation for time zone detail.
+ int offset; // Offset from UTC in seconds.
+ BOOL is_dst; // Is it daylight savings time?
}
- (id) initWithTimeZone: (NSTimeZone*)aZone
- withAbbrev: (NSString*)anAbbrev
- withOffset: (int)anOffset
- withDST: (BOOL)isDST;
+ withAbbrev: (NSString*)anAbbrev
+ withOffset: (int)anOffset
+ withDST: (BOOL)isDST;
@end
@interface GSAbsTimeZoneDetail : NSTimeZoneDetail
{
- GSAbsTimeZone *zone; // Time zone which created this object.
+ GSAbsTimeZone *zone; // Time zone which created this object.
}
- (id) initWithTimeZone: (GSAbsTimeZone*)aZone;
@@ -324,7 +357,7 @@
- (NSEnumerator*) objectEnumerator
{
return AUTORELEASE([[NSInternalAbbrevDictObjectEnumerator alloc]
- initWithDict: [NSTimeZone abbreviationMap]]);
+ initWithDict: [NSTimeZone abbreviationMap]]);
}
- (id) objectForKey: (NSString*)key
@@ -340,18 +373,18 @@
- (id) autorelease
{
NSWarnLog(@"-autorelease sent to uninitialised time zone");
- return self; // placeholders never get released.
+ return self; // placeholders never get released.
}
- (void) dealloc
{
- return; // placeholders never get deallocated.
+ return; // placeholders never get deallocated.
}
- (id) initWithName: (NSString*)name data: (NSData*)data
{
- NSTimeZone *zone;
- unsigned length = [name length];
+ NSTimeZone *zone;
+ unsigned length = [name length];
if (length == 0)
{
@@ -386,68 +419,68 @@
if (zone == nil)
{
- unichar c;
- unsigned i;
+ unichar c;
+ unsigned i;
if (length == 8 && [name hasPrefix: @"GMT"] == YES
- && ((c = [name characterAtIndex: 3]) == '+' || c == '-'))
- {
- c = [name characterAtIndex: 4];
- if (c >= '0' && c <= '9')
- {
- i = c - '0';
- c = [name characterAtIndex: 5];
- if (c >= '0' && c <= '9')
- {
- i = i * 10 + (c - '0');
- c = [name characterAtIndex: 6];
- if (c >= '0' && c <= '9')
- {
- i = i * 6 + (c - '0');
- c = [name characterAtIndex: 7];
- if (c >= '0' && c <= '9')
- {
- i = i * 10 + (c - '0');
- zone = [[GSAbsTimeZone alloc] initWithOffset: i*60];
- }
- }
- }
- }
- }
+ && ((c = [name characterAtIndex: 3]) == '+' || c == '-'))
+ {
+ c = [name characterAtIndex: 4];
+ if (c >= '0' && c <= '9')
+ {
+ i = c - '0';
+ c = [name characterAtIndex: 5];
+ if (c >= '0' && c <= '9')
+ {
+ i = i * 10 + (c - '0');
+ c = [name characterAtIndex: 6];
+ if (c >= '0' && c <= '9')
+ {
+ i = i * 6 + (c - '0');
+ c = [name characterAtIndex: 7];
+ if (c >= '0' && c <= '9')
+ {
+ i = i * 10 + (c - '0');
+ zone = [[GSAbsTimeZone alloc] initWithOffset: i*60];
+ }
+ }
+ }
+ }
+ }
if (zone == nil && length > 19
- && [name hasPrefix: @"NSAbsoluteTimeZone:"] == YES)
- {
- i = [[name substringFromIndex: 19] intValue];
+ && [name hasPrefix: @"NSAbsoluteTimeZone:"] == YES)
+ {
+ i = [[name substringFromIndex: 19] intValue];
- zone = [[GSAbsTimeZone alloc] initWithOffset: i];
- }
+ zone = [[GSAbsTimeZone alloc] initWithOffset: i];
+ }
if (zone == nil)
- {
- if (data == nil)
- {
- NSString *fileName;
- const char *str = [name UTF8String];
-
- /* 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 `%@'.", name);
- return nil;
- }
-
- fileName = [NSTimeZoneClass getTimeZoneFile: name];
- if (fileName == nil)
- {
- NSLog(@"Unknown time zone name `%@'.", name);
- return nil;
- }
- data = [NSData dataWithContentsOfFile: fileName];
- }
- zone = [[GSTimeZone alloc] initWithName: name data: data];
- }
+ {
+ if (data == nil)
+ {
+ NSString *fileName;
+ const char *str = [name UTF8String];
+
+ /* 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 `%@'.", name);
+ return nil;
+ }
+
+ fileName = [NSTimeZoneClass getTimeZoneFile: name];
+ if (fileName == nil)
+ {
+ NSLog(@"Unknown time zone name `%@'.", name);
+ return nil;
+ }
+ data = [NSData dataWithContentsOfFile: fileName];
+ }
+ zone = [[GSTimeZone alloc] initWithName: name data: data];
+ }
}
RELEASE(self);
return zone;
@@ -455,18 +488,18 @@
- (void) release
{
- return; // placeholders never get released.
+ return; // placeholders never get released.
}
- (id) retain
{
- return self; // placeholders never get retained.
+ return self; // placeholders never get retained.
}
@end
[EMAIL PROTECTED] NSLocalTimeZone
[EMAIL PROTECTED] NSLocalTimeZone
- (NSString*) abbreviation
{
@@ -551,15 +584,15 @@
@implementation GSAbsTimeZone
-static int uninitialisedOffset = 100000;
-static NSMapTable *absolutes = 0;
+static int uninitialisedOffset = 100000;
+static NSMapTable *absolutes = 0;
+ (void) initialize
{
if (self == [GSAbsTimeZone class])
{
absolutes = NSCreateMapTable(NSIntMapKeyCallBacks,
- NSNonOwnedPointerMapValueCallBacks, 0);
+ NSNonOwnedPointerMapValueCallBacks, 0);
}
}
@@ -573,10 +606,10 @@
if (offset != uninitialisedOffset)
{
if (zone_mutex != nil)
- [zone_mutex lock];
+ [zone_mutex lock];
NSMapRemove(absolutes, (void*)(gsaddr)offset);
if (zone_mutex != nil)
- [zone_mutex unlock];
+ [zone_mutex unlock];
}
RELEASE(name);
RELEASE(detail);
@@ -590,9 +623,9 @@
- (id) initWithOffset: (int)anOffset
{
- GSAbsTimeZone *z;
- int extra;
- int sign = anOffset >= 0 ? 1 : -1;
+ GSAbsTimeZone *z;
+ int extra;
+ int sign = anOffset >= 0 ? 1 : -1;
/*
* Set the uninitialised offset so that dealloc before full
@@ -634,25 +667,25 @@
else
{
if (anOffset % 60 == 0)
- {
- char s = (anOffset >= 0) ? '+' : '-';
- int i = (anOffset >= 0) ? anOffset / 60 : -anOffset / 60;
- int h = i / 60;
- int m = i % 60;
- char buf[9];
-
- sprintf(buf, "GMT%c%02d%02d", s, h, m);
- name = [[NSString alloc] initWithCString: buf];
- }
+ {
+ char s = (anOffset >= 0) ? '+' : '-';
+ int i = (anOffset >= 0) ? anOffset / 60 : -anOffset / 60;
+ int h = i / 60;
+ int m = i % 60;
+ char buf[9];
+
+ sprintf(buf, "GMT%c%02d%02d", s, h, m);
+ name = [[NSString alloc] initWithCString: buf];
+ }
else
- {
- /*
- * Should never happen now we round to the minute
- * for MacOS-X compatibnility.
- */
- name = [[NSString alloc] initWithFormat: @"NSAbsoluteTimeZone:%d",
- anOffset];
- }
+ {
+ /*
+ * Should never happen now we round to the minute
+ * for MacOS-X compatibnility.
+ */
+ name = [[NSString alloc] initWithFormat: @"NSAbsoluteTimeZone:%d",
+ anOffset];
+ }
detail = [[GSAbsTimeZoneDetail alloc] initWithTimeZone: self];
offset = anOffset;
z = self;
@@ -715,12 +748,12 @@
}
- (id) initWithTimeZone: (NSTimeZone*)aZone
- withAbbrev: (NSString*)anAbbrev
- withOffset: (int)anOffset
- withDST: (BOOL)isDST
+ withAbbrev: (NSString*)anAbbrev
+ withOffset: (int)anOffset
+ withDST: (BOOL)isDST
{
timeZone = RETAIN(aZone);
- abbrev = anAbbrev; // NB. Depend on this being retained in aZone
+ abbrev = anAbbrev; // NB. Depend on this being retained in aZone
offset = anOffset;
is_dst = isDST;
return self;
@@ -856,14 +889,23 @@
* wildly between OSes (this could be a big problem when
* archiving is used between different systems).
* </p>
+ * On platforms where the zone info files are already installed
+ * elsewhere it is sufficient to use a symlink provided the GMT+/-
+ * zones are added.
*/
@implementation NSTimeZone
+/*
+ * DEPRICATED.
+ */
+ (NSDictionary*) abbreviationDictionary
{
return fake_abbrev_dict;
}
+/*
+ * Returns an abbreviation to time zone map which is quite large.
+ */
+ (NSDictionary*) abbreviationMap
{
/* Instead of creating the abbreviation dictionary when the class is
@@ -882,7 +924,7 @@
/* Read dictionary from file. */
abbreviationDictionary = [[NSMutableDictionary alloc] init];
fileName = [NSTimeZone getAbbreviationFile];
-#if defined(__WIN32__)
+#if defined(__WIN32__)
file = fopen([fileName fileSystemRepresentation], "rb");
#else
file = fopen([fileName fileSystemRepresentation], "r");
@@ -899,10 +941,10 @@
the_abbrev = [NSString stringWithCString: abbrev];
a = [abbreviationDictionary objectForKey: the_abbrev];
if (a == nil)
- {
- a = [[NSMutableArray alloc] init];
- [abbreviationDictionary setObject: a forKey: the_abbrev];
- }
+ {
+ a = [[NSMutableArray alloc] init];
+ [abbreviationDictionary setObject: a forKey: the_abbrev];
+ }
[a addObject: the_name];
}
fclose(file);
@@ -920,42 +962,42 @@
* is called.
*/
if (z == NSDefaultMallocZone() || z == 0)
- {
- /*
- * As a special case, we can return a placeholder for a time zone
- * in the default malloc zone extremely efficiently.
- */
- return defaultPlaceholderTimeZone;
- }
+ {
+ /*
+ * As a special case, we can return a placeholder for a time zone
+ * in the default malloc zone extremely efficiently.
+ */
+ return defaultPlaceholderTimeZone;
+ }
else
- {
- id obj;
+ {
+ id obj;
- /*
- * For anything other than the default zone, we need to
- * locate the correct placeholder in the (lock protected)
- * table of placeholders.
- */
- if (zone_mutex != nil)
- {
- [zone_mutex lock];
- }
- obj = (id)NSMapGet(placeholderMap, (void*)z);
- if (obj == nil)
- {
- /*
- * There is no placeholder object for this zone, so we
- * create a new one and use that.
- */
- obj = (id)NSAllocateObject(GSPlaceholderTimeZoneClass, 0, z);
- NSMapInsert(placeholderMap, (void*)z, (void*)obj);
- }
- if (zone_mutex != nil)
- {
- [zone_mutex unlock];
- }
- return obj;
- }
+ /*
+ * For anything other than the default zone, we need to
+ * locate the correct placeholder in the (lock protected)
+ * table of placeholders.
+ */
+ if (zone_mutex != nil)
+ {
+ [zone_mutex lock];
+ }
+ obj = (id)NSMapGet(placeholderMap, (void*)z);
+ if (obj == nil)
+ {
+ /*
+ * There is no placeholder object for this zone, so we
+ * create a new one and use that.
+ */
+ obj = (id)NSAllocateObject(GSPlaceholderTimeZoneClass, 0, z);
+ NSMapInsert(placeholderMap, (void*)z, (void*)obj);
+ }
+ if (zone_mutex != nil)
+ {
+ [zone_mutex unlock];
+ }
+ return obj;
+ }
}
else
{
@@ -968,7 +1010,7 @@
*/
+ (NSTimeZone*) defaultTimeZone
{
- NSTimeZone *zone;
+ NSTimeZone *zone;
if (zone_mutex != nil)
{
@@ -981,13 +1023,13 @@
else
{
if (zone_mutex != nil)
- {
- zone = AUTORELEASE(RETAIN(defaultTimeZone));
- }
+ {
+ zone = AUTORELEASE(RETAIN(defaultTimeZone));
+ }
else
- {
- zone = defaultTimeZone;
- }
+ {
+ zone = defaultTimeZone;
+ }
}
if (zone_mutex != nil)
{
@@ -1008,25 +1050,25 @@
* Set up infrastructure for placeholder timezones.
*/
defaultPlaceholderTimeZone = (GSPlaceholderTimeZone*)
- NSAllocateObject(GSPlaceholderTimeZoneClass, 0, NSDefaultMallocZone());
- placeholderMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
- NSNonRetainedObjectMapValueCallBacks, 0);
+ NSAllocateObject(GSPlaceholderTimeZoneClass, 0, NSDefaultMallocZone());
+ placeholderMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
+ NSNonRetainedObjectMapValueCallBacks, 0);
localTimeZone = [[NSLocalTimeZone alloc] init];
fake_abbrev_dict = [[NSInternalAbbrevDict alloc] init];
if ([NSThread isMultiThreaded])
- {
- [self _becomeThreaded: nil];
- }
+ {
+ [self _becomeThreaded: nil];
+ }
else
- {
- [[NSNotificationCenter defaultCenter]
- addObserver: self
- selector: @selector(_becomeThreaded:)
- name: NSWillBecomeMultiThreadedNotification
- object: nil];
- }
+ {
+ [[NSNotificationCenter defaultCenter]
+ addObserver: self
+ selector: @selector(_becomeThreaded:)
+ name: NSWillBecomeMultiThreadedNotification
+ object: nil];
+ }
}
}
@@ -1067,18 +1109,18 @@
* cause recursion ...
*/
if (aTimeZone == localTimeZone)
- {
- aTimeZone = [self systemTimeZone];
- }
+ {
+ aTimeZone = [self systemTimeZone];
+ }
if (zone_mutex != nil)
- {
- [zone_mutex lock];
- }
+ {
+ [zone_mutex lock];
+ }
ASSIGN(defaultTimeZone, aTimeZone);
if (zone_mutex != nil)
- {
- [zone_mutex unlock];
- }
+ {
+ [zone_mutex unlock];
+ }
}
}
@@ -1087,7 +1129,7 @@
*/
+ (NSTimeZone*) systemTimeZone
{
- NSTimeZone *zone = nil;
+ NSTimeZone *zone = nil;
if (zone_mutex != nil)
{
@@ -1095,63 +1137,66 @@
}
if (systemTimeZone == nil)
{
- NSString *localZoneString = nil;
+ NSString *localZoneString = nil;
/*
* setup default value in case something goes wrong.
*/
systemTimeZone = RETAIN([NSTimeZoneClass timeZoneForSecondsFromGMT: 0]);
+ /*
+ * Try to get timezone from user defaults database
+ */
localZoneString = [[NSUserDefaults standardUserDefaults]
- stringForKey: LOCALDBKEY];
+ stringForKey: LOCALDBKEY];
+ /*
+ * Try to get timezone from GNUSTEP_TZ environment variable.
+ */
if (localZoneString == nil)
- {
- /*
- * Try to get timezone from GNUSTEP_TZ environment variable.
- */
- localZoneString = [[[NSProcessInfo processInfo]
- environment] objectForKey: @"GNUSTEP_TZ"];
- }
+ {
+ localZoneString = [[[NSProcessInfo processInfo]
+ environment] objectForKey: @"GNUSTEP_TZ"];
+ }
+ /*
+ * Try to get timezone from LOCAL_TIME_FILE
+ */
if (localZoneString == nil)
- {
- /*
- * Try to get timezone from LOCAL_TIME_FILE.
- */
- NSString *f = _time_zone_path(LOCAL_TIME_FILE);
- if (f != nil)
- {
- localZoneString = [NSString stringWithContentsOfFile: f];
- localZoneString = [localZoneString stringByTrimmingSpaces];
- }
- }
+ {
+ NSString *f = _time_zone_path(LOCAL_TIME_FILE);
+ if (f != nil)
+ {
+ localZoneString = [NSString stringWithContentsOfFile: f];
+ localZoneString = [localZoneString stringByTrimmingSpaces];
+ }
+ }
#if HAVE_TZSET
+ /*
+ * Try to get timezone from tzset and tzname
+ */
if (localZoneString == nil)
- {
- /*
- * Try to get timezone from tzset and tzname
- */
- tzset();
- if (tzname[0] != NULL && *tzname[0] != '\0')
- localZoneString = [NSString stringWithCString: tzname[0]];
- }
+ {
+ tzset();
+ if (tzname[0] != NULL && *tzname[0] != '\0')
+ localZoneString = [NSString stringWithCString: tzname[0]];
+ }
#else
+ /*
+ * Try to get timezone from standard unix environment variable.
+ */
if (localZoneString == nil)
- {
- /*
- * Try to get timezone from standard unix environment variable.
- */
- localZoneString = [[[NSProcessInfo processInfo]
- environment] objectForKey: @"TZ"];
- }
+ {
+ localZoneString = [[[NSProcessInfo processInfo]
+ environment] objectForKey: @"TZ"];
+ }
#endif
if (localZoneString != nil)
- {
- zone = [defaultPlaceholderTimeZone initWithName: localZoneString];
- }
+ {
+ zone = [defaultPlaceholderTimeZone initWithName: localZoneString];
+ }
else
- {
- NSLog(@"No local time zone specified.");
- }
+ {
+ NSLog(@"No local time zone specified.");
+ }
/*
* If local time zone fails to allocate, then allocate something
@@ -1177,10 +1222,14 @@
return zone;
}
+/**
+ * Returns an array of all the known regions.<br />
+ * There are 24 elements, of course, one for each time zone.
+ * Each element contains an array of NSStrings which are
+ * the region names.
+ */
+ (NSArray*) timeZoneArray
{
- /* We create the array only when we need it to reduce overhead. */
-
static NSArray *regionsArray = nil;
int index, i;
char name[80];
@@ -1188,6 +1237,7 @@
id temp_array[24];
NSString *fileName;
+ /* We create the array only when we need it to reduce overhead. */
if (regionsArray != nil)
return regionsArray;
@@ -1195,7 +1245,7 @@
temp_array[i] = [NSMutableArray array];
fileName = [NSTimeZoneClass getRegionsFile];
-#if defined(__WIN32__)
+#if defined(__WIN32__)
file = fopen([fileName fileSystemRepresentation], "rb");
#else
file = fopen([fileName fileSystemRepresentation], "r");
@@ -1221,21 +1271,23 @@
*/
+ (NSTimeZone*) timeZoneForSecondsFromGMT: (int)seconds
{
- NSTimeZone *zone;
+ NSTimeZone *zone;
zone = [[GSAbsTimeZone alloc] initWithOffset: seconds];
return AUTORELEASE(zone);
}
/**
- * Returns a timezone for the specified abbrevition,
+ * Returns a timezone for the specified abbrevition. The same abbreviations
+ * are used in different regions so this isn't particularly useful.<br />
+ * Calls NSTimeZone-abbreviation dictionary an so uses a lot of memory.
*/
+ (NSTimeZone*) timeZoneWithAbbreviation: (NSString*)abbreviation
{
- NSTimeZone *zone;
+ NSTimeZone *zone;
zone = [self timeZoneWithName: [[self abbreviationDictionary]
- objectForKey: abbreviation] data: nil];
+ objectForKey: abbreviation] data: nil];
return zone;
}
@@ -1244,20 +1296,21 @@
*/
+ (NSTimeZone*) timeZoneWithName: (NSString*)aTimeZoneName
{
- NSTimeZone *zone;
+ NSTimeZone *zone;
zone = [defaultPlaceholderTimeZone initWithName: aTimeZoneName data: nil];
return AUTORELEASE(zone);
}
/**
- * Returns a timezone for the specified name, created from the supplied data.
+ * Returns a timezone for aTimeZoneName, created from the supplied
+ * time zone data. Data must be in TZ format as per the Olson database.
*/
-+ (NSTimeZone*) timeZoneWithName: (NSString*)name data: (NSData*)data
++ (NSTimeZone*) timeZoneWithName: (NSString*)aTimeZoneName data: (NSData*)data
{
- NSTimeZone *zone;
+ NSTimeZone *zone;
- zone = [defaultPlaceholderTimeZone initWithName: name data: nil];
+ zone = [defaultPlaceholderTimeZone initWithName: aTimeZoneName data: data];
return AUTORELEASE(zone);
}
@@ -1276,8 +1329,8 @@
*/
- (NSString*) abbreviationForDate: (NSDate*)aDate
{
- NSTimeZoneDetail *detail;
- NSString *abbr;
+ NSTimeZoneDetail *detail;
+ NSString *abbr;
detail = [self timeZoneDetailForDate: aDate];
abbr = [detail timeZoneAbbreviation];
@@ -1285,6 +1338,9 @@
return abbr;
}
+/**
+ * Returns the Class for this object
+ */
- (Class) classForCoder
{
return NSTimeZoneClass;
@@ -1303,6 +1359,9 @@
return nil;
}
+/**
+ * Returns the name of this object.
+ */
- (NSString*) description
{
return [self name];
@@ -1320,7 +1379,7 @@
- (id) initWithCoder: (NSCoder*)aDecoder
{
- NSString *name;
+ NSString *name;
name = [aDecoder decodeObject];
self = [self initWithName: name data: nil];
@@ -1363,8 +1422,8 @@
*/
- (BOOL) isDaylightSavingTimeForDate: (NSDate*)aDate
{
- NSTimeZoneDetail *detail;
- BOOL isDST;
+ NSTimeZoneDetail *detail;
+ BOOL isDST;
detail = [self timeZoneDetailForDate: aDate];
isDST = [detail isDaylightSavingTimeZone];
@@ -1381,6 +1440,9 @@
return [self isEqualToTimeZone: other];
}
+/*
+ * Returns TRUE if the time zones are equal.
+ */
- (BOOL) isEqualToTimeZone: (NSTimeZone*)aTimeZone
{
if (aTimeZone == self)
@@ -1425,8 +1487,8 @@
*/
- (int) secondsFromGMTForDate: (NSDate*)aDate
{
- NSTimeZoneDetail *detail;
- int offset;
+ NSTimeZoneDetail *detail;
+ int offset;
detail = [self timeZoneDetailForDate: aDate];
offset = [detail timeZoneSecondsFromGMT];
@@ -1434,16 +1496,25 @@
return offset;
}
+/*
+ * DEPRICATED: see NSTimeZoneDetail
+ */
- (NSArray*) timeZoneDetailArray
{
return [self subclassResponsibility: _cmd];
}
+/*
+ * DEPRICATED: see NSTimeZoneDetail
+ */
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
{
return [self subclassResponsibility: _cmd];
}
+/*
+ * Returns the name of this timezone.
+ */
- (NSString*) timeZoneName
{
return [self name];
@@ -1461,9 +1532,9 @@
- (NSString*) description
{
return [NSString stringWithFormat: @"%@(%@, %s%d)", [self name],
- [self timeZoneAbbreviation],
- ([self isDaylightSavingTimeZone]? "IS_DST, ": ""),
- [self timeZoneSecondsFromGMT]];
+ [self timeZoneAbbreviation],
+ ([self isDaylightSavingTimeZone]? "IS_DST, ": ""),
+ [self timeZoneSecondsFromGMT]];
}
- (BOOL) isDaylightSavingTimeZone
@@ -1489,7 +1560,7 @@
@implementation NSTimeZone (Private)
/*
- * When the system becomes multithreaded, we set a flag to say so
+ * When the system becomes multithreaded, we set a flag to say so
*/
+ (void) _becomeThreaded: (NSNotification*)notification
{
@@ -1499,8 +1570,8 @@
}
[[NSNotificationCenter defaultCenter]
removeObserver: self
- name: NSWillBecomeMultiThreadedNotification
- object: nil];
+ name: NSWillBecomeMultiThreadedNotification
+ object: nil];
}
+ (NSString*) getAbbreviationFile
@@ -1515,7 +1586,7 @@
+ (NSString*) getTimeZoneFile: (NSString *)name
{
- NSString *dir;
+ NSString *dir;
dir= _time_zone_path (ZONES_DIR);
return [dir stringByAppendingPathComponent: name];
@@ -1525,7 +1596,7 @@
[EMAIL PROTECTED] GSTimeZone
[EMAIL PROTECTED] GSTimeZone
/**
* Perform a binary search of a transitions table to locate the index
@@ -1536,15 +1607,15 @@
static TypeInfo*
chop(NSTimeInterval since, GSTimeZone *zone)
{
- gss32 when = (gss32)since;
- gss32 *trans = zone->trans;
- unsigned hi = zone->n_trans;
- unsigned lo = 0;
- unsigned int i;
+ gss32 when = (gss32)since;
+ gss32 *trans = zone->trans;
+ unsigned hi = zone->n_trans;
+ unsigned lo = 0;
+ unsigned int i;
if (hi == 0 || trans[0] > when)
{
- unsigned n_types = zone->n_types;
+ unsigned n_types = zone->n_types;
/*
* If the first transition is greater than our date,
@@ -1552,40 +1623,40 @@
* or just use the first transition.
*/
for (i = 0; i < n_types; i++)
- {
- if (zone->types[i].isdst == 0)
- {
- return &zone->types[i];
- }
- }
+ {
+ if (zone->types[i].isdst == 0)
+ {
+ return &zone->types[i];
+ }
+ }
return &zone->types[0];
}
else
{
for (i = hi/2; hi != lo; i = (hi + lo)/2)
- {
- if (when < trans[i])
- {
- hi = i;
- }
- else if (when > trans[i])
- {
- lo = ++i;
- }
- else
- {
- break;
- }
- }
+ {
+ if (when < trans[i])
+ {
+ hi = i;
+ }
+ else if (when > trans[i])
+ {
+ lo = ++i;
+ }
+ else
+ {
+ break;
+ }
+ }
/*
* If we went off the top of the table or the closest transition
* was later than our date, we step back to find the last
* transition before our date.
*/
if (i > 0 && (i == zone->n_trans || trans[i] > when))
- {
- i--;
- }
+ {
+ i--;
+ }
return &zone->types[zone->idxs[i]];
}
}
@@ -1593,19 +1664,19 @@
static NSTimeZoneDetail*
newDetailInZoneForType(GSTimeZone *zone, TypeInfo *type)
{
- GSTimeZoneDetail *detail;
+ GSTimeZoneDetail *detail;
detail = [GSTimeZoneDetail alloc];
detail = [detail initWithTimeZone: zone
- withAbbrev: type->abbreviation
- withOffset: type->offset
- withDST: type->isdst];
+ withAbbrev: type->abbreviation
+ withOffset: type->offset
+ withDST: type->isdst];
return detail;
}
- (NSString*) abbreviationForDate: (NSDate*)aDate
{
- TypeInfo *type = chop([aDate timeIntervalSince1970], self);
+ TypeInfo *type = chop([aDate timeIntervalSince1970], self);
return type->abbreviation;
}
@@ -1621,12 +1692,12 @@
RELEASE(timeZoneData);
if (types != 0)
{
- unsigned i;
+ unsigned i;
for (i = 0; i < n_types; i++)
- {
- RELEASE(types[i].abbreviation);
- }
+ {
+ RELEASE(types[i].abbreviation);
+ }
NSZoneFree(NSDefaultMallocZone(), types);
}
[super dealloc];
@@ -1634,32 +1705,32 @@
- (id) initWithName: (NSString*)name data: (NSData*)data
{
- static NSString *fileException = @"GSTimeZoneFileException";
+ static NSString *fileException = @"GSTimeZoneFileException";
timeZoneName = [name copy];
timeZoneData = [data copy];
NS_DURING
{
- const void *bytes = [timeZoneData bytes];
- unsigned length = [timeZoneData length];
- void *buf;
- unsigned pos = 0;
- unsigned i, charcnt;
- unsigned char *abbr;
- struct tzhead *header;
+ const void *bytes = [timeZoneData bytes];
+ unsigned length = [timeZoneData length];
+ void *buf;
+ unsigned pos = 0;
+ unsigned i, charcnt;
+ unsigned char *abbr;
+ struct tzhead *header;
if (length < sizeof(struct tzhead))
- {
- [NSException raise: fileException
- format: @"File is too small"];
- }
+ {
+ [NSException raise: fileException
+ format: @"File is too small"];
+ }
header = (struct tzhead *)(bytes + pos);
pos += sizeof(struct tzhead);
if (memcmp(header->tzh_magic, TZ_MAGIC, strlen(TZ_MAGIC)) != 0)
- {
- [NSException raise: fileException
- format: @"TZ_MAGIC is incorrect"];
- }
+ {
+ [NSException raise: fileException
+ format: @"TZ_MAGIC is incorrect"];
+ }
n_trans = GSSwapBigI32ToHost(*(gss32*)header->tzh_timecnt);
n_types = GSSwapBigI32ToHost(*(gss32*)header->tzh_typecnt);
charcnt = GSSwapBigI32ToHost(*(gss32*)header->tzh_charcnt);
@@ -1667,27 +1738,27 @@
i = pos;
i += sizeof(gss32)*n_trans;
if (i > length)
- {
- [NSException raise: fileException
- format: @"Transitions list is truncated"];
- }
+ {
+ [NSException raise: fileException
+ format: @"Transitions list is truncated"];
+ }
i += n_trans;
if (i > length)
- {
- [NSException raise: fileException
- format: @"Transition indexes are truncated"];
- }
+ {
+ [NSException raise: fileException
+ format: @"Transition indexes are truncated"];
+ }
i += sizeof(struct ttinfo)*n_types;
if (i > length)
- {
- [NSException raise: fileException
- format: @"Types list is truncated"];
- }
+ {
+ [NSException raise: fileException
+ format: @"Types list is truncated"];
+ }
if (i + charcnt > length)
- {
- [NSException raise: fileException
- format: @"Abbreviations list is truncated"];
- }
+ {
+ [NSException raise: fileException
+ format: @"Abbreviations list is truncated"];
+ }
/*
* Now calculate size we need to store the information
@@ -1704,63 +1775,63 @@
/* Read in transitions. */
for (i = 0; i < n_trans; i++)
- {
- trans[i] = GSSwapBigI32ToHost(*(gss32*)(bytes + pos));
- pos += sizeof(gss32);
- }
+ {
+ trans[i] = GSSwapBigI32ToHost(*(gss32*)(bytes + pos));
+ pos += sizeof(gss32);
+ }
for (i = 0; i < n_trans; i++)
- {
- idxs[i] = *(unsigned char*)(bytes + pos);
- pos++;
- }
+ {
+ idxs[i] = *(unsigned char*)(bytes + pos);
+ pos++;
+ }
for (i = 0; i < n_types; i++)
- {
- struct ttinfo *ptr = (struct ttinfo*)(bytes + pos);
+ {
+ struct ttinfo *ptr = (struct ttinfo*)(bytes + pos);
- types[i].isdst = (ptr->isdst != 0 ? YES : NO);
- types[i].abbr_idx = ptr->abbr_idx;
- types[i].offset = decode(ptr->offset);
- pos += sizeof(struct ttinfo);
- }
+ types[i].isdst = (ptr->isdst != 0 ? YES : NO);
+ types[i].abbr_idx = ptr->abbr_idx;
+ types[i].offset = decode(ptr->offset);
+ pos += sizeof(struct ttinfo);
+ }
abbr = (char*)(bytes + pos);
{
- id abbrevs[charcnt];
+ id abbrevs[charcnt];
- memset(abbrevs, '\0', sizeof(id)*charcnt);
- for (i = 0; i < n_types; i++)
- {
- int loc = types[i].abbr_idx;
-
- if (abbrevs[loc] == nil)
- {
- abbrevs[loc] = [[NSString alloc] initWithCString: abbr + loc];
- }
- else
- {
- RETAIN(abbrevs[loc]);
- }
- types[i].abbreviation = abbrevs[loc];
- }
+ memset(abbrevs, '\0', sizeof(id)*charcnt);
+ for (i = 0; i < n_types; i++)
+ {
+ int loc = types[i].abbr_idx;
+
+ if (abbrevs[loc] == nil)
+ {
+ abbrevs[loc] = [[NSString alloc] initWithCString: abbr + loc];
+ }
+ else
+ {
+ RETAIN(abbrevs[loc]);
+ }
+ types[i].abbreviation = abbrevs[loc];
+ }
}
if (zone_mutex != nil)
- {
- [zone_mutex lock];
- }
+ {
+ [zone_mutex lock];
+ }
[zoneDictionary setObject: self forKey: timeZoneName];
if (zone_mutex != nil)
- {
- [zone_mutex unlock];
- }
+ {
+ [zone_mutex unlock];
+ }
}
NS_HANDLER
{
DESTROY(self);
NSLog(@"Unable to obtain time zone `%@'... %@", name, localException);
if ([localException name] != fileException)
- {
- [localException raise];
- }
+ {
+ [localException raise];
+ }
}
NS_ENDHANDLER
return self;
@@ -1768,7 +1839,7 @@
- (BOOL) isDaylightSavingTimeForDate: (NSDate*)aDate
{
- TypeInfo *type = chop([aDate timeIntervalSince1970], self);
+ TypeInfo *type = chop([aDate timeIntervalSince1970], self);
return type->isdst;
}
@@ -1780,16 +1851,16 @@
- (int) secondsFromGMTForDate: (NSDate*)aDate
{
- TypeInfo *type = chop([aDate timeIntervalSince1970], self);
+ TypeInfo *type = chop([aDate timeIntervalSince1970], self);
return type->offset;
}
- (NSArray*) timeZoneDetailArray
{
- NSTimeZoneDetail *details[n_types];
- unsigned i;
- NSArray *array;
+ NSTimeZoneDetail *details[n_types];
+ unsigned i;
+ NSArray *array;
for (i = 0; i < n_types; i++)
{
@@ -1805,8 +1876,8 @@
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)aDate
{
- TypeInfo *type;
- NSTimeZoneDetail *detail;
+ TypeInfo *type;
+ NSTimeZoneDetail *detail;
type = chop([aDate timeIntervalSince1970], self);
detail = newDetailInZoneForType(self, type);
2003-12-13 Sheldon Gill <[EMAIL PROTECTED]>
* Source/NSTimeZone.m: Added documentation and clean up.
[NSTimeZone initTimeZoneWithName:data:] now uses data.
_______________________________________________
Bug-gnustep mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-gnustep