2012-02-03 11 views
10

In un programma Perl ho una variabile che contiene data/ora in questo formato:Differenza di tempo in secondi

Feb 3 12:03:20 

ho bisogno per determinare se tale data è più di x secondi di vita (in base al tempo corrente), anche se ciò si verifica oltre la mezzanotte (ad es. Feb 3 23:59:00 con orario corrente = Feb 4 00:00:30).

Le informazioni di data/ora perl che ho trovato sono sbalorditive. Per quanto posso dire ho bisogno di usare Date::Calc, ma non sto trovando un delta secondi. Grazie :)

risposta

3

In perl, c'è sempre più di un modo per fare qualcosa. Ecco un che utilizza solo un modulo che viene fornita di serie con il Perl:

#! perl -w 

use strict; 
use Time::Local; 

my $d1 = "Feb 3 12:03:20"; 
my $d2 = "Feb 4 00:00:30"; 

# Your date formats don't include the year, so 
# figure out some kind of default. 
use constant Year => 2012; 


# Convert your date strings to Unix/perl style time in seconds 
# The main problems you have here are: 
# * parsing the date formats 
# * converting the month string to a number from 1 to 11 
sub convert 
{ 
    my $dstring = shift; 

    my %m = ('Jan' => 0, 'Feb' => 1, 'Mar' => 2, 'Apr' => 3, 
      'May' => 4, 'Jun' => 5, 'Jul' => 6, 'Aug' => 7, 
      'Sep' => 8, 'Oct' => 9, 'Nov' => 10, 'Dec' => 11); 

    if ($dstring =~ /(\S+)\s+(\d+)\s+(\d{2}):(\d{2}):(\d{2})/) 
    { 
     my ($month, $day, $h, $m, $s) = ($1, $2, $3, $4, $5); 
     my $mnumber = $m{$month}; # production code should handle errors here 

     timelocal($s, $m, $h, $day, $mnumber, Year - 1900); 
    } 
    else 
    { 
     die "Format not recognized: ", $dstring, "\n"; 
    } 
} 

my $t1 = convert($d1); 
my $t2 = convert($d2); 

print "Diff (seconds) = ", $t2 - $t1, "\n"; 

per rendere questo davvero pronto per la produzione, ha bisogno di una migliore gestione dell 'anno (per esempio, cosa succede quando la data di inizio è nel mese di dicembre e la fine data nel mese di gennaio?) e una migliore gestione degli errori (ad esempio, cosa succede se l'abbreviazione di 3 caratteri è mispelled?).

+0

wow ... molto più coinvolto di quanto mi aspettassi ... grazie –

+2

@xivix, è inutilmente complicato per quello che vuoi. [La risposta di vmpstr] (http://stackoverflow.com/a/9134822/132382) è totalmente utilizzabile qui. – pilcrow

+0

Dipende tutto da quanti moduli puoi o userai. Vedere la risposta di @vmpstr, usando Date :: Parse. Se l'installazione di quel modulo è accettabile, provaci. È probabile che stia facendo un lavoro migliore per gestire formati di dati e possibili errori diversi da questo breve frammento di codice. – theglauber

9

Sembra esserci un comodo Date::Parse. Ecco l'esempio:

use Date::Parse; 

print str2time ('Feb 3 12:03:20') . "\n"; 

Ed ecco quello che uscite:

$ perl test.pl 
1328288600 

che è: Fri Feb 3 12:03:20 EST 2012

io non sono sicuro di come decente l'analisi è, ma analizza il tuo esempio solo bene :)

+0

come si ottiene la data corrente nello stesso formato per il confronto? localtime (time) fornisce un numero molto più lungo. –

+0

@xivix: Non è necessario 'localtime', basta usare' time': restituisce un timestamp Unix (secondi dal 1 gennaio 1970 00:00:00 UTC), proprio come 'str2time'. –

+0

Fortunatamente per le tue esigenze, perl usa la convenzione Unix di misurare il tempo in secondi dal 1 ° gennaio 1970, quindi l'output di str2parse sopra è già in secondi, e tu puoi fare i conti. – theglauber

2

Supponendo che si desidera utilizzare Date::Calc, convertire i due valori in "tempo" valori con Date_to_Time e s ubtract i valori per ottenere la differenza in secondi. Ma per fare questo, è necessario convertire le stringhe in valori YY MM DD hh mm ss per passare a Date_to_Time prima.

6

Nello spirito di TMTOWTDI, è possibile sfruttare il nucleo Time::Piece:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Time::Piece; 
my $when = "@ARGV" or die "'Mon Day HH:MM:SS' expected\n"; 
my $year = (localtime)[5] + 1900; 
my $t = Time::Piece->strptime($year . q() . $when, "%Y %b %d %H:%M:%S"); 
print "delta seconds = ", time() - $t->strftime("%s"),"\n"; 

$ ./mydelta Feb 3 12:03:20

delta seconds = 14553 

L'anno in corso è assunto e portato da il tuo locale

+1

Non so perché, ma '$ t-> epoch' funziona mentre' $ t-> strftime ("% s") 'non – Zaid

+0

@Zaid Quale versione di [Time :: Piece] (https: // metacpan. org/changes/distribution/Time-Piece) stai usando? Sembra che sia stato aggiunto 1.20 il supporto 'strftime' per'% s'. – JRFerguson

+0

$ t-> epoch sembra utilizzare alcune impostazioni di localizzazione di cui non sono a conoscenza. Nel mio caso, 'epoch' sta restituendo il valore del fuso orario EDT, mentre attualmente sono in orario JST (ora giapponese). Tuttavia, 'strftime ("% s ")' restituisce il valore corretto in secondi (JST), che è coerente con 'time()'. – lepe

18
#!/usr/bin/perl 

$Start = time(); 
sleep 3; 
$End = time(); 
$Diff = $End - $Start; 

print "Start ".$Start."\n"; 
print "End ".$End."\n"; 
print "Diff ".$Diff."\n"; 

Questo è un modo semplice per trovare la differenza di tempo in secondi.

+0

Questo non risponde affatto alla domanda, che riguarda il confronto dei tempi in due variabili. – RichVel

+0

Vero, MA consente ... a.) La persona che ha chiesto alla domanda originale di considerare un approccio diverso, che potrebbe essere più semplice del suo modo originale; b.) Altre persone che trovano questa pagina attraverso una ricerca sul Web per misurare facilmente i secondi trascorsi. Io appartengo a quest'ultimo, e mi piace molto l'esempio di Sjoerd. Semplice e non ha dipendenze. Proprio quello che stavo cercando. – Keve

Problemi correlati