0

I'm using Bugzilla on an IIS server which uses Perl's DateTime module. Unfortunately the time is showing incorrectly. gmtime shows the correct time in GMT but localtime does not give the correct time when I change $ENV{TZ}.

Here is some code to demonstrate the issue:

#C:\Perl64\bin/perl -w
$ENV{TZ} = 'America/New_York';
my $now = scalar localtime;
$TZone =  $ENV{'TZ'}; 
print "It is now $now $TZone\n";

$ENV{TZ} = 'America/Los_Angeles';
my $now = scalar localtime;
$TZone =  $ENV{'TZ'}; 
print "It is now $now $TZone\n";

my $GMTime = scalar gmtime;
print "It is now $GMTime GMT\n";

This prints:

It is now Wed Mar 18 17:02:46 2015 America/New_York
It is now Wed Mar 18 17:02:46 2015 America/Los_Angeles
It is now Wed Mar 18 16:02:46 2015 GMT

Here are the expected results:

It is now Wed Mar 18 12:02:46 2015 America/New_York
It is now Wed Mar 18 9:02:46 2015 America/Los_Angeles
It is now Wed Mar 18 16:02:46 2015 GMT

Here is my perl version information:

This is perl 5, version 20, subversion 1 (v5.20.1) built for MSWin32-x64-multi-thread
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2014, Larry Wall

Binary build 2000 [298557] provided by ActiveState http://www.ActiveState.com
Built Oct 15 2014 14:56:57

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

I have seen posts that say you have to run

POSIX::tzset();

after changing $ENV{TZ}, but when I try that, I get an error:

POSIX::tzset not implemented on this architecture.

Here are the server logs for IIS. The times are in UTC and are correct.

#Software: Microsoft Internet Information Services 7.5
#Version: 1.0
#Date: 2015-03-18 20:15:34
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2015-03-18 20:17:52 127.0.0.1 GET /bugzilla/skins/standard/show_bug.css - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/42.0.2311.39+Safari/537.36 304 0 0 1
2015-03-18 20:17:52 127.0.0.1 GET /bugzilla/js/comments.js - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/42.0.2311.39+Safari/537.36 304 0 0 24
2015-03-18 20:18:06 127.0.0.1 POST /bugzilla/process_bug.cgi - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/42.0.2311.39+Safari/537.36 200 0 0 9498
2015-03-18 20:18:23 127.0.0.1 GET /bugzilla/show_bug.cgi id=1 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/42.0.2311.39+Safari/537.36 200 0 0 1164

How can I fix this?

Our Solution was to move Bugzilla to a Linux Guest OS on a VM. This solved the problem.

Community
  • 1
  • 1
Jeff Gay
  • 1
  • 1
  • I've retracted my close vote based on your comment that you get `POSIX::tzset not implemented on this architecture` when you try to use `POSIX::tzset`. I've also edited your question to clarify that it isn't a duplicate (at least, not of the question I originally linked to). It's still unclear from your question whether Bugzilla is actually using `localtime` or whether you're just trying to duplicate the behavior you see. You mention that Bugzilla uses `DateTime` but your snippet uses `localtime`. – ThisSuitIsBlackNot Mar 18 '15 at 18:52
  • From what I have read Bugzilla is using localtime. At the moment Bugzilla is giving also giving times that are GMT+1. That is what the test script above was demonstrating. – Jeff Gay Mar 18 '15 at 19:34
  • Have you tried setting the timezone in the preferences? What version of Bugzilla are you using? Do you see any errors in your logs? – ThisSuitIsBlackNot Mar 18 '15 at 19:52
  • The timezone settings in Bugzilla are currently set to New York on the default settings page. Im using Bugzilla 4.4.8 which is the most recent stable version. – Jeff Gay Mar 18 '15 at 20:21

3 Answers3

1

You need to call POSIX::tzset() after changing $ENV{TZ}.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    I had seen several places that had suggested this. When I tried using POSIX::tzset() I get a different error. POSIX::tzset not implemented on this architecture. It looks like this is not available on windows. I also tried Time::Piece::_tzset() but got the same results as the original with New York and LA having the sametime one hour ahead of GMT – Jeff Gay Mar 18 '15 at 17:38
  • Weird. I tested with ActivePerl 5.16.3 build 1603 built for MSWin32-x64-multi-thread. You could always use DateTime. – ikegami Mar 18 '15 at 17:51
  • I just installed ActivePerl 5.18.4 build 1803 and was still unable to get this to work. Unfortunately version 5.18.4 is as old a version as I can get. – Jeff Gay Mar 18 '15 at 19:04
1

The code you posted is not using DateTime.

perl -MDateTime -E" say DateTime->now(time_zone => 'local'); 
                    say DateTime->now(time_zone => 'America/New_York');
                    say DateTime->now(time_zone => 'America/Los_Angeles');
                    say DateTime->now(time_zone => 'GMT');

                    my $now = DateTime->now(time_zone => 'local');
                    say 'before conversion: ', $now;
                    $now->set_time_zone('America/New_York');
                    say 'after conversion: ', $now;
                  "

Output (from CST):

2015-03-18T11:47:10
2015-03-18T12:47:10
2015-03-18T09:47:10
2015-03-18T16:47:10
before conversion: 2015-03-18T11:47:10
after conversion: 2015-03-18T12:47:10
Oesor
  • 6,632
  • 2
  • 29
  • 56
  • Sorry, not a perl developer. I thought that localtime was part of datetime. Unfortunately even with this I get time offset by 1 hour in the wrong direction. – Jeff Gay Mar 18 '15 at 19:10
  • 1
    @Jeff Gay, `localtime` is a builtin Perl operator. DateTime is a 3rd party module/distribution. DateTime produces the right results (independent of system), so you must have done something wrong. – ikegami Mar 18 '15 at 19:21
  • Which part specifically gives the time incorrectly offset by 1 hour? `Time_zone => 'local'`? `America/New_York`? – Oesor Mar 18 '15 at 21:09
1

The documentation for _tzset explains the acceptable format for $ENV{TZ}:

set TZ=tzn[+ | –]hh[:mm[:ss] ][dzn]

tzn: Three-letter time-zone name, such as PST. You must specify the correct offset from local time to UTC.

hh: Difference in hours between UTC and local time. Sign (+) optional for positive values.

mm: Minutes. Separated from hh by a colon (:).

ss: Seconds. Separated from mm by a colon (:).

dzn: Three-letter daylight-saving-time zone such as PDT. If daylight saving time is never in effect in the locality, set TZ without a value for dzn. The C run-time library assumes the United States' rules for implementing the calculation of daylight saving time (DST).

So, the following works:

 C:\> perl -E "$ENV{TZ}='PST-8:00PDT';say scalar localtime"
Wed Mar 18 15:44:57 2015

But, you'll find that some other values "work" as well, even though they are not documented:

C:\> set TZ='-08:00'

C:\> perl -E "say scalar localtime"
Wed Mar 18 12:27:33 2015
C:\> set TZ=

C:\> perl -E "say scalar localtime"
Wed Mar 18 15:28:03 2015
C:\> perl -E "$ENV{TZ}=q{'-08:00'};say scalar localtime"
Wed Mar 18 15:34:41 2015
C:\> perl -E "$ENV{TZ}=q{'America/Los_Angeles'};say scalar localtime"
Wed Mar 18 15:35:09 2015
Community
  • 1
  • 1
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339