73 votes

Accéder rapidement à YYYY-mm-dd HH:MM:SS en Perl

Lors de l'écriture de scripts Perl, je trouve souvent le besoin d'obtenir l'heure actuelle représentée sous forme de chaîne formatée comme AAAA-MM-JJ HH:MM:SS (disons 2009-11-29 14:28:29).

En faisant cela, je me retrouve à emprunter ce chemin assez laborieux :

  • man perlfunc
  • /localtime pour rechercher localtime - répétez cinq fois (/ + \n) pour atteindre la section pertinente de la page de manuel
  • Copier la chaîne ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); de la page de manuel vers mon script.
  • Essayer avec my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
  • Rappel gotcha n°1 : Doit ajouter 1900 à $year pour obtenir l'année en cours.
  • Essayer avec my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
  • Rappel gotcha n°2 : Doit ajouter 1 à $mon pour obtenir le mois en cours.
  • Essayer avec my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
  • Ça semble bon. Terminé !

Alors 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, donc ma question est simplement :

Quel est le moyen le plus simple d'obtenir un AAAA-MM-JJ HH:MM:SS de la date/heure actuelle en Perl ?

Où "simple" englobe à la fois "facile à écrire" et "facile à retenir".

1 votes

Tu aurais dû écrire une sous-routine pour rechercher dans le perlfunc et se souvenir des pièges pour toi, bien sûr!

0 votes

Ecrire une question sur stackoverflow avec toutes les étapes, en faisant semblant de demander une solution :-)

81voto

Greg Bacon Points 50449

Utilisez strftime dans le module standard POSIX. Les arguments de strftime dans la liaison Perl ont été conçus pour être en adéquation avec les valeurs de retour de localtime et gmtime. Comparez

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);

L'utilisation en ligne de commande est par exemple

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

ou depuis un fichier source comme ci-dessous

use POSIX;

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

Certains systèmes ne supportent pas les raccourcis %F et %T, donc vous devrez ê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 retourne l'heure actuelle lors de son appel tandis que $^T est figé à 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.

0 votes

Il y a aussi strftime dans Time::Piece (noyau depuis 5.10) qui vous permet d'utiliser une forme plus orientée objet (voir ma réponse ci-dessous). De plus, $^T (temps écoulé depuis le démarrage du programme) n'est pas ce que vous voulez.

34voto

Zaid Points 21192

Pourquoi ne pas utiliser le module DateTime pour faire le travail à votre place? C'est facile à écrire et à retenir!

use strict;
use warnings;
use DateTime;

my $dt   = DateTime->now;
my $date = $dt->ymd;
my $time = $dt->hms;

my $wanted = "$date $time";
print $wanted;

Une fois que vous savez ce qui se passe, vous pouvez vous débarrasser des variables temporaires et gagner quelques lignes de code:

use strict;
use warnings;
use DateTime;

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

33voto

Vish Points 159

Essayez ceci :

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

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


13voto

MkV Points 2454

Time::Piece (in core since Perl 5.10) a également une fonction strftime et surcharge par défaut les fonctions localtime et gmtime pour retourner des objets Time::Piece :

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

ou sans la surcharge de localtime :

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

1 votes

+1 pour la mention d'un module principal et son utilisation -- puisque la grande quantité de modules disponibles est l'une des principales raisons pour lesquelles la plupart d'entre nous utilisent Perl en premier lieu

4voto

ernix Points 1061

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

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

0 votes

Une autre mention de Time::Piece devrait me faire m'en souvenir maintenant - pas vraiment le module le plus facile à se rappeler d'utiliser s'il n'est pas utilisé quotidiennement :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X