[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSTimeZone timeZoneWithName: unit test fails unnecessarily
From: |
Robert Slover |
Subject: |
Re: NSTimeZone timeZoneWithName: unit test fails unnecessarily |
Date: |
Fri, 14 Jun 2013 14:10:38 -0400 |
I've been through this with Java applications - had a customer setting time
zone to 'GB' and all sorts of things were breaking with third-party Java
components distributed with our app. Turns out it isn't an official Olsen time
zone abbreviation nor is it a POSIX one - just a locally traditional one. Some
OSs do have it in their zones database (on Solaris, it is a hard link to
Europe/London and a few others). Others do not. Java, like GNUStep, ships its
own zones database - but the Java one does not contain GB. Switching to
Europe/London worked.
Some timezone-related arcanum you might be interested in: make sure your
default system time zone info file is copied into the corresponding location
inside any jail. At least on Linux, there are weird date/time shifts
encountered if you don't do this - SFTP running inside the jail is one instance
in which this shows up.
Another frustrating thing about time zones, at least on Linux, is determining
what the system time zone actually is if you need to display it to a user (TZ
isn't set on most systems). A formatted time only includes the appropriate
abbreviation (so for example America/New_York and US/East-Indiana currently
format the time zone as EDT), which is non-unique. On RHEL, the /etc/localtime
file is a copy (for good reasons) of whatever the sysadmin originally picked
when setting the system up, but it has lost its name, and the file itself is
non-unique. One can munge through /usr/share/zoneinfo looking for equivalents,
but there are often more than one. Since the names usually follow political
boundaries, a heuristic like picking the first match is hazardous - not so much
inside the US, but even here, it might make a difference to someone if
"US/Mountain" is displayed when they chose "Navajo". I have yet to find a good
solution - I use a more complex heuristic but first look for a match out of the
possibilities against the ZONE assignment in /etc/sysconfig/clock. I hate this
though - it is so system-specific.
--Robert
On Jun 14, 2013, at 11:40, Frank Rehwinkel <address@hidden> wrote:
> The GNUstep-base make check for NSTimeZone's +timeZoneWithName: is based on
> an invalid assumption.
> As a result, it fails on my FreeBSD 9.1 system (and could give the impression
> that the class has a bug in it).
>
> The test is meant to check whether an NSTimeZone can be built from a timezone
> name. Turns out when
> it is given a timezone name that matches its platform's zones directory, it
> works. The invalid assumption
> is that the sample name picked is going to be found in each platform's zones
> directory.
>
> The test that is bundled with GNUstep's core/base uses the @"GB" name. But
> on my FreeBSD 9.1 system,
> the /usr/share/zoneinfo directory doesn't have a file with that name. So the
> class returns nil and the
> test reports a failure.
>
> Ironically, or perhaps not, there is a GB timezone file provided by the
> GNUstep installation. But it is not
> left in a directory that the NSTimeZone class looks in first. The class
> lookup seems a bit odd. It uses
> a hardcoded list of possible directories, and just uses the first one that is
> actually a directory. If the file
> doesn't exist in that directory, it doesn't bother to check other directories.
>
> There is the option of building the code with a TZDIR define, but I didn't
> find an install script or instructions
> for setting it as part of the configuration step.
>
> NSTimeZone does use the GNUstep supplied directory, for matching my defaults
> setup of
> 'defaults write NSGlobalDomain "Local Time Zone" America/New_York'. I
> noticed that before I had the defaults
> setup, NSLog would cause NSTimeZone to printout a warning that the local
> timezone wasn't set.
>
> /usr/GNUstep/Local/Library/Libraries/gnustep-base/Versions/1.24/Resources/NSTimeZones/zones/America/New_York
>
> Odd that the timeZoneWithName: doesn't use the same lookup mechanism.
>
>
> Here's some test code to show that the lookup works when passed a name that
> can be found.
>
> $ cat test00.m
> #import <Foundation/Foundation.h>
>
> int main(int argc, char * argv[]){
> id current;
> for (NSString *name in
> [NSArray arrayWithObjects:
> @"GB", // This one won't be found.
> @"EST", // This one will be found.
> nil]
> ) {
> current = [NSTimeZone timeZoneWithName: name];
> NSLog(@"For name:'%@' timezone: address@hidden", name, current);
> }
> return 0;
> }
> $ ./test00
> 2013-06-14 09:50:45.738 test00[11019] For name:'GB' timezone: (null)
> 2013-06-14 09:50:45.740 test00[11019] For name:'EST' timezone: EST
>
> And GB is not found because it is not in this FreeBSD directory.
>
> $ ls /usr/share/zoneinfo
> Africa Australia Etc MST WET
> America CET Europe MST7MDT posixrules
> Antarctica CST6CDT Factory PST8PDT zone.tab
> Arctic EET HST Pacific
> Asia EST Indian SystemV
> Atlantic EST5EDT MET UTC
>
> GB would have been found if this directory had been searched.
>
> $ ls
> /usr/GNUstep/Local/Library/Libraries/gnustep-base/Versions/1.24/Resources/NSTimeZones/zones/
> Africa Etc GMT+8 Greenwich Navajo
> America Europe GMT+9 HST PRC
> Antarctica GB GMT-0 Hongkong PST8PDT
> Arctic GB-Eire GMT-1 Iceland Pacific
> Asia GMT GMT-10 Indian Poland
> Atlantic GMT+0 GMT-11 Iran Portugal
> Australia GMT+1 GMT-12 Israel ROC
> Brazil GMT+10 GMT-13 Jamaica ROK
> CET GMT+11 GMT-14 Japan Singapore
> CST6CDT GMT+12 GMT-2 Kwajalein Turkey
> Canada GMT+13 GMT-3 Libya UCT
> Chile GMT+14 GMT-4 MET US
> Cuba GMT+2 GMT-5 MST UTC
> EET GMT+3 GMT-6 MST7MDT Universal
> EST GMT+4 GMT-7 Mexico W-SU
> EST5EDT GMT+5 GMT-8 Mideast WET
> Egypt GMT+6 GMT-9 NZ Zulu
> Eire GMT+7 GMT0 NZ-CHAT
>
> _______________________________________________
> Gnustep-dev mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/gnustep-dev