
Des codes sources perlConsultez toutes les FAQ
Nombre d'auteurs : 13, nombre de questions : 59, dernière mise à jour : 27 mai 2011
Sommaire
→
Gestions des dates- Comment afficher une date en perl ?
- Comment récupérer une date aléatoire entre deux dates données ?
- Comment connaitre le time depuis une date ( L'inverse de localtime et gmtime) ?
- Comment calculer le nombre de jours et/ou semaines entre deux dates ?
- Connaitre une date vieille ou futur
- Comment obtenir la date au format DB2, obtenir la microseconde ?
- Les modules les plus utilisés pour la gestion des dates en perl
Il existe plusieurs fonctions perl permettant d'obtenir la date (année, mois, jour, heure, etc. ).
- time : renvoie un nombre scalaire qui indique le nombre de secondes qui se sont écoulées depuis la date fr epoch de votre machine.
- localtime : renvoie les données relatives au temps local. L'affichage ressemble à celui de la fonction date de linux.
- gmtime : renvoie les données relatives au temps universel.
- Module POSIX.
#!/usr/bin/perl
use strict;
use warnings;
my $le_time = time;
print "Depuis le 1/1/1970, il y a eu $le_time secondes.\n";
my $le_localtime = localtime;
print "La date locale : $le_localtime\n";
my $le_gmtime = gmtime;
print "La date universelle : $le_gmtime\n";
Depuis le 1/1/1970, il y a eu 1185539208 secondes.
La date locale : Fri Jul 27 14:26:48 2007
La date universelle : Fri Jul 27 12:26:48 2007
localtime(time) renvoie un tableau contenant plusieurs données nécessaires comme le jour, le mois, l'année, etc. Il est plus facile d'expliquer via un exemple. Voici une procédure que j'utilise régulièrement pour afficher la date.
#!/usr/bin/perl
use strict;
use warnings;
my $RefDateActuelle = date(); # On recupere la réference d'un hash
my $time = 1234567890;
my $RefAutreDate = date($time); # On recupere la réference d'un hash
print "Date actuelle : $RefDateActuelle->{date} $RefDateActuelle->{heure}\n";
print "Date correspondant au time $time : $RefAutreDate>{date} $RefAutreDate>{heure}\n";
sub date {
my $time = shift || time; #$time par defaut vaut le time actuel
my ( $seconde, $minute, $heure, $jour, $mois, $annee, $jour_semaine, $jour_annee, $heure_hiver_ou_ete )
= localtime($time);
$mois += 1;
$annee += 1900;
# On rajoute 0 si le chiffre est compris entre 1 et 9
foreach ( $seconde, $minute, $heure, $jour, $mois, $annee ) {
s/^(\d)$/0$1/;
}
my %date = (
"date" => "$jour-$mois-$annee",
"heure" => "$heure:$minute:$seconde",
"jour_semaine" => $jour_semaine,
"jour_annee" => $jour_annee,
"hiverOuEte" => $heure_hiver_ou_ete,
);
return \%date;
}
Date actuelle : 05-12-2008 11:02:57
Date correspondant au time 1234567890 : 14-02-2009 00:31:30
POSIX
use POSIX qw(strftime);
my $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
Exemple 2 en utilisant le format %V, qui défini le numéro de semaine selon la norme ISO 8601:2000
use POSIX qw(strftime);
my %jours = ("1er janvier 2009" => [ 0, 0, 0, 1, 0, 109 ],
"31 décembre 2009" => [ 0, 0, 0, 31, 11, 109 ]);
print strftime "Le $_ est en semaine %V\n", @{$jours{$_}} foreach sort keys %jours;
Qui produit :
Le 1er janvier 2009 est en semaine 01
Le 31 décembre 2009 est en semaine 53
Comme DateTime est le module préconisé, mais qu'il n'est pas disponible dans le Core,
alors que POSIX l'est, il me semble que c'est une bonne alternative pour des utilisations "limitées".
Le code ci-dessous est compatible avec des machines acceptant des entiers sur 32 bits. Il
utilise mktime et localtime.
Attention toutefois sur les machines 32 bits, les dates limites utilisables sont de 1904 à 2038.
Pour utiliser des dates en dehors de cette plage, il faut s'en remettre aux modules spécialisés comme DateTime.
Il peut être utile de connaître le time d'une date, c'est l'inverse de time, localtime et gmtime.
Cela se fait par exemple en php pour les connaisseurs via la fonction mktime.
Comme d'habitude, il existe un module Time::LocalTime::Local
en perl déjà présent dans le CORE, donc pas besoin d'installation.
Ce module posséde deux méthodes timelocal et timegm qui renvoient le time.
Il faut leur donner 6 informations sous forme de tableau ($sec,$min,$hour,$mday,$mon,$year).
Attention : $year sera bien l'année classique (avec + 1900),
ex : 2007 et $mois sera compris entre 0 et 11 et non entre 1 et 12.
Nous trouver le time des dates 01/01/2000 et 05/12/2008
#!/usr/bin/perl
use strict;
use Carp;
use warnings;
use Time::Local;
my @Dates1 = split("/", "01/01/2000" );
my @Dates2 = split("/", "05/12/2008" );
# Reduisons le mois de 1
$Dates1[1] -= 1;
$Dates2[1] -= 1;
print "01/01/2000 : ", timelocal( 0,0,0, @Dates1 ),"\n";
print "05/12/2008 : ", timelocal( 0,0,0, @Dates2 ),"\n";
Vous pourrez maintenant jongler avec les time afin de faire des calculs sur les dates, faires des comparaisons de dates et autres. D'un point pédagogique c'est bien, mais je vous conseille d'utiliser des modules adéquats pour faire cela plus proprement.
01/01/2000 : 946681200
15/12/2008 : 1229295600
Vous souhaitez connaitre le nombre de jours (ou le nombre de semaines) entre deux dates, utilisez le module Date::CalcDate::Calc.
#!/usr/bin/perl
use warnings;
use strict;
use Date::Calc qw(:all);
my $date1 = '28/05/2006';
my $date2 = '19/11/2009';
my ( $jour1, $mois1, $annee1 ) = split( '/', $date1 );
my ( $jour2, $mois2, $annee2 ) = split( '/', $date2 );
# Calcul le nombre de jour entre 2 dates
my $NombreJoursEntreDate = Delta_Days( ( $annee1, $mois1, $jour1 ), ( $annee2, $mois2, $jour2 ) );
print "Il y a $NombreJoursEntreDate jours entre $date1 et $date2\n";
# ou Nombre de semaines et jours
my $NbrSemaine = int( $NombreJoursEntreDate / 7 );
my $NbrJourRestant = $NombreJoursEntreDate % 7;
print "Il y a $NbrSemaine semaine(s) et $NbrJourRestant jour(s) entre $date1 et $date2\n";
Il y a 1271 jours entre 28/05/2006 et 19/11/2009
Il y a 181 semaine(s) et 4 jour(s) entre 28/05/2006 et 19/11/2009
Exemple de script permettant de connaitre :
- la date d'aujourd'hui
- la date dans 6 jours
- la date 48 jours avant aujourd'hui
- la date 2 ans et 6 mois avant aujourd'hui
- la date de demain
#!/usr/bin/perl
use strict;
use warnings;
use Date::Calc qw(:all);
my $usage = <<"FIN_USAGE";
Usage: perl $0 date separateur (Ex : perl $0 12/05/2003 / )
ou perl $0
FIN_USAGE
my ($jour,$mois,$annee) = ();
if ( @ARGV == 0 ) {
($jour,$mois,$annee)= format_date();
}
elsif ( @ARGV == 2 ) {
my ($date, $separateur ) = @ARGV;
chomp $date;
chomp $separateur;
($jour,$mois,$annee) = format_date($date,$separateur);
}
else {
print "$usage\n";
exit;
}
##############################
print "Date : $jour/$mois/$annee\n";
my ($aa,$mm,$jj,$aaa,$mmm,$jjj) = ();
($aa,$mm,$jj)= Add_Delta_Days($annee,$mois,$jour,6);
print "6 jours apres : $jj/$mm/$aa\n";
($aa,$mm,$jj)= Add_Delta_Days($annee,$mois,$jour,-48);
print "48 jours avant : $jj/$mm/$aa\n";
($aa,$mm,$jj)= Add_Delta_YM($annee,$mois,$jour,-2,-6);
print "2 ans et 6 mois avant : $jj/$mm/$aa\n";
($aaa,$mmm,$jjj)= Add_Delta_Days($annee,$mois,$jour,1);
print "jour d'apres : $jjj/$mmm/$aaa\n";
sub format_date {
my ($date, $separateur) = @_;
my ($jour,$mois,$annee) = ();
if (defined $date) {
($jour,$mois,$annee) = split($separateur,$date);
return ($jour,$mois,$annee);
}
else {
($jour,$mois,$annee) =(localtime)[3,4,5];
$mois = $mois + 1;
$annee = $annee + 1900;
# On rajoute 0 si le chiffre est compris entre 1 et 9
foreach ($jour,$mois,$annee) {
s/^(\d)$/0$1/;
}
return ($jour, $mois, $annee);
}
}
Voici une procédure pour générer un timestamp au format DB2 c'est à dire au format : AAAA-MM-JJ HH:mm:ss.xxxxxx où les x représentent les microsecondes.
#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes;
print ObtenirDateFormatDB2(),"\n";
# ------------------------------------------------
# ObtenirDateFormatDB2
# But : Retourne un temps au foramt DB2
# ex : 2009-10-25 16:35:53.123456
# ------------------------------------------------
sub ObtenirDateFormatDB2 {
my ( $epochsecondes, $microsecondes ) = Time::HiRes::gettimeofday;
my ( $seconde, $minute, $heure, $jour, $mois, $annee ) = localtime($epochsecondes);
$mois += 1;
$annee += 1900;
# On rajoute 0 si le nombre est compris entre 1 et 9
foreach ( $seconde, $minute, $heure, $jour, $mois, $annee, $microsecondes ) {
s{^(\d)$}{0$1};
}
return "$annee-$mois-$jour $heure:$minute:$seconde.$microsecondes";
}
Résultat : 2009-10-23 09:37:52.957328
N'hésitez pas à consulter la documentation du module
Time::HiResTime::HiRes.
Les modules les plus utilisés en perl pour la gestion des dates sont DateTimeDateTime,
Date::ManipDate::Manip,
Date::CalcDate::Calc
et POSIXPOSIX.
DateTime a été fondé afin de rassembler l'ensemble des fonctionnalités en rapport
avec le temps auparavant dispersées sur un grand nombre de module et d'offrir une
interface simple et cohérente à ces fonctionnalités, le tout en gardant des bonnes
performances et un poids très raisonnable. D'après tout ce que j'ai pu essayer avec,
c'est un succès ! Je recommande donc à tous ceux qui veulent manipuler de façon
complexe des dates en Perl de se diriger vers cette distribution, ils sont garantis
d'y trouver ce dont ils ont besoin, et de pouvoir travailler simplement et efficacement avec.
Si une grande majorité de Perliste se met à utiliser DateTime, cela facilitera également
les échanges de code entre utilisateurs du forum. Il est également possible que DateTime
se retrouve intégré au CORE, ce qui faciliterait encore son utilisation et sa diffusion.
Vous êtes bien sûr libre d'utiliser n'importe quel module de gestion de dates (après
tout la philosophie de Perl c'est TIMTOWDI : There's more than one way to do it).



