2015-03-18 1 views
0

Я использую Bugzilla на сервере IIS, который использует модуль Perl DateTime. К сожалению, время показывается неправильно. gmtime показывает правильное время в GMT, но localtime не дает правильного времени, когда я меняю $ENV{TZ}.

Вот код, чтобы продемонстрировать вопрос:

#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"; 

Печатается:

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 

Ниже приведены ожидаемые результаты:

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 

Вот мой Perl Информация о версии:

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. 

Я видел posts, которые говорят, вы должны запустить

POSIX::tzset(); 

после изменения $ENV{TZ}, но когда я пытаюсь это, я получаю сообщение об ошибке:

POSIX::tzset not implemented on this architecture. 

Здесь находятся серверные журналы для IIS , Время в UTC и верно.

#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 

Как это исправить?

Нашим решением было переместить Bugzilla в гостевую ОС Linux на виртуальной машине. Это решило проблему.

+0

Я отказался от моего близкого голоса на основе ваших комментариев что вы пытаетесь использовать 'POSIX :: tzset не реализованы в этой архитектуре', когда пытаетесь использовать' POSIX :: tzset'. Я также отредактировал ваш вопрос, чтобы уточнить, что это не дубликат (по крайней мере, не связанный с этим вопросом).С вашего вопроса все еще неясно, действительно ли Bugzilla использует «localtime» или вы просто пытаетесь дублировать поведение, которое вы видите. Вы отмечаете, что Bugzilla использует 'DateTime', но ваш фрагмент использует' localtime'. – ThisSuitIsBlackNot

+0

Из того, что я читал, Bugzilla использует localtime. В настоящий момент Bugzilla также дает время, равное GMT ​​+ 1. Вот что демонстрировал тестовый сценарий выше. –

+0

Вы пробовали установить часовой пояс в настройках? Какую версию Bugzilla вы используете? Вы видите ошибки в ваших журналах? – ThisSuitIsBlackNot

ответ

1

После смены $ENV{TZ} необходимо позвонить POSIX::tzset().

+1

Я видел несколько мест, которые предложили это. Когда я попытался использовать POSIX :: tzset(), я получаю другую ошибку. POSIX :: tzset не реализована в этой архитектуре. Похоже, что это невозможно в окнах. Я также попробовал Time :: Piece :: _ tzset(), но получил те же результаты, что и оригинал с Нью-Йорком и Лос-Анджелесом, имеющим время на один час раньше GMT ​​ –

+0

Weird. Я тестировал с помощью ActivePerl 5.16.3 build 1603, созданного для MSWin32-x64-multi-thread. Вы всегда можете использовать DateTime. – ikegami

+0

Я только что установил ActivePerl 5.18.4 build 1803 и все еще не смог заставить это работать. К сожалению, версия 5.18.4 такая же старая версия, как я могу получить. –

1

Код, который вы отправили, не используется 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; 
        " 

выход (из ДКБ):

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 
+0

Извините, не разработчик perl. Я думал, что местное время было частью datetime. К сожалению, даже с этим я получаю смещение по времени на 1 час в неправильном направлении. –

+1

@Jeff Gay, 'localtime' - встроенный оператор Perl. DateTime является сторонним модулем/дистрибутивом. DateTime дает правильные результаты (независимо от системы), поэтому вы должны сделать что-то неправильно. – ikegami

+0

Какая часть конкретно дает время, неверно смещенное на 1 час? 'Time_zone => 'local''? 'Америка/New_York'? – Oesor

1

Документация _tzset объясняет приемлемый формат для $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).

Таким образом, следующие работы:

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

Но, вы обнаружите, что некоторые другие ценности «работают», а также, несмотря на то, что они не документированы:

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