web-dev-qa-db-fra.com

Se rendre rapidement à AAAA-mm-jj HH: MM: SS en Perl

Lors de l'écriture de scripts Perl, je trouve souvent qu'il est nécessaire d'obtenir l'heure actuelle représentée par une chaîne au format YYYY-mm-dd HH:MM:SS (disons 2009-11-29 14:28:29).

En faisant cela, je me retrouve dans cette voie assez lourde:

  • man perlfunc
  • /localtime pour rechercher heure locale - répétez l'opération cinq fois (/ + \n) pour atteindre la section correspondante de la page de manuel
  • Copiez la chaîne ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); de la page de manuel dans mon script.
  • Essayez avec my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
  • Rappelez-vous le n ° 1: Vous devez ajouter 1900 à $ année pour obtenir l'année en cours.
  • Essayez avec my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
  • Rappelez-vous gotcha # 2: Doit ajouter 1 à $ mon pour obtenir le mois en cours.
  • Essayez avec my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
  • Semble ok. Terminé!

Bien que le processus décrit ci-dessus fonctionne, il est loin d'être optimal. Je suis sûr qu'il existe un moyen plus intelligent, alors ma question est simplement:

Quel est le moyen le plus simple d’obtenir un YYYY-mm-dd HH:MM:SS de la date/heure actuelle en Perl?

Où «facile» englobe à la fois «facile à écrire» et «facile à retenir».

58
knorv

Utilisez strftime dans le module standard POSIX . Les arguments de strftime in Perl ont été conçus pour s’aligner sur les valeurs de retour de localtime et gmtime . Comparer

strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)

avec

my          ($sec,$min,$hour,$mday,$mon,$year,$wday,     $yday,     $isdst) = gmtime(time);

Exemple d'utilisation en ligne de commande:

$ Perl -MPOSIX -le 'print strftime "%F %T", localtime $^T'

ou à partir d'un fichier source comme dans

use POSIX;

print strftime "%F %T", localtime time;

Certains systèmes ne supportent pas les raccourcis %F et %T, vous devrez donc être explicite avec

print strftime "%Y-%m-%d %H:%M:%S", localtime time;

ou

print strftime "%Y-%m-%d %H:%M:%S", gmtime time;

Notez que time renvoie l’heure actuelle lorsqu’elle est appelée tandis que $^T est fixée à l’heure à laquelle votre programme a démarré. Avec gmtime , la valeur de retour est l'heure actuelle en GMT. Récupérez l'heure dans votre fuseau horaire local avec localtime .

67
Greg Bacon

Quoi ne pas utiliser le module DateTime pour faire le sale boulot pour vous? C'est facile d'écrire et souvenez-vous!

use strict;
use warnings;
use DateTime;

my $dt   = DateTime->now;   # Stores current date and time as datetime object
my $date = $dt->ymd;   # Retrieves date as a string in 'yyyy-mm-dd' format
my $time = $dt->hms;   # Retrieves time as a string in 'hh:mm:ss' format

my $wanted = "$date $time";   # creates 'yyyy-mm-dd hh:mm:ss' string
print $wanted;

Une fois que vous savez ce qui se passe, vous pouvez vous débarrasser du temps et enregistrer quelques lignes de code:

use strict;
use warnings;
use DateTime;

my $dt = DateTime->now;
print join ' ', $dt->ymd, $dt->hms;
33
Zaid

Essaye ça:

use POSIX qw/strftime/;
print strftime('%Y-%m-%d',localtime);

la méthode strftime fait le travail efficacement pour moi. Très simple et efficace.


29
Vish

Time :: Piece (dans le noyau depuis Perl 5.10) a également une fonction strftime et surcharge par défaut localtime et gmtime pour retourner les objets Time :: Piece:

use Time::Piece;
print localtime->strftime('%Y-%m-%d');

ou sans l'heure locale remplacée:

use Time::Piece (); 
print Time::Piece::localtime->strftime('%F %T');
13
MkV

J'ai fait un petit test (Perl v5.20.1 sous FreeBSD sous VM) en appelant les blocs suivants 1 000 000 fois chacun:

UNE

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);

B

my $now = strftime('%Y%m%d%H%M%S',localtime);

C

my $now = Time::Piece::localtime->strftime('%Y%m%d%H%M%S');

avec les résultats suivants:

A: 2 secondes

B: 11 secondes

C: 19 secondes

Ce n'est bien sûr pas un test approfondi ni une référence, mais au moins il est reproductible pour moi. Même si c'est plus compliqué, je préférerais la première méthode si la génération d'un horodatage est très souvent requise.

Appeler (par exemple sous FreeBSD 10.1)

my $now = `date "+%Y%m%d%H%M%S" | tr -d "\n"`;

ce n’est peut-être pas une bonne idée, car il n’est pas indépendant du système d’exploitation et prend un certain temps.

Cordialement, Holger

4
Holger

si vous voulez juste une chaîne de temps lisible par l'homme et non ce format exact:

$t = localtime;
print "$t\n";

empreintes 

Mon Apr 27 10:16:19 2015

ou ce qui est configuré pour vos paramètres régionaux.

3
robm

Time::Piece::datetime() peut éliminer T.

use Time::Piece;
print localtime->datetime(T => q{ });
2
ernix

Dans de nombreux cas, le "temps actuel" nécessaire est plutôt $ ^ T, qui correspond au moment où le script a commencé à s'exécuter, en secondes entières (en supposant seulement 60 minutes) depuis l’époque UNIX.

Cela permet d'éviter qu'une partie antérieure d'un script utilise une date (ou un statut d'heure avancée) différente de celle d'une partie ultérieure d'un script, par exemple dans les conditions de requête et les autres valeurs dérivées.

Pour cette variante de 'heure actuelle', on peut utiliser une constante, également pour documenter le fait qu'elle était gelée au moment de la compilation:

use constant YMD_HMS_AT_START => POSIX::strftime( "%F %T", localtime $^T );

Temps de démarrage alternatif à haute résolution:

0+ [ Time::HiRes::stat("/proc/$$") ]->[10]
1
druid62

Court et doux, pas de modules supplémentaires nécessaires:

my $toDate = `date +%m/%d/%Y" "%l:%M:%S" "%p`;

La sortie par exemple serait: 25/04/2017 09:30:33

0
Off The Gold