web-dev-qa-db-fra.com

Comment analyser des dates et convertir des fuseaux horaires en Perl?

J'ai utilisé la fonction localtime en Perl pour obtenir la date et l'heure actuelles, mais j'ai besoin d'analyser les dates existantes. J'ai une date GMT au format suivant: "20090103 12:00" Je voudrais l'analyser en un objet de date avec lequel je peux travailler, puis convertir l'heure/la date GMT dans mon fuseau horaire actuel, qui est actuellement l'heure normale de l'Est. . Je voudrais donc convertir "20090103 12:00" en "20090103 7:00". Toute information sur la façon de procéder serait grandement appréciée.

26
Jared

Parce que les interfaces de gestion des dates intégrées à Perl sont un peu maladroites et que vous finissez par passer autour d'une demi-douzaine de variables, la meilleure façon est d'utiliser soit DateTime ou Time :: Piece . DateTime est l'objet de date Perl tout chantant et tout dansant, et vous voudrez probablement éventuellement l'utiliser, mais Time :: Piece est plus simple et parfaitement adapté à cette tâche, a l'avantage d'être expédié avec 5.10 et la technique est fondamentalement la même chose pour les deux.

Voici la manière simple et flexible d'utiliser Time :: Piece et strptime .

#!/usr/bin/Perl

use 5.10.0;

use strict;
use warnings;

use Time::Piece;

# Read the date from the command line.
my $date = shift;

# Parse the date using strptime(), which uses strftime() formats.
my $time = Time::Piece->strptime($date, "%Y%m%d %H:%M");

# Here it is, parsed but still in GMT.
say $time->datetime;

# Create a localtime object for the same timestamp.
$time = localtime($time->Epoch);

# And here it is localized.
say $time->datetime;

Et voici la manière manuelle, pour le contraste.

Puisque le format est fixe, une expression régulière fera très bien l'affaire, mais si le format change, vous devrez Ajuster l'expression régulière.

my($year, $mon, $day, $hour, $min) = 
    $date =~ /^(\d{4}) (\d{2}) (\d{2})\ (\d{2}):(\d{2})$/x;

Puis convertissez-le en temps Unix Epoch (secondes depuis le 1er janvier 1970)

use Time::Local;
# Note that all the internal Perl date handling functions take month
# from 0 and the year starting at 1900.  Blame C (or blame Larry for
# parroting C).
my $time = timegm(0, $min, $hour, $day, $mon - 1, $year - 1900);

Et puis revenez à votre heure locale.

(undef, $min, $hour, $day, $mon, $year) = localtime($time);

my $local_date = sprintf "%d%02d%02d %02d:%02d\n",
    $year + 1900, $mon + 1, $day, $hour, $min;
48
Schwern

Voici un exemple, en utilisant DateTime et son module de format strptime .

use DateTime;
use DateTime::Format::Strptime;

my $val = "20090103 12:00";

my $format = new DateTime::Format::Strptime(
                pattern => '%Y%m%d %H:%M',
                time_zone => 'GMT',
                );

my $date = $format->parse_datetime($val);

print $date->strftime("%Y%m%d %H:%M %Z")."\n";

$date->set_time_zone("America/New_York");  # or "local"

print $date->strftime("%Y%m%d %H:%M %Z")."\n";

$ Perl dates.pl
20090103 12:00 UTC
20090103 07:00 EST

use DateTime;

my @time = (localtime);

my $date = DateTime->new(year => $time[5]+1900, month => $time[4]+1,
                day => $time[3], hour => $time[2], minute => $time[1],
                second => $time[0], time_zone => "America/New_York");

print $date->strftime("%F %r %Z")."\n";

$date->set_time_zone("Europe/Prague");

print $date->strftime("%F %r %Z")."\n";
21
Vinko Vrsalovic

Voilà ce que je ferais ...

#!/usr/bin/Perl
use Date::Parse;
use POSIX;

$orig = "20090103 12:00";

print strftime("%Y%m%d %R", localtime(str2time($orig, 'GMT')));

Vous pouvez également utiliser Time::ParseDate Et parsedate() au lieu de Date::Parse Et str2time(). Notez que l'atmosphère standard de facto. semble être DateTime (mais vous pourriez ne pas vouloir utiliser OO syntaxe juste pour convertir un horodatage).

5
mjy

Faites votre choix:

Il y en a des millions, sans doute, mais ce sont probablement les meilleurs candidats.

4
Jonathan Leffler