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($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
de la page de manuel dans mon script.my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
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».
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
.
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;
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.
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');
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
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.
Time::Piece::datetime()
peut éliminer T
.
use Time::Piece;
print localtime->datetime(T => q{ });
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]
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