Comment définir le fuseau horaire de localtime () de Perl?

en Perl, j'aimerais regarder le temps local dans un fuseau horaire spécifique. J'avais été en utilisant cette technique:

$ENV{TZ} = 'America/Los_Angeles';
my $now = scalar localtime;
print "It is now $nown";
# WORKS: prints the current time in LA

cependant, ce n'est pas fiable -- notamment, si je prépare un autre appel localtime() avant de définir $ENV{TZ}, il casse:

localtime();
$ENV{TZ} = 'America/Los_Angeles';
my $now = scalar localtime;
print "It is now $nown";
# FAILS: prints the current time for here instead of LA

Est-il une meilleure façon de le faire?

16
demandé sur mike 2009-04-15 23:34:31

6 réponses

Utiliser POSIX:: tzset.

use POSIX qw(tzset);

my $was = localtime;
print "It was      $was\n";

$ENV{TZ} = 'America/Los_Angeles';

$was = localtime;
print "It is still $was\n";

tzset;

my $now = localtime;
print "It is now   $now\n";
$ perl -v

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

Copyright 1987-2006, Larry Wall

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.

$ perl tzset-test.pl
It was      Wed Apr 15 15:58:10 2009
It is still Wed Apr 15 15:58:10 2009
It is now   Wed Apr 15 12:58:10 2009
19
répondu ephemient 2009-04-15 23:13:06

je suggère fortement d'utiliser un module pour faire cela. Plus précisément, je suggère D'utiliser DateTime (voir Perl DateTime Wiki ou CPAN

Ensuite, vous devriez être en mesure de faire quelque chose comme ce qui suit:

use strict;
use warnings;
use DateTime;
my $dt = DateTime->now(); # *your* local time assuming your system knows it!


my $clone1 = $dt->clone; # taking a copy.
$clone1->set_time_zone('America/Los_Angeles');


print "$clone1\n";   # output using ISO 8601 format (there a lot of choices)
print "$dt\n";
9
répondu Nic Gibson 2009-04-15 19:56:08

alors que votre code fonctionne très bien pour moi sur Linux (Perl 5.10.0) et MacOS X (5.8.9), il y a une solution possible.

Le C sous-jacente fonctions utilisé par Perl (ctime(),localtime(), etc) appel tzset() la première fois qu'ils sont invoqués, mais pas nécessairement par la suite. En l'appelant vous-même, vous devez vous assurer que les structures du fuseau horaire sont correctement initialisées après tout changement vers $TZ.

heureusement que c'est facile - le tzset() fonction est disponible dans le POSIX module:

#!/usr/bin/perl -w
use POSIX qw[tzset];

$ENV{'TZ'} = 'Europe/London';
tzset();
print scalar localtime();

NB: certaines recherches Google suggèrent que cela n'est nécessaire qu'avec les versions Perl allant jusqu'à 5.8.8. Les versions suivantes appellent toujours tzset() automatiquement avant chaque appel localtime().

3
répondu Alnitak 2009-04-15 20:19:26
use Time::Zone;

my $TZ = 'America/Los_Angeles';
my $now = scalar localtime time() + tz_offset($TZ);
print "It is now $now\n";

semble fonctionner ici. (Le "scalar" est redondant ici puisque $lui donne maintenant un contexte scalar, mais c'est aussi bien d'être explicite.)

selon le commentaire, j'ai eu le problème original. Cela semble corriger pour moi, mais étant donné que d'autres n'ont pas le problème original, le "semble travailler ici" bit est destiné à une invitation pour ces personnes à essayer cette solution aussi bien pour s'assurer qu'il ne casse rien. (Je me demande si alnitak a remarqué la différence entre ce que j'ai posté et le post original?)

1
répondu Tanktalus 2009-04-15 20:05:15

Sommaire:

Paramètre $ENV{TZ}='/*&+000000000005 " et de Temps d'appel:::: _tzset() fixe localtime() en accord avec le windoz de l'horloge système.

Sanguinarily détails techniques:

chaque fuseau horaire sur http://www.timeanddate.com/time/zones/ que j'ai essayé donne le bon moment si vous êtes à Greenwich.

à Chaque fois: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones aussi ne change localtime (). Et, il n'y a aucune indication apparente. Ils ne font rien et ne disent rien.

il n'y a même pas de concept de POSIX ??? C:\bin > cpan install POSIX ... Attention: ne peut pas installer POSIX, ne sait pas ce que C'est. Essayez la commande I / POSIX/

il semble être cuit dans win8 et il y a des Points pas des bibliothèques pour cela.

heure L'heure actuelle est: 16: 36: 39.44 ... Time=Apr 14 16:36: 42 2015, ENV->TZ=/*&+5

en lançant une boucle pour et en essayant des valeurs aléatoires à partir de divers messages, pour la fraise Perl uname='Win32 strawberry-perl 5.18.2.2...'avec des bogues de fuseau horaire connus, n'importe quel 3 caractères que j'ai essayé (n'a pas essayé + ou -) suivi de +/- et un petit nombre a fonctionné. Voici un tableau de valeurs de texte et de leur sortie ci-dessous:

use Time::Piece;
@tz = ('', 'CDT+5', 'CST+5', 'FKU+5', 'XYZ+5', '+5', '+05', '+05.00', 
    'America/Chicago', 'America/Los_Angeles', 'CDT', 
    'CST', 'UTC', 'PDT', 'PST', '-01:00', '+01:00', '-05:00'.
    'ACDT', 'EASST', '5000', '+0500', '+5:00', '+05:00', 'SSS+1', 'SSS+0',
    'zzz-1', 'ZZ1+5', '123+5', '___+5', '/*&+5', , '/*&+05', '/*&+005',
    '/*&+000000000005');
foreach $tz (@tz)  {
    $ENV{TZ} = $tz         if $tz;
    Time::Piece::_tzset()  if $tz;
    printf("T%s, ENV->TZ=%s\n", scalar localtime, $ENV{TZ}  ||  'NoTZ');
}

la Plupart des tous les essayer avec quelque chose, mais XXX . + / - . integer a donné UTC, mais beaucoup étaient une heure de congé sans raison (America / Los_Angeles et America/Chicago ont donné la même valeur). Je suis presque sûr que j'avais l'habitude de m'en tirer avec juste CDT et CST, éventuellement sur Activestate (commuté sur Strawberry pour compiler mes propres modules Perl plutôt que de compter sur Activestate pour tout). C'est le premier grand grognement.

j'ai reconstruit DateTime à partir de zéro et ça a bien fonctionné. DateTime::Fuseau horaire:::: Win32 "a échoué pour" Win32::TieRegistry'"

    P:\br1\sxsw.2015\sx-2015.0318\done>bb | sort
    Running c:/bin/bb.pl  Tue Apr 14 21:43:56 2015
    TTue Apr 14 16:43:56 2015, ENV->TZ=/*&+000000000005
    TTue Apr 14 16:43:56 2015, ENV->TZ=/*&+005
    TTue Apr 14 16:43:56 2015, ENV->TZ=/*&+05
    TTue Apr 14 16:43:56 2015, ENV->TZ=/*&+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=___+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=123+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=CDT+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=CST+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=FKU+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=XYZ+5
    TTue Apr 14 16:43:56 2015, ENV->TZ=ZZ1+5
    ABOVE ALL WORKED Below most failed with UTC or +1 hour???
    TTue Apr 14 20:43:56 2015, ENV->TZ=SSS+1
    TTue Apr 14 21:43:56 2015, ENV->TZ=-01:00
    TTue Apr 14 21:43:56 2015, ENV->TZ=+01:00
    TTue Apr 14 21:43:56 2015, ENV->TZ=+05
    TTue Apr 14 21:43:56 2015, ENV->TZ=+05:00
    TTue Apr 14 21:43:56 2015, ENV->TZ=+0500
    TTue Apr 14 21:43:56 2015, ENV->TZ=+5
    TTue Apr 14 21:43:56 2015, ENV->TZ=+5:00
    TTue Apr 14 21:43:56 2015, ENV->TZ=5000
    TTue Apr 14 21:43:56 2015, ENV->TZ=CDT
    TTue Apr 14 21:43:56 2015, ENV->TZ=CDT
    TTue Apr 14 21:43:56 2015, ENV->TZ=CST
    TTue Apr 14 21:43:56 2015, ENV->TZ=PDT
    TTue Apr 14 21:43:56 2015, ENV->TZ=PST
    TTue Apr 14 21:43:56 2015, ENV->TZ=SSS+0
    TTue Apr 14 21:43:56 2015, ENV->TZ=UTC
    TTue Apr 14 22:43:56 2015, ENV->TZ=-05:00ACDT
    TTue Apr 14 22:43:56 2015, ENV->TZ=+05.00
    TTue Apr 14 22:43:56 2015, ENV->TZ=America/Chicago
    TTue Apr 14 22:43:56 2015, ENV->TZ=America/Los_Angeles
    TTue Apr 14 22:43:56 2015, ENV->TZ=EASST
    TTue Apr 14 22:43:56 2015, ENV->TZ=zzz-1
  • même après avoir trouvé et installé le Graal, le module TzFile pour la base de données Olsen, il est toujours vissé, aucune différence!

    Installation C:\bin\strawberry_perl_5_18\perl\site\lib\DateTime\TimeZone\Tzfile.pm ZEFRAM / DateTime-TimeZone-Tzfile-0.010.tar.gz C:\bin\strawberry_perl_5_18\perl\bin\perl.EXE. / Build install --uninst 1 -- OK

Voici tous les timezones allégués qui ne font rien sur cette plate-forme de: @atz = DateTime:: TimeZone- > all_names(); printf("Tous tz noms [%d] = %s\n", scalar @atz, join(", ", @atz));

tous les noms tz [349] = Afrique / Abidjan, Afrique/ Accra, Afrique/Alger, Afrique/Bissau, Afrique/Le Caire, Afrique/Casablanca, Afrique/Ceuta, Afrique/El_Aaiun, Afrique/Johannesburg, Afrique/Khartoum, Afrique/Lagos, Afrique/Maputo, Afrique/Monrovia, Afrique/Nairobi, Afrique/Ndjamena, Afrique/Tripoli, Afrique/Tunis, Afrique/Windhoek, Amérique/Adak, Amérique/Anchorage, Amérique/Araguaina, Amérique/Argentine/Buenos_Aires, Amérique/Argentine/Catamarca, Amérique/Argentine/Cordoba, Amérique/Argentine/Jujuy, Amerique / Argentina/ La_rioja, America/Argentina/Mendoza, Amerique/Argentina/Rio_Gallegos, America/Argentina/Salta, America/Argentina/San_Juan, America/Argentina/San_Luis, America/Argentina/Tucuman, America/Argentina/Ushuaia, America/Asuncion, America/Atikokan, America/Bahia, America/Bahia_Banderas, America/Barbados, America/Belem, America/Belize, America/Blanc-Sablon, America/Boa_Vista, America/Bogota, America/Boise, America/Cambridge_Bay, America/Campo_grande, America/Cancun, America/Caracas, Amerique / Cayenne, America / Chicago, America / Chihuahua, America/Costa_Rica, America/Creston, America/Cuiaba, America/Curacao, America/Danmarkshavn, America/Dawson, America/Dawson_Creek, America/Denver, America/Detroit, America/Edmonton, America/Eirunepe, America/El_Salvador, America/Fortaleza, America/Glacie_bay, America/Godthab, America/Goose_Bay, America/Grand_Turk, America/Guatemala, America/Guayaquil, America/Guyane, Amérique/Halifax, Amérique/La Havane, Amérique/Hermosillo, Amérique/Indiana/Indianapolis, Amerique / Indiana / Knox, America / Indiana / Marengo, Amerique/Indiana/Petersburg, America/Indiana/Tell_City, America/Indiana/Vevay, America/Indiana/Vincennes, America/Indiana/Winamac, America/Inuvik, America/Iqaluit, America/Jamaica, America/Juneau, America/Kentucky/Louisville, America/Kentucky/Monticello, America/La_Paz, America/Lima, America/Los_Angeles, America/Maceio, America/Managua, America/Manaus, America/Martinique, America/Matamoros, America/Mazatlan, America/Menominee, America / Merida, America / Metlakatla, America/Mexico_City, Amérique/ - Miquelon, Amérique/Moncton, America/Monterrey, l'Amérique/Montevideo, l'Amérique, Montréal, America/Nassau, America/New_York, l'Amérique/Nipigon, l'Amérique/Nome, en Amérique/Noronha, l'Amérique/North_Dakota/Beulah, l'Amérique/North_Dakota/Centre de l'Amérique/North_Dakota/New_Salem, l'Amérique/Ojinaga, America/Panama, Amérique/Pangnirtung, l'Amérique/Paramaribo, l'Amérique/Phoenix, America/Port-au-Prince, l'Amérique/Port_of_Spain, l'Amérique/Porto_Velho, l'Amérique/Puerto_Rico, Amérique/Rainy_River, L'Amérique/Rankin_Inlet, Amérique/Recife, America/Regina, L'Amérique/Resolute, L'Amérique/Rio_Branco, L'Amérique/Santa_Isabel, L'Amérique/Santarem, America/Santiago, America/Santo_Domingo, America/Sao_Paulo, Amérique Du Scoresbysund, L'Amérique/Sitka, America/St_Johns, L'Amérique/Swift_Current, America/Tegucigalpa, L'Amérique/Thule, L'Amérique/Thunder_Bay, L'Amérique/Tijuana, America/Toronto, America/Vancouver, L'Amérique/Whitehorse, Amérique Du/De Winnipeg, De L'Amérique/Yakutat, L'Amérique/Yellowknife, Antarctique/Casey, Antarctique/Davis, Antarctique/DumontDUrville, Antarctique/Macquarie, Antarctique/Mawson, Antarctique/Palmer, Antarctique/Rothera, Antarctique/Syowa, Antarctique/Troll, Antarctique/Vostok, Asie/Almaty, Asie/Amman, Asie/Anadyr, Asie/Aqtau, Asie/Aqtobe, Asie/Achgabat, Asie/Bagdad, Asie/Bakou, Asie/Bangkok, Asie/Beyrouth, Asie/Bichkek, Asie/Brunei, Asie/Chita, Asie/Choibalsan, Asie/Colombo, Asie/Damas, Asie/Dhaka, Asie/Dili, Asie / Dubaï, Asie/Douchanbé, Asie / Gaza, Asie / Hébron, Asie / Ho_Chi_Minh, Asie/Hong_Kong, Asie/Hovd, Asie / Irkutsk, Asie / Jakarta, Asie/Jayapura, Asie/Jérusalem, Asie/Kaboul, Asie/Kamchatka, Asie/Karachi, Asie/Katmandou, Asie/Khandyga, Asie/Kolkata, Asie/Krasnoyarsk, Asie/Kuala_Lumpur, Asie/Kuching, Asie/Macao, Asie/Magadan, Asie/Makassar, Asie/Manille, Asie/Nicosie, Asie/Novokuznetsk, Asie/Novosibirsk, Asie/Omsk, Asie/Oral, Asie/Pontianak, Asie/Pyongyang, Asie/Qatar, Asie/Qyzylorda, Asie/Rangoon, Asie / Riyad, Asie / Sakhalin, Asie / Samarkand, Asie / Séoul, Asie / Shanghai, Asie / Singapour, Asie/Srednekolymsk, Asie / Taipei, Asie/Tachkent, Asie/Tbilissi, Asie/Téhéran, Asie/Thimphu, Asie/Tokyo, Asie/Ulaanbaatar, Asie/Urumqi, Asie/Ust-Nera, Asie/Vladivostok, Asie/Yakutsk, Asie/Yekaterinburg, Asie/Yerevan, Atlantique/Açores, Atlantique/Bermudes, Atlantique/Canary, Atlantique/Cape_Verde, Atlantique/Faroe, Atlantique/Madeira, Atlantique/Reykjavik, Atlantique/South_Georgia, Atlantique/Stanley, Australie/Adelaide, Australie/Brisbane, Australie/Broken_hill, Australie / Currie, Australie / Darwin, Australie / Eucla, Australie / Hobart, Australie / Lindeman, Australie/Lord_Howe, Australie/Melbourne, Australie/Perth, Australie/Sydney, CET, CST6CDT, EET, EST, EST5EDT, Europe/Amsterdam, Europe/Andorre, Europe/Athènes, Europe/Belgrade, Europe/Berlin, Europe/Bruxelles, Europe/Bucarest, Europe/Budapest, Europe/Chisinau, Europe/Copenhague, Europe/Dublin, Europe/Gibraltar, Europe/Helsinki, Europe/Istanbul, Europe/Kaliningrad, Europe/Kiev, Europe / Lisbonne, Europe / Londres, Europe / Luxembourg, Europe / Madrid, Europe / Malte, Europe / Minsk, Europe / Monaco, Europe/Moscou, Europe/Oslo, Europe/Paris, Europe/Prague, Europe/Riga, Europe/Rome, Europe/Samara, Europe/Simferopol, Europe/Sofia, Europe/Stockholm, Europe/Tallinn, Europe/Tirane, Europe/Uzhgorod, Europe/Vienne, Europe/Vilnius, Europe/Volgograd, Europe/Varsovie, Europe/Zaporozhye, Europe/Zurich, HST, Indian/Chagos, Indian/Christmas, Indian/Cocos, Indian / Kerguelen, Indian/ Mahe, Indian / Maldives, Indian / Mauritius, Indian/Reunion, MET, MST, MST7MDT, PST8PDT, Pacific/Apia, Pacific/Auckland, Pacific/Bougainville, Pacific/Chatham, Pacific/Chuuk, Pacific/Easter, Pacific/Efate, Pacific/Enderbury, Pacific/Fakaofo, Pacific/Fiji, Pacific/Funafuti, Pacific/Galapagos, Pacific/Gambier, Pacific/Guadalcanal, Pacific/Guam, Pacific/Honolulu, Pacific/Kiritimati, Pacific/Kosrae, Pacific/Kwajalein, Pacific/Majuro, Pacific/Marquesas, Pacific/Nauru, Pacific/Niue, Pacifique/Norfolk, Pacifique/Noumea, Pacifique/Pago_pago, Pacifique / Palaos, Pacifique / Pitcairn, Pacifique / Pohnpei, Pacifique / Port_Moresby, Pacifique / Rarotonga, Pacifique / Tahiti, Pacifique / Tarawa, Pacifique / Tongatapu, Pacifique / Wake, Pacifique / Wallis, UTC, humide

0
répondu BrianP007 2015-04-14 23:04:16

étendre sur BrianP007 réponse vous utilisez à la fois TZ et _tzset

$was = localtime;
print "It was $was\n";
$ENV{TZ} = 'CST6CDT'; # America/Chicago
Time::Piece::_tzset(); # Local time is now Chicago Time
$was = localtime;
print "It is $was\n"; # Right now in Chicago

Le truc, c'est que la TZ est réglée de votre position à GMT. Donc normalement, vous pensez que Chicago est UTC-6, mais de Chicago, il est de 6 heures à UTC qui = 'CST6'.

voir http://science.ksc.nasa.gov/software/winvn/userguide/3_1_4.htm

0
répondu ozcoder 2016-02-19 07:56:42