2016-07-08 79 views
7

Recentemente ho appreso how to change the timezone returned by localtime in Perl.Quando uno script Perl deve chiamare `tzset` prima di chiamare` localtime`?

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

uscite

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

notare come l'ora cambia solo dopo aver chiamato tzset.

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

Tuttavia, sui miei sistemi sto ottenendo,

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

Notate come sul mio sistema, l'ora cambia senza chiamare tzset. Questo vale sulle recenti versioni di Perl in Ubuntu e illumos, così come Perl v5.8.8 su Solaris 10.

Quindi, se tutti i miei test indicano che tzset non ha alcun effetto, perché/quali altri sistemi richiedono tzset di essere chiamato in modo esplicito? Devo ancora chiamare lo tzset per rimanere compatibile con determinati ambienti o è ormai una cosa del passato?

+1

http://perldoc.perl.org/perlport.html#Time-and-Date tl; dr - La nozione di ora del giorno e data del calendario del sistema è controllata in modi molto diversi. Non dare per scontato che il fuso orario sia memorizzato in $ ENV {TZ}, e anche se lo è, non dare per scontato che tu possa controllare il fuso orario attraverso quella variabile. – xxfelixxx

+0

Vorrei qualcosa di specifico. Il mio test indica che è sicuro non chiamare 'tzset'. Poiché il software qui è inteso solo per piattaforme specifiche, non voglio dire al nostro team di fare del lavoro extra che non è necessario. Quindi, in quali condizioni abbiamo bisogno di 'tzset'? –

+1

Una risposta è stata pubblicata ed eliminata, ma si collega a http://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html, che dice * "Le informazioni sul fuso orario locale vengono utilizzate come se localtime() chiama tzset(). "*, quindi suona come' localtime' dovrebbe chiamare 'tzset' automaticamente se il sistema è conforme a POSIX ??? È questo il fattore determinante: se il sistema operativo è conforme a POSIX? –

risposta

4

TL; DR: A partire da Perl v5.8.9 (uscito nel 2011) chiamando tzset quando si cambia $ENV{TZ} non è più necessaria.


del Perl localtime chiamate localtime_r(3)internally, che non è tenuto a chiamare tzset(3). Il Linux manpage consiglia:

Secondo POSIX.1-2004, localtime() è necessario per comportarsi come se tzset (3) è stato chiamato, mentre localtime_r() non ha questo requisito . Per il codice portatile tzset (3) dovrebbe essere chiamato prima di localtime_r().

In più anziani Perls non multithread, o se localtime_r(3) non era disponibile durante la costruzione, localtime(3) viene utilizzato al posto. In tal caso, una chiamata a tzset sarebbe stato inutile, per POSIX:

informazioni sul fuso orario locale viene utilizzato come se localtime() chiama tzset()

anche se ci sembrano essere stati momenti in cui glibc didn't adhere to that :

Come per qualsiasi codice che non richiede tzset tutto il tempo: questo sicuramente non cambierà. È troppo costoso. E per cosa? Lo 0,000001% delle persone che portano i laptop in un tour mondiale e si aspettano, ad esempio, i messaggi syslog con date in base al fuso orario nativo. Questo è non abbastanza giustificato. Riavvia la tua macchina.

Questo fatto cambiamento e anche se glibc fa ora agire come se tztime(3) è stato chiamato, ma solo per non rientrante localtime che potrebbe non essere ciò che il vostro Perl è stato compilato da usare.

Ci sono state due segnalazioni di bug Perl su questo: #26136 e #41591.

Come una correzione, Perl ora decides at configuration time se un implicito tzset(3) deve essere eseguito, il che rende superfluo specificarlo nel codice utente.