2016-07-08 23 views
7

Ich habe kürzlich how to change the timezone returned by localtime in Perl gelernt.Wann muss ein Perl-Skript `tzset` aufrufen, bevor 'localtime` aufgerufen wird?

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

Ausgänge

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

Beachten Sie, wie die Stunde erst nach tzset Aufruf ändert.

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

jedoch auf meine Systeme Ich erhalte,

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

Beachten Sie, wie auf meinem System, die Stunde ändert ohnetzset aufrufen. Dies gilt auf neueren Versionen von Perl in Ubuntu und Illumos sowie Perl v5.8.8 auf Solaris 10.

Also, wenn alle meine Tests zeigen, dass tzset keine Wirkung hat, warum/was andere Systeme erfordern tzset explizit aufgerufen werden? Muss ich immer noch tzset anrufen, um mit bestimmten Umgebungen kompatibel zu bleiben, oder gehört es jetzt der Vergangenheit an?

+1

http://perldoc.perl.org/perlport.html#Time-and-Date tl; dr - Die Uhrzeit und das Kalenderdatum des Systems werden auf sehr unterschiedliche Weise gesteuert. Nehmen Sie nicht an, dass die Zeitzone in $ ENV {TZ} gespeichert ist, und selbst wenn dies der Fall ist, nehmen Sie nicht an, dass Sie die Zeitzone über diese Variable steuern können. – xxfelixxx

+0

Ich möchte etwas Spezifisches. Meine Tests zeigen, dass es sicher ist, 'tzset' nicht aufzurufen. Da die Software hier nur für bestimmte Plattformen gedacht ist, möchte ich unser Team nicht dazu auffordern, zusätzliche Arbeit zu leisten, die nicht benötigt wird. Also, unter welchen Bedingungen brauchen wir 'tzset'? –

+1

Eine Antwort wurde gepostet und gelöscht, aber es gibt Links zu http://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html, in der steht: "Lokale Zeitzoneninformationen werden verwendet, als ob localtime() tzset() aufruft. "*, also klingt es wie' localtime' sollte 'tzset' automatisch aufrufen, wenn das System POSIX-konform ist ??? Ist das der entscheidende Faktor - ob das Betriebssystem POSIX-konform ist? –

Antwort

4

TL; DR: Beginnend mit Perl v5.8.9 (im Jahr 2011 veröffentlicht) rufen tzset beim Wechsel $ENV{TZ} nicht mehr benötigt wird.


Perl localtime Anrufe localtime_r(3)internally, die erforderlich ist, nicht tzset(3) zu nennen. Die Linux manpage rät:

Nach POSIX.1-2004, localtime() erforderlich ist, als ob tzset (3) aufgerufen wurde zu verhalten, während localtime_r() nicht über diese Anforderung haben. Für portablen Code sollte tzset (3) vor localtime_r() aufgerufen werden.

Bei älteren Nicht-multithreaded Perls, oder wenn localtime_r(3) war während Build nicht verfügbar, localtime(3) stattdessen verwendet wird. In diesem Fall würde ein Aufruf an tzset unnötig gewesen, per POSIX:

Lokalen Zeitzone Informationen werden als ob Localtime verwendet() ruft tzset()

obwohl es scheint schon mal zu haben, wo glibc didn't adhere to that :

für jeden Code Wie die die ganze Zeit nicht nennen tzset: diese definitly nicht ändern wird. Es ist viel zu teuer. Und wofür? Die 0.000001% der Leute, die die Laptops auf einer Welttournee nehmen und z. B. Syslog-Nachrichten mit Daten gemäß der nativen Zeitzone erwarten. Dies ist nicht gerechtfertigt genug. Starten Sie einfach Ihren Rechner neu.

Diese tat Änderung obwohl und glibc jetzt nicht handeln, als ob tztime(3) genannt wurde, aber nur für nicht-Reentry localtime, die vielleicht nicht, was Ihre Perl verwenden kompiliert wurde.

Es gab zwei Perl Fehlerberichte in Bezug auf diese: #26136 und #41591.

Als Fix, Perl jetzt decides at configuration time, ob eine implizite tzset(3) getan werden muss, die Angabe im Benutzercode überflüssig macht.