Domanda

Ho usato la funzione localtime in Perl per ottenere la data e l'ora correnti ma è necessario analizzare le date esistenti. Ho una data GMT nel seguente formato: "20090103 12: 00" Vorrei analizzarlo in un oggetto data con cui posso lavorare e quindi convertire l'ora / la data GMT nel mio fuso orario attuale che è attualmente l'ora solare orientale. Quindi vorrei convertire " 20090103 12: 00 " a "20090103 7: 00" qualsiasi informazione su come farlo sarebbe molto apprezzata.

È stato utile?

Soluzione

Poiché le interfacce di gestione della data incorporate in Perl sono un po 'goffe e si finisce per passare una mezza dozzina di variabili, il modo migliore è usare DateTime o Time :: Piece . DateTime è l'oggetto data Perl che canta e balla, e probabilmente alla fine vorrai usarlo, ma Time :: Piece è più semplice e perfettamente adeguato a questo compito, ha il vantaggio di spedire con 5.10 e la tecnica è praticamente lo stesso per entrambi.

Ecco il modo semplice e flessibile di utilizzare Time :: Piece e 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;

Ed ecco il modo manuale, per contrasto.

Dato che il formato è fisso, un'espressione regolare andrà bene, ma se il formato cambia dovrete modificare la regex.

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

Quindi convertilo in tempo di epoca Unix (secondi dal 1 ° gennaio 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);

E poi di nuovo all'ora 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;

Altri suggerimenti

Ecco un esempio, usando DateTime e il suo strptime modulo formato.

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


Se avessi voluto analizzare il localtime, ecco come lo faresti :)

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";

Questo è quello che farei ...

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

$orig = "20090103 12:00";

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

Puoi anche usare Time :: ParseDate e parsedate () invece di Date :: Parse e str2time () . Si noti che lo standard di fatto atm. sembra essere DateTime (ma potresti non voler usare la sintassi OO solo per convertire un timestamp).

Fai la tua scelta:

Ci sono molti altri miliardi, senza dubbio, ma sono probabilmente i migliori contendenti.

use strict;
use warnings;
my ($sec,$min,$hour,$day,$month,$year)=localtime();
$year+=1900;
$month+=1;
$today_time = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$day,$month,$year,$hour,$min,$sec);
print $today_time;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top