Question

Étant donné que la date / heure est un tableau de (année, mois, jour, heure, minute, seconde), comment la convertir en heure d’époque, c’est-à-dire le nombre de secondes depuis 1970-01-01 00:00 : 00 GMT?

Question bonus: si la date / heure était donnée sous forme de chaîne, comment l’analyseriez-vous d’abord dans le tableau (y, m, j, h, m, s)?

Était-ce utile?

La solution 2

C’est le moyen le plus simple d’obtenir un temps Unix:

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

Notez l'ordre inverse des arguments et le mois de janvier correspond au mois 0. Pour de nombreuses autres options, voir le module DateTime de CPAN.

En ce qui concerne l'analyse syntaxique, consultez le module Date :: Parse de CPAN. Si vous avez vraiment besoin d’avoir l’intérêt pour l’analyse de date, Date :: Manip peut être utile, bien que sa propre documentation vous prévienne, car elle contient beaucoup de bagages (elle connaît des choses comme les jours fériés, par exemple) et que les autres solutions sont bien plus rapides.

Si vous savez quelque chose au sujet du format de la date / heure que vous allez analyser, une simple expression régulière peut suffire, mais vous feriez probablement mieux d'utiliser un module CPAN approprié. Par exemple, si vous savez que les dates seront toujours dans l'ordre YMDHMS, utilisez le module CPAN DateTime: : Format :: ISO8601 .

Pour ma propre référence, si rien d’autre, vous trouverez ci-dessous une fonction que j’utilise pour une application dans laquelle je sais que les dates seront toujours dans l’ordre YMDHMS, avec tout ou partie du paramètre "HMS". partie facultative. Il accepte tous les délimiteurs (par exemple, "2009-02-15" ou "2009.02.15"). Il renvoie l'heure unix correspondante (secondes depuis le 1970-01-01 à 00:00:00 GMT) ou -1 s'il ne peut pas l'analyser (ce qui signifie que vous devez vous assurer que vous n'aurez jamais légitimement besoin d'analyser la date. 1969- 12-31 23:59:59). Il présume également les années XX à deux chiffres jusqu’à "69". se référer à "20XX", sinon "19XX" (Par exemple, "50-02-15" signifie 2050-02-15 mais "75-02-15" signifie 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;
}

Autres conseils

Si vous utilisez le module DateTime , vous pouvez appeler le epoch () comme méthode sur un objet DateTime, car c'est ce que vous appelez le temps unix.

Utiliser DateTimes vous permet de convertir assez facilement d’objets datant d’époque.

Alternativement, localtime et gmtime convertiront une époque en un tableau contenant le jour et le mois. et année, timelocal et timegm du module Time :: Local feront le contraire, convertir un tableau d’éléments de temps (secondes, minutes, ..., jours, mois, etc.) en une époque.

Pour analyser une date, consultez Date :: Parse dans le réseau CPAN.

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

Je sais que c'est une vieille question, mais je pensais pouvoir offrir une autre réponse.

Time :: Piece est à la base de Perl 5.9 .5

Ceci permet l'analyse du temps dans des formats arbitraires via la méthode strptime .

exemple:

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

La partie utile est que, puisqu'il s'agit d'un objet surchargé, vous pouvez l'utiliser pour les comparaisons numériques.

par exemple.

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

Ou si vous y accédez dans un contexte de chaîne:

print $t,"\n"; 

Vous obtenez:

Wed Nov  3 00:00:00 1943

Il existe de nombreuses méthodes d’accessoires qui permettent diverses transformations utiles basées sur le temps. https://metacpan.org/pod/Time::Piece

Obtenir la date :: Manip de CPAN , puis:

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

modifier:

Date :: Manip est grand et lent, mais son analyse est très flexible et c'est du pur perl. Utilisez-le si vous êtes pressé lorsque vous écrivez du code, et vous savez que vous ne serez pas pressé lorsque vous l'exécutez.

par exemple. Utilisez-le pour analyser les options de ligne de commande une fois au démarrage, mais ne l’utilisez pas pour analyser de grandes quantités de données sur un serveur Web occupé.

Voir commentaires des auteurs .

(Merci à l'auteur du premier commentaire ci-dessous)

Mon analyseur de date / heure préféré est DateTime :: Format :: ISO8601 Une fois que cela fonctionne, vous obtenez un objet DateTime, facilement convertible en secondes d’époque avec epoch ()

Il existe de nombreux modules de manipulation de date sur CPAN. Mon préféré est DateTime et vous pouvez utiliser le modules strptime pour analyser les dates dans des formats arbitraires. Il existe également de nombreux modules DateTime :: Format sur CPAN pour la gestion des formats de date spécialisés, mais strptime est le plus générique.

Pour référence ultérieure, une ligne pouvant être appliquée, par exemple, aux scripts ! # # bin / sh .

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

N'oubliez pas d'éviter les valeurs octales!

Peut-être l'un des meilleurs exemples de "Il existe plus d'un moyen de le faire", avec ou sans l'aide de CPAN.

Si vous avez le contrôle sur ce qui vous a été transmis en tant que "date / heure", je vous suggérerais d'aller à la . DateTime , soit en utilisant une sous-classe Date :: Time :: Format spécifique, soit en utilisant DateTime :: Format :: Strptime si aucun format ne prend en charge votre format de date loufoque (voir la section FAQ de datetime pour plus de détails). En général, Date :: Time est la voie à suivre si vous voulez faire quelque chose de sérieux avec le résultat: peu de classes sur CPAN sont aussi rétentives anales et d'une précision obsessionnelle.

Si vous attendez des éléments étranges de formes libres, jetez-les à l'adresse Date :: Parse . La méthode str2time (), qui vous donnera une valeur en secondes depuis l'époque où vous pourrez ensuite avoir votre façon la plus folle, sans la surcharge de Date :: Manip .

Un filtre convertissant toutes les dates dans divers formats liés à ISO (et qui utiliserait quoi que ce soit d’autre après la lecture de les écritures du Mighty Kuhn?) sur l’entrée standard en secondes à partir de l’époque sur la sortie standard pourraient servir à illustrer les deux parties:

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:~$ 

Si vous recherchez simplement un utilitaire de ligne de commande (c’est-à-dire pas quelque chose qui sera appelé à partir d’autres fonctions), essayez ce script. Il suppose l’existence de la date GNU (présente sur pratiquement tous les systèmes Linux):

#! /usr/bin/perl -w

use strict;

Si vous recherchez simplement un utilitaire de ligne de commande (c’est-à-dire pas quelque chose qui sera appelé à partir d’autres fonctions), essayez ce script. Il suppose l’existence de la date GNU (présente sur pratiquement tous les systèmes Linux):

$ 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

Voici comment cela fonctionne:

<*> = (join ' ', @ARGV);

Si vous recherchez simplement un utilitaire de ligne de commande (c’est-à-dire pas quelque chose qui sera appelé à partir d’autres fonctions), essayez ce script. Il suppose l’existence de la date GNU (présente sur pratiquement tous les systèmes Linux):

<*>

Voici comment cela fonctionne:

<*> ||= <STDIN>; chomp; if (/^[\d.]+$/) { print scalar localtime

Si vous recherchez simplement un utilitaire de ligne de commande (c’est-à-dire pas quelque chose qui sera appelé à partir d’autres fonctions), essayez ce script. Il suppose l’existence de la date GNU (présente sur pratiquement tous les systèmes Linux):

<*>

Voici comment cela fonctionne:

<*>; print "\n"; } else { exec "date -d '

Si vous recherchez simplement un utilitaire de ligne de commande (c’est-à-dire pas quelque chose qui sera appelé à partir d’autres fonctions), essayez ce script. Il suppose l’existence de la date GNU (présente sur pratiquement tous les systèmes Linux):

<*>

Voici comment cela fonctionne:

<*>' +%s"; }

Voici comment cela fonctionne:

<*>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top