Domanda

Data una data/ora come array di (anno, mese, giorno, ora, minuto, secondo), come la convertiresti in epoca, ovvero il numero di secondi dal 1970-01-01 00:00:00 GMT ?

Domanda bonus:Se viene data la data/ora come stringa, come la analizzeresti prima nell'array (y,m,d,h,m,s)?

È stato utile?

Soluzione 2

Questo è il modo più semplice per ottenere l'ora Unix:

use Time::Local;
timelocal($second,$minute,$hour,$day,$month-1,$year);

Nota l'ordine inverso degli argomenti e che gennaio è il mese 0.Per molte altre opzioni, vedere il Appuntamento modulo da CPAN.

Per quanto riguarda l'analisi, vedere il Data::Analizza modulo da CPAN.Se hai davvero bisogno di divertirti con l'analisi delle date, il file Data::Manip può essere utile, anche se la sua stessa documentazione ti mette in guardia dal farlo poiché trasporta molti bagagli (conosce cose come le normali vacanze lavorative, ad esempio) e altre soluzioni sono molto più veloci.

Se ti capita di sapere qualcosa sul formato della data/ora che analizzerai, una semplice espressione regolare potrebbe essere sufficiente, ma probabilmente è meglio utilizzare un modulo CPAN appropriato.Ad esempio, se sai che le date saranno sempre nell'ordine YMDHMS, utilizza il modulo CPAN Data e ora:: Formato:: ISO8601.


Per mio riferimento, se non altro, di seguito è riportata una funzione che utilizzo per un'applicazione in cui so che le date saranno sempre in ordine YMDHMS con tutta o parte della parte "HMS" opzionale.Accetta qualsiasi delimitatore (ad esempio, "2009-02-15" o "2009.02.15").Restituisce l'ora unix corrispondente (secondi dal 1970-01-01 00:00:00 GMT) o -1 se non è riuscito ad analizzarlo (il che significa che è meglio essere sicuri di non aver mai legittimamente bisogno di analizzare la data 1969- 12-31 23:59:59).Si presuppone inoltre che gli anni XX a due cifre fino a "69" si riferiscano a "20XX", altrimenti "19XX" (ad esempio, "50-02-15" significa 2050-02-15 ma "75-02-15" significa 1975- 02-15).

use Time::Local;

sub parsedate { 
  my($s) = @_;
  my($year, $month, $day, $hour, $minute, $second);

  if($s =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0*
                 (\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x) {
    $year = $1;  $month = $2;   $day = $3;
    $hour = $4;  $minute = $5;  $second = $6;
    $hour |= 0;  $minute |= 0;  $second |= 0;  # defaults.
    $year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year);
    return timelocal($second,$minute,$hour,$day,$month-1,$year);  
  }
  return -1;
}

Altri suggerimenti

Se stai utilizzando il Appuntamento modulo, puoi chiamare il file epoca() metodo su un oggetto DateTime, poiché è ciò che pensi come tempo Unix.

L'utilizzo di DateTimes consente di convertire abbastanza facilmente da oggetti di epoca a oggetti di data.

In alternativa, ora locale e gmtime convertirà un'epoca in un array contenente giorno, mese e anno, e timelocal e timegm dal file Orario::Modulo locale farà il contrario, convertendo una serie di elementi temporali (secondi, minuti, ..., giorni, mesi ecc.) in un'epoca.

Per analizzare una data, guarda Data::Analizza nel CPAN.

$ENV{TZ}="GMT";
POSIX::tzset();
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900);

So che questa è una vecchia domanda, ma ho pensato di offrire un'altra risposta.

Time::Piece è fondamentale a partire da Perl 5.9.5

Ciò consente l'analisi del tempo in formati arbitrari tramite il file strptime metodo.

per esempio.:

my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943",
                              "%A %drd %b, %Y");

La parte utile è che, poiché è un oggetto sovraccarico, puoi usarlo per confronti numerici.

per esempio.

if ( $t < time() ) { #do something }

Oppure se accedi in un contesto di stringa:

print $t,"\n"; 

Ottieni:

Wed Nov  3 00:00:00 1943

Esistono numerosi metodi di accesso che consentono alcune altre utili trasformazioni basate sul tempo. https://metacpan.org/pod/Time::Piece

Ottieni data::Manip da CPAN, Poi:

use Date::Manip;
$string = '18-Sep-2008 20:09'; # or a wide range of other date formats
$unix_time = UnixDate( ParseDate($string), "%s" );

modificare:

Date::Manip è grande e lento, ma molto flessibile nell'analisi ed è puro Perl.Usalo se hai fretta quando scrivi il codice e sai che non avrai fretta mentre lo esegui.

per esempio.Usalo per analizzare le opzioni della riga di comando una volta all'avvio, ma non usarlo per analizzare grandi quantità di dati su un server web occupato.

Vedere commentano gli autori.

(Grazie all'autore del primo commento qui sotto)

Il mio parser datetime preferito è Data e ora:: Formato:: ISO8601 Una volta che avrai funzionato, avrai un oggetto DateTime, facilmente convertibile in secondi epoch con epoch()

Ci sono molti moduli per la manipolazione della data su CPAN.Il mio preferito in particolare è Appuntamento e puoi usare il moduli strptime per analizzare le date in formati arbitrari.Esistono anche molti moduli DateTime::Format su CPAN per la gestione di formati di data specializzati, ma strptime è il più generico.

Per ulteriore riferimento, un rivestimento che può essere applicato, ad esempio, !#/bin/sh script.

EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`"

Ricorda solo di evitare i valori ottali!

Forse uno dei migliori esempi di "C'è più di un modo per farlo", con o senza l'aiuto di CPAN.

Se hai il controllo su ciò che ti viene passato come "data/ora", suggerirei di andare su Appuntamento route, utilizzando una specifica sottoclasse Date::Time::Format o utilizzando DateTime::Format::Srptime se non ce n'è una che supporta il tuo stravagante formato di data (vedi la sezione Domande frequenti su datetime per ulteriori dettagli).In generale, Date::Time è la strada da percorrere se vuoi fare qualcosa di serio con il risultato:poche lezioni su CPAN sono altrettanto ritentive anali e ossessivamente accurate.

Se ti aspetti cose strane a mano libera, lanciagliele Data::Analizza, che ti darà un valore di secondi dall'epoca con il quale potrai fare a modo tuo, senza il sovraccarico di Data::Manip.

Un filtro che converte qualsiasi data in vari formati relativi a ISO (e chi utilizzerebbe qualsiasi altra cosa dopo aver letto gli scritti of the Mighty Kuhn?) sullo standard input al tempo dei secondi dall'epoca sullo standard output potrebbe servire a illustrare entrambe le parti:

martind@whitewater:~$ cat `which isoToEpoch`
#!/usr/bin/perl -w
use strict;
use Time::Piece;
# sudo apt-get install libtime-piece-perl
while (<>) {
  # date --iso=s:
  # 2007-02-15T18:25:42-0800
  # Other matched formats:
  # 2007-02-15 13:50:29 (UTC-0800)
  # 2007-02-15 13:50:29 (UTC-08:00)
  s/(\d{4}-\d{2}-\d{2}([T ])\d{2}:\d{2}:\d{2})(?:\.\d+)? ?(?:\(UTC)?([+\-]\d{2})?:?00\)?/Time::Piece->strptime ($1, "%Y-%m-%d$2%H:%M:%S")->epoch - (defined ($3) ? $3 * 3600 : 0)/eg;
  print;
}
martind@whitewater:~$ 

Se stai solo cercando un'utilità da riga di comando (cioè non qualcosa che verrà chiamato da altre funzioni), prova questo script.Si presuppone l'esistenza della data GNU (presente praticamente su qualsiasi sistema Linux):

#! /usr/bin/perl -w

use strict;

$_ = (join ' ', @ARGV);
$_ ||= <STDIN>;

chomp;

if (/^[\d.]+$/) {
    print scalar localtime $_;
    print "\n";
}
else {
    exec "date -d '$_' +%s";
}

Ecco come funziona:

$ Time now
1221763842

$ Time yesterday
1221677444

$ Time 1221677444
Wed Sep 17 11:50:44 2008

$ Time '12:30pm jan 4 1987'
536790600

$ Time '9am 8 weeks ago'
1216915200
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top