Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DateTime-TimeZone CPAN distribution.

Report information
The Basics
Id: 55029
Status: resolved
Priority: 0/
Queue: DateTime-TimeZone

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.10
Fixed in: (no value)

Attachments


Subject: "Cannot determine time zone" on FreeBSD
$ perl -wle 'use DateTime; DateTime->now( time_zone => "local" )' Cannot determine local time zone $ uname -a FreeBSD eschaton.local 7.2-STABLE FreeBSD 7.2-STABLE #0: Sat Nov 14 22:23:32 EST 2009 root@eschaton.local:/usr/obj/usr/src/sys/ESCHATON amd64 I'm also seeing it on FreeBSD 8. http://www.cpantesters.org/cpan/report/6868995 Digging into the problem, the only DateTime::TimeZone::Local::Unix method which is having any luck is /etc/localtime, the rest of the files checked do not exist, but there are no files of the same size in /usr/share/zoneinfo. Attached is a copy of /etc/localtime from that system. This is with 5.10.1 and DateTime::TimeZone 1.10.
Subject: localtime
Download localtime
application/octet-stream 1.2k

Message body not shown because it is not plain text.

A further tidbit of information, /etc/localtime is not a symlink and it is a TZif file while all the applicable files in /usr/share/zoneinfo are TZif2. One possibility is that /etc/localtime was updated as part of an update for the 2007 DST changes and the zoneinfo files were changed under it. http://www.freebsd.org/releng/dst_info.html One possible work around is to use zdump and scrape the output. $ zdump /etc/localtime /etc/localtime Fri Feb 26 14:56:30 2010 EST
Subject: Re: [rt.cpan.org #55029] "Cannot determine time zone" on FreeBSD
Date: Sat, 27 Feb 2010 10:47:44 -0600 (CST)
To: Michael G Schwern via RT <bug-DateTime-TimeZone [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Fri, 26 Feb 2010, Michael G Schwern via RT wrote: Show quoted text
> Digging into the problem, the only DateTime::TimeZone::Local::Unix > method which is having any luck is /etc/localtime, the rest of the files > checked do not exist, but there are no files of the same size in > /usr/share/zoneinfo.
This could, in theory, be fixed by just using the binary Olson file directly, as we discussed on the list. But in this case, it seems like your system has a problem. If there's no match in /usr/share/zoneinfo, the most likely case is that the file copied to /etc/localtime is now out of date and wrong, so actually using it will just produce wrong answers, instead of dying. I'm not sure that's an improvement. You suggested using zdump, which I suppose could work, assuming that the combination of a zone's short name and gmt offset for a given date is unique. However, that'd require a whole bunch of new code to look this up given the list of all possible zones. This really doesn't seem worth it, when the simple fix is to symlink /etc/localtime instead of copying a file to it. -dave /*============================================================ http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) ============================================================*/
Subject: Re: [rt.cpan.org #55029] "Cannot determine time zone" on FreeBSD
Date: Sat, 27 Feb 2010 13:52:14 -0800
To: bug-DateTime-TimeZone [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
autarch@urth.org via RT wrote: Show quoted text
>> Digging into the problem, the only DateTime::TimeZone::Local::Unix >> method which is having any luck is /etc/localtime, the rest of the files >> checked do not exist, but there are no files of the same size in >> /usr/share/zoneinfo.
> > This could, in theory, be fixed by just using the binary Olson file > directly, as we discussed on the list. > > But in this case, it seems like your system has a problem. If there's no > match in /usr/share/zoneinfo, the most likely case is that the file copied > to /etc/localtime is now out of date and wrong, so actually using it will > just produce wrong answers, instead of dying. I'm not sure that's an > improvement. > > You suggested using zdump, which I suppose could work, assuming that the > combination of a zone's short name and gmt offset for a given date is > unique. However, that'd require a whole bunch of new code to look this up > given the list of all possible zones. This really doesn't seem worth it, > when the simple fix is to symlink /etc/localtime instead of copying a file > to it.
So far this has shown up on two independent machines, neither are mine. A FreeBSD 7.2 box provided to me by apeiron and szrezic's FreeBSD 8.0 smoke tests. If they've simply both misconfigured their machines then I'll get them to fix it. If its a systematic FreeBSD problem then as much as it sucks, working around it would be necessary. I've contacted szrezic and apeiron to see if they can shed any light. -- 87. If the thought of something makes me giggle for longer than 15 seconds, I am to assume that I am not allowed to do it. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Here's what I've figured out from talking with apeiron. Its likely policy for FreeBSD and other distributions to copy zone files rather than symlink. The logic appears to be that they want the time to be correct even if /usr isn't mounted. Here's Gentoo discussing it. http://bugs.gentoo.org/110038 That discussion also indicates this is a more widespread problem than just FreeBSD. The problem occurs like so: 1) tzsetup is run and a file from /usr/share/zoneinfo is copied to /etc/localtime. 2) The operating system is updated and new zoneinfo files are installed. 3) tzsetup is not as part of the update 4) /etc/localtime now represents no installed zoneinfo file. Failure to re-run tzsetup is the fault of the operating system distribution, not the sysadmin. It should be handled as part of the updated mechanism and it is not. Which is to say, a lot of systems will have this problem. Since its a problem endemic to an entire major distribution, it should be worked around. A simple fallback mechanism would be to use POSIX::strftime() to get the short form time zone name and GMT offset. $ perl -wle 'use POSIX; print strftime("%Z %z", localtime)' EST -0500 This is enough to identify the time zone. If there's a way to get all zones which match a given short form zone then DateTime can simply pick the first one that matches the gmtoff. For modern times it shouldn't matter if you're in America/Seattle or America/Los_Angeles. Or DT simply reads and trusts /etc/localtime which would seem to be the best long term fix.
On Sat Feb 27 17:47:03 2010, MSCHWERN wrote: Show quoted text
> Here's what I've figured out from talking with apeiron. Its likely > policy for FreeBSD and other distributions to copy zone files rather > than symlink. The logic appears to be that they want the time to be > correct even if /usr isn't mounted. Here's Gentoo discussing it. > http://bugs.gentoo.org/110038 That discussion also indicates this is a > more widespread problem than just FreeBSD. > > The problem occurs like so: > 1) tzsetup is run and a file from /usr/share/zoneinfo is copied to > /etc/localtime. > 2) The operating system is updated and new zoneinfo files are installed. > 3) tzsetup is not as part of the update > 4) /etc/localtime now represents no installed zoneinfo file. > > Failure to re-run tzsetup is the fault of the operating system > distribution, not the sysadmin. It should be handled as part of the > updated mechanism and it is not. Which is to say, a lot of systems will > have this problem. Since its a problem endemic to an entire major > distribution, it should be worked around. > > A simple fallback mechanism would be to use POSIX::strftime() to get the > short form time zone name and GMT offset. > > $ perl -wle 'use POSIX; print strftime("%Z %z", localtime)' > EST -0500 > > This is enough to identify the time zone. If there's a way to get all > zones which match a given short form zone then DateTime can simply pick > the first one that matches the gmtoff. For modern times it shouldn't > matter if you're in America/Seattle or America/Los_Angeles. > > Or DT simply reads and trusts /etc/localtime which would seem to be the > best long term fix.
Excellent analysis, and this is what happened on my system, too: I upgraded from FreeBSD 6.1 to FreeBSD 8.0, but /etc/localtime was not changed during this process. Though there's one problem in the proposed workaround with POSIX: depending on DST being active or not one will get different results: $ perl -wle 'use POSIX; print strftime("%Z %z", localtime)' CET +0100 $ perl -wle 'use POSIX; print strftime("%Z %z", localtime(time+86400*30))' CEST +0200 However, I think that the result of DateTime::TimeZone's heuristics was always something DST-agnostic like "Europe/Berlin". Regards, Slaven
On Sun Feb 28 05:11:09 2010, SREZIC wrote: Show quoted text
> Though there's one problem in the proposed workaround with POSIX: > depending on DST being active or not one will get different results: > > $ perl -wle 'use POSIX; print strftime("%Z %z", localtime)' > CET +0100 > $ perl -wle 'use POSIX; print strftime("%Z %z", localtime(time+86400*30))' > CEST +0200 > > However, I think that the result of DateTime::TimeZone's heuristics was > always something DST-agnostic like "Europe/Berlin".
Yes, and the result from the heuristic would not be "CET" but would be a European time zone. It could be Europe/Berlin or Europe/Paris or any other time zone which calls itself "CET". Its not 100% accurate, the rules for one city in a time zone may be slightly different from another, but it will account for daylight savings time. Personally I'd just trust /etc/localtime like everything else does. I've worked around it in perl5i by using DateTime::TimeZone::Tzfile to read /etc/localtime if present. Tzfile is so small the simplest solution may be to just include it in DT::TZ. Dave?
On Sun Feb 28 05:11:09 2010, SREZIC wrote: [...] Show quoted text
> $ perl -wle 'use POSIX; print strftime("%Z %z", localtime)' > CET +0100 > $ perl -wle 'use POSIX; print strftime("%Z %z", localtime(time+86400*30))' > CEST +0200 >
Another observation: a list of all possible timezone names as returned by POSIX.pm may be generated with the following oneliner: for tz in `perl -nale 'next if /^#/; print $F[2]' /usr/share/zoneinfo/zone.tab |sort -u`; do env TZ=$tz perl -MPOSIX -le 'print strftime("%Z", localtime)'; done|sort -u This results in 137 timezone names on a FreeBSD machine, and 138 on a Linux machine. However, DateTime::TimeZone::Catalog knows only a small fraction of these names. Regards, Slaven
Subject: Re: [rt.cpan.org #55029] "Cannot determine time zone" on FreeBSD
Date: Sun, 28 Feb 2010 14:50:54 -0600 (CST)
To: Slaven_Rezic via RT <bug-DateTime-TimeZone [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Sun, 28 Feb 2010, Slaven_Rezic via RT wrote: Show quoted text
> Another observation: a list of all possible timezone names as returned > by POSIX.pm may be generated with the following oneliner: > > for tz in `perl -nale 'next if /^#/; print $F[2]' > /usr/share/zoneinfo/zone.tab |sort -u`; do env TZ=$tz perl -MPOSIX -le > 'print strftime("%Z", localtime)'; done|sort -u > > This results in 137 timezone names on a FreeBSD machine, and 138 on a > Linux machine. However, DateTime::TimeZone::Catalog knows only a small > fraction of these names.
Those are _short_ names, which are generated based on a long name (like America/Chicago) and a specific date. For example, America/Chicago can be either CDT or CST, depending on whether daylight savings is currently in effect. The DT::TZ catalog is generated based on the Olson database source data. This data has, for historical reasons, some short names aliased to longer names, as well as some actual zones with short names like EST or EST5EDT. It's strongly recommended that you use the Continent/City names when _selecting_ a time zone, since these are the most likely to do what people expect. The short names are primarily useful for _output_ only. If you look in the datetime@perl.org list archives, you can probably find discussions about this. -dave /*============================================================ http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) ============================================================*/
Subject: Re: [rt.cpan.org #55029] "Cannot determine time zone" on FreeBSD
Date: Tue, 2 Mar 2010 12:49:14 -0600 (CST)
To: Michael G Schwern via RT <bug-DateTime-TimeZone [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Sun, 28 Feb 2010, Michael G Schwern via RT wrote: Show quoted text
> Yes, and the result from the heuristic would not be "CET" but would be a > European time zone. It could be Europe/Berlin or Europe/Paris or any > other time zone which calls itself "CET". Its not 100% accurate, the > rules for one city in a time zone may be slightly different from > another, but it will account for daylight savings time. > > Personally I'd just trust /etc/localtime like everything else does. > I've worked around it in perl5i by using DateTime::TimeZone::Tzfile to > read /etc/localtime if present. Tzfile is so small the simplest > solution may be to just include it in DT::TZ.
I'd rather not include Tzfile. That doesn't really fix the problem, since the _real_ problem is an out of date zone file in /etc/localtime. So including Tzfile just means we'd get wrong answers later in the process, rather than blowing up early on. If someone wants to implement a lookup based on POSIX output, I'd probably take a patch. -dave /*============================================================ http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) ============================================================*/
Subject: Re: [rt.cpan.org #55029] "Cannot determine time zone" on FreeBSD
Date: Tue, 02 Mar 2010 12:41:49 -0800
To: bug-DateTime-TimeZone [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
autarch@urth.org via RT wrote: Show quoted text
>> Yes, and the result from the heuristic would not be "CET" but would be a >> European time zone. It could be Europe/Berlin or Europe/Paris or any >> other time zone which calls itself "CET". Its not 100% accurate, the >> rules for one city in a time zone may be slightly different from >> another, but it will account for daylight savings time. >> >> Personally I'd just trust /etc/localtime like everything else does. >> I've worked around it in perl5i by using DateTime::TimeZone::Tzfile to >> read /etc/localtime if present. Tzfile is so small the simplest >> solution may be to just include it in DT::TZ.
> > I'd rather not include Tzfile. That doesn't really fix the problem, since > the _real_ problem is an out of date zone file in /etc/localtime. So > including Tzfile just means we'd get wrong answers later in the process, > rather than blowing up early on. > > If someone wants to implement a lookup based on POSIX output, I'd probably > take a patch.
We know using POSIX::strtime() is going to give us an ambiguous time zone because the short form can match many zones with the same current GMT offset but possibly different DST rules. For example, Arizona doesn't observe DST but it'll still match MST. Here's the list of fun DST exceptions in the US alone. https://secure.wikimedia.org/wikipedia/en/wiki/Daylight_saving_time_in_the_United_States#Local_observance_of_DST On the one hand, using POSIX::strftime output we know is never going to be quite right. We'll probably get lucky and probably the server is in a place that has normal DST rules. Probably. But "probably correct" is the same level of accuracy we have for /etc/localtime. I'm not sure how one would efficiently map the short form time zone to a long form. You can't make it static, because a given zone changes its short form over the course of a year. America/New York can be EDT or EST depending on the date and time. You'd have to ask every time zone what its current short form is until you got a hit. This can be reduced by storing a list of all possible zones for a given short form, possibly tweaking the order to prefer normal ones over odd ones. But this is still all a complicated guess. On the other hand, /etc/localtime might be out of date, but it might not be. A given time zone doesn't change often, and I'd gamble on /etc/localtime being correct. If its significantly out of touch the problem will show up across the whole system and the admin will fix it. One can reverse the whole argument. Because DateTime maintains its own zone files they can just as easily fall out of date as /etc/localtime can. Can you trust the currently installed DateTime to be up to date? DateTime getting it wrong isn't any better than /etc/localtime getting it wrong. It requires a lot more work for DateTime to get it wrong. It will be wrong in a way different from the rest of the system. I don't see this as a win. DateTime can't solve the real problem, it is out of its control and scope. The user asked for the local time the system is configured to and that's the best that DateTime can give it. -- 31. Not allowed to let sock puppets take responsibility for any of my actions. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
From: ppisar [...] redhat.com
Dne Ne 28.úno.2010 05:46:49, MSCHWERN napsal(a): Show quoted text
> Personally I'd just trust /etc/localtime like everything else does. > I've worked around it in perl5i by using DateTime::TimeZone::Tzfile to > read /etc/localtime if present.
I have the same feeling. The only problem with this approach is you cannot obtain the time zone name. I asked tzdata Fedora package maintainer to augment tzfile format to deliver the zone name, and he said that upstream had already refused any change in the format. Show quoted text
> Tzfile is so small the simplest > solution may be to just include it in DT::TZ. >
Attached patch utilizes DateTime::TimeZone::Tzfile as a last resort to obtain unnamed time zone definition from /etc/localtime content. I hit this "bug" in Fedora build system, unfortunately nobody can come with a fix on other side (tzdata package, build tools etc). You can read <https://bugzilla.redhat.com/show_bug.cgi?id=1135981> and bugs referenced from there via See Also and Blocks or Depends, if you are interested in this topic. -- Petr
Subject: 0001-Parse-etc-localtime-by-DateTime-TimeZone-Tzfile.patch
From 2976394b5aceb92df60dafdce4b5b50f3a7d14b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com> Date: Mon, 1 Sep 2014 17:37:12 +0200 Subject: [PATCH] Parse /etc/localtime by DateTime::TimeZone::Tzfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there is valid /etc/localtime, then the system has configured local time. If the file is not a symlink to /usr/share/zoneinfo or a copy from there, then it's still a valid configuration. The only issue is one cannot know the time zone name (Unfortunately, the time zone abbreviations are ambiguous.) This patch implements this scenario and caused returning a DateTime::TimeZone::Tzfile object instead of dying with "Cannot determine local time zone" message. Signed-off-by: Petr Písař <ppisar@redhat.com> --- lib/DateTime/TimeZone/Local/Unix.pm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/DateTime/TimeZone/Local/Unix.pm b/lib/DateTime/TimeZone/Local/Unix.pm index db96616..1b5011d 100644 --- a/lib/DateTime/TimeZone/Local/Unix.pm +++ b/lib/DateTime/TimeZone/Local/Unix.pm @@ -14,6 +14,7 @@ sub Methods { FromEtcTIMEZONE FromEtcSysconfigClock FromEtcDefaultInit + FromEtcLocaltimeContent ); } @@ -233,6 +234,25 @@ sub _ReadEtcDefaultInit { } } +sub FromEtcLocaltimeContent { + my $class = shift; + + my $lt_file = $class->_EtcFile('localtime'); + return unless -r $lt_file && -s $lt_file && ! -l $lt_file; + + my $tz; + { + local $@; + local $SIG{__DIE__}; + $tz = eval { + require DateTime::TimeZone::Tzfile; + DateTime::TimeZone::Tzfile->new($lt_file); + }; + } + + return $tz if $tz; +} + 1; # ABSTRACT: Determine the local system's time zone on Unix @@ -295,6 +315,13 @@ a time zone name. If this file exists, it is opened and we look for a line starting like "TZ=...". If this is found, it should indicate a time zone name. +=item * F</etc/localtime> content + +If this file is not a symlink, it's parsed by +a L<DateTime::TimeZone::Tzfile> to retrieve the time zone offset +definition. No time zone name will be defined. This is usefull if the +file does not present in the system time zone database. + =back =cut -- 1.9.3