2016-07-08 9 views
7

Niedawno dowiedziałem się how to change the timezone returned by localtime in Perl.Kiedy skrypt Perla musi wywoływać `tzset` przed wywołaniem` localtime`?

use POSIX qw(tzset); 
print localtime . "\n"; 
$ENV{TZ} = 'America/Los_Angeles'; 
print localtime . "\n"; 
tzset; 
print localtime . "\n"; 

Wyjścia

Wed Apr 15 15:58:10 2009 
Wed Apr 15 15:58:10 2009 
Wed Apr 15 12:58:10 2009 

zauważyć, jak zmienia się tylko godziny po wywołaniu tzset.

This is perl, v5.8.8 built for x86_64-linux-thread-multi 

Jednak w moich systemach Dostaję,

Fri Jul 8 19:00:51 2016 
Fri Jul 8 16:00:51 2016 
Fri Jul 8 16:00:51 2016 

zauważyć, jak w moim systemie, godzina zmienia bez nazywając tzset. Odnosi się to na ostatnich wersjach Perl w Ubuntu i illumos, a także Perl v5.8.8 na Solaris 10.

Więc jeśli wszystkie moje testy wykazały, że tzset nie ma żadnego wpływu, dlaczego/co inne systemy wymagają tzset aby nazwać jednoznacznie? Czy nadal muszę dzwonić pod numer tzset, aby zachować kompatybilność z określonymi środowiskami, czy też należy już do przeszłości?

+1

http://perldoc.perl.org/perlport.html#Time-and-Date tl; dr - Pojęcie systemu dotyczące pory dnia i daty kalendarza jest kontrolowane na wiele różnych sposobów. Nie zakładaj, że strefa czasowa jest zapisana w $ ENV {TZ}, a nawet jeśli jest, nie zakładaj, że możesz kontrolować strefę czasową za pomocą tej zmiennej. – xxfelixxx

+0

Chciałbym coś konkretnego. Moje testy wskazują, że nie można wywoływać 'tzset'. Ponieważ tutaj oprogramowanie jest przeznaczone tylko dla konkretnych platform, nie chcę mówić naszemu zespołowi, aby wykonał dodatkową pracę, która nie jest potrzebna. Więc w jakich warunkach potrzebujemy 'tzset'? –

+1

Odpowiedź została opublikowana i usunięta, ale zawiera linki do http://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html, która mówi: "Informacje o lokalnej strefie czasowej są używane tak, jakby wywoływały funkcje localtime() tzset(). "*, więc brzmi to jak' localtime' powinno automatycznie wywoływać 'tzset', jeśli system jest zgodny z POSIX ??? Czy to jest decydujący czynnik - czy system operacyjny jest zgodny z POSIX? –

Odpowiedz

4

TL; DR: Począwszy Perl v5.8.9 (wydany w 2011), wywołanie tzset przy zmianie $ENV{TZ} nie jest już potrzebny.


Perla localtime rozmowy localtime_r(3)internally, które nie jest wymagane, aby zadzwonić tzset(3). Linux manpage radzi:

Według POSIX.1-2004, localtime() jest wymagane aby zachowywać się tak, jakby tzset (3) została wywołana, gdy localtime_r() nie ma tego wymóg. Dla przenośnego kodu tzset (3) powinien zostać wywołany przed localtime_r().

W starszych Perls non-wielowątkowych, czy localtime_r(3) nie był dostępny w czasie kompilacji, localtime(3) jest używany zamiast. W takim przypadku, wezwanie do tzset byłaby niepotrzebna, per POSIX:

Informacje lokalne strefy czasowej służy jakby localtime() zwraca tzset()

chociaż nie wydaje się być czasach, w których glibc didn't adhere to that :

Jak dla dowolnego kodu, który nie wymaga tzset cały czas: to zdecydowanie nie zmieni. To zbyt drogie. I po co? 0.000001% osób, które biorą komputery przenośne podczas światowej trasy koncertowej i oczekują na przykład wiadomości syslog z datami zgodnie z rodzimą strefą czasową. To jest niewystarczająco uzasadnione. Po prostu uruchom ponownie komputer.

Ten zrobił zmiana choć i glibc teraz ma działać tak, jakby tztime(3) nazywano, ale tylko dla non-reentrant localtime który może nie być co twój Perl został opracowany do użycia.

Wystąpiły dwa raporty błędów Perla dotyczące tego: #26136 i #41591.

Jako poprawkę, Perl teraz decides at configuration time, czy konieczne jest wykonanie niejawnego tzset(3), co powoduje, że podanie go w kodzie użytkownika jest zbędne.

Powiązane problemy