Fil d'Ariane
Mis à jour le vendredi 18 avril 2014
  • 2 heures
  • Facile
Connectez-vous ou inscrivez-vous pour bénéficier de toutes les fonctionnalités de ce cours !

Introduction du cours

Les dates en PHP ont toujours été une question fondamentale pour les développeurs. Comment stocker, gérer, manipuler les dates ou les intervalles de temps.

La plupart des développeurs vous crieront : "le timestamp mon ami !!! le timestamp"...

Mais ils auraient tort. Eh bien oui, le timestamp c'est quoi au juste ? Le timestamp c'est un nombre de secondes écoulées depuis le 1er janvier 1970. Cela signifie qu'il faut toujours se creuser la tête pour passer d'un timestamp à une date et vice-versa.

Oui oui je sais, la fonction date() de php vous retranscrit un timestamp en date php. Mais quid des dates antérieures au 1er janvier 1970 ? Comment stockeriez-vous la date d'anniversaire de vos grands-parents ? Comment calculeriez-vous l'âge de vos grands-parents à partir de leur date de naissance ? Bah vous le feriez mais à grand coup de fonctions lourdes et complexes auxquelles vous ne comprendriez rien et vous mettriez un temps fou à les écrire et encore, si vous le faîtes vous-même... Bref vous perdriez votre temps en recherche...

Alors arrêtez de chercher sur internet ! La réponse est là, le DateTime PHP ! Celui-ci couplé à DateInterval, gérer toutes vos dates deviendra un véritable jeu d'enfants.
Sans plus attendre, entrons dans le vif du sujet !

Une conséquence heureuse de ce tutoriel sera la migration d'une application écrite avec le timestamp vers une application gérée par DateTime. Nous donnerons une partie des codes nécessaires au fur et à mesure de l'avancement du tutoriel. Néanmoins plus amples explications et un détail plus complet de la partie SQL vous est déjà donnée par Taguan dans son tutoriel

DateTime : au delà du timestamp

Passer du timestamp à DateTime

En PHP, pour se servir de date, au tout départ était le timestamp.Le timestamp, c'est le nombre de secondes qui se sont passées depuis le 1er janvier 1970. Ça en fait des secondes croyez moi !Pendant très longtemps tout cela a suffit, le timestamp était à la base de tout dans tous les langages, c'était un standard. On ne s'en plaignait pas trop, le web n'était pas trop développé, gérer les dates en PHP était très courant (pour les forums) mais n'était pas très développé.

Avec le temps, le timestamp est devenu de plus en plus long,
parallèlement, avec le développement du web, l'utilisation des dates est
devenue plus fréquente et plus complexe.

Les gestionnaires de base de données relationnelles tels que MySQL ou Postgres  avaient déjà montré la puissance d'un type de données propre aux dates plutôt que le timestamp en lui même. Notamment, parce que cela permettait de ne conserver que la partie "date" ou la partie "time" (c'est à dire heures, minutes, secondes). Oui mais PHP a mis quelques temps à suivre car de tels outils sont difficiles à créer et que les développeurs de PHP avaient d'autres soucis à l'époque.Le problème c'est que ça obligeait les gens à toujours passer par strtotime pour changer leur date SQL en date php. En plus c'était un vrai casse tête pour mettre les jours en français, en allemand... Alors les développeurs de PHP ont décidé d'inclure dans la version 5.2 l'objet DateTime et quelques autres outils que nous découvrirons dans la suite du tutoriel.

Syntaxe

Pour générer un DateTime et profiter de sa puissance il y a trois méthodes, utilisant soit le constructeur soit createFromFormat :

  • Soit on veut juste la date d'aujourd'hui : <?php $date = new DateTime();

  • Une date à un format standard, par exemple une date stockée dans une base de donnée :

    <?php
    // Le 2ème argument c'est pour être sûr qu'il n'y aura pas 
    //de décalage horaire
    $date = new DateTime($maDateDansMaBDD,new DateTimeZone('Paris/Europe'));
  • Avec un format qui n'est pas standard, par exemple JJ/MM <?php $date = DateTime::createFromFormat('d/m',$maDate);

Pour ce qui est du fuseau horaire, nous verrons cela plus en détail dans une partie suivante.

J'ai un petit problème : je désire souhaiter l'anniversaire de quelqu'un qui est né le 29 février, que se passe-t-il?

Le 29 février est une date particulière. PHP est néanmoins capable de comprendre que comme il n'existe pas tout le temps, si vous demandez 29-02-2013, ça veut juste dire que vous voulez une date équivalente à ce 29 février mais en 2013, à savoir le 1er mars.

Par contre le 29 février est la seule date "particulière". Si vous donnez une date fausse, par exemple le 32 mars ou le 31 avril, il ne comprendra pas et enverra une Exception (POO oblige).

Encore plus fort : les dates relatives

Attaquons-nous à une nouveauté qu'apporte le dateTime : la datation relative. Si l’appellation semble barbare, c'est parce qu'elle cache quelque chose de très puissant que les timestamp ne vous permettent pas de gérer facilement. Imaginez-vous que vous désirez connaître la date de fin d'un évènement.

Vous savez quand a commencé l'évènement, et combien de temps il dure. Une solution semble donc de créer un DateTime puis de dire "ajoute-moi la durée que je désire". Seulement cela signifie des lignes de codes supplémentaires et puis cela n'aurait pas grand intérêt. Une autre solution est de dire "je veux la date qui est x temps après la date de départ".

L'intérêt, c'est qu'en faisant ça, vous n'écrivez qu'une seule ligne de code et que cette ligne a un sens précis et est parfaitement lisible. C'est très bien, cela crée un code propre et de qualité.

Maintenant, il faut savoir comment faire pour dire cela à PHP. Tout se passe dans le constructeur de DateTime (ou dans la fonction date_create). Vous allez tout d'abord écrire la date de départ (disons le 14-02-2012) puis vous allez écrire, en anglais, la durée. Cela donne par exemple :

<?php $date = new DateTime('14-02-2012 +1 day');

Encore plus fort, vous pouvez utiliser des mots clefs comme "first", "last","next". Ces mots-clefs permettent d'atteindre une date dont on ne connait qu'un minimum d'informations : je sais que c'est
samedi prochain, que c'est le premier mercredi du mois de juillet. Par exemple je sais que c'est samedi prochain, que c'est le premier mercredi du mois de juillet... Par exemple, vous désirez prévoir quand sera le prochain essai de la sirène des pompiers (en France, le premier mercredi de chaque mois). Il suffit de l'écrire en anglais "first Wednesday of next month".

DateTimezone ou la gestion du fuseau horaire

Un des grands problèmes lorsqu'on veut gérer les heures, c'est que tout le monde sur terre n'est pas à la même heure. Entre fuseau horaire et heures d'été vous aurez vite fait de tomber dans des problèmes difficilement solubles.

Vous n'êtes pas sans savoir que sur notre bonne vieille Terre, il y a 24 fuseaux horaires. Ceux-ci allant de -12 à +12 en passant par Greenwich. Afin de vous assurer que chacun de vos utilisateurs visualise votre site à sa propre heure, vous devez régler le fuseau horaire de votre site ce qu'on appelle en php le Timezone.

Il y a différentes façons de gérer ce Timezone. Soit vous définissez un Timezone fixe pour toute votre application mais seul les utilisateurs de votre fuseau auront la bonne heure, les autres verront un décalage horaire.

Il faudra donc définir votre fuseau horaire de façon dynamique et vous pourrez le faire grâce à DateTimeZone.

Cet objet vous permettra de paramétrer le fuseau horaire pour chacun de vos DateTime afin que chaque utilisateur voit les dates sans aucun décalage horaire. Avouez tout de même que c'est plus agréable pour eux ?

DateTimeZone étant un objet, il renvoie des exceptions en cas d'erreur de fuseau. On peut donc le placer dans des blocs try/catch.

Sans plus tarder, voici comment on construit un fuseau horaire.

<?php 
try{
    $tz = new DateTimeZone($fuseau);
}
catch(Exception $e){
    exit($e->getMessage());
}

Ici $fuseau représente une chaine de caractère qui va déterminer le fuseau horaire justement.

Cette chaîne de caractère ne doit pas ressembler à n'importe quoi. Par ailleurs, il existe des constantes pré-existantes pour choisir son fuseau, par exemple DateTimeZone::AFRICA, DateTimeZone::AMERICA, etc.

Mais bon ce n'est pas assez précis et on ne sait pas vraiment quel fuseau on a choisit. Il y a donc toute une liste des fuseaux horaires.

Revenons maintenant à notre DateTime. Jusqu'à maintenant vous aviez défini des DateTime sans vous soucier du fuseau horaire. Maintenant que nous savons que c'est possible de le choisir pour chacune de nos dates, nous allons marier les deux éléments pour obtenir des dates encore plus justes

<?php 
$tz = new DateTimeZone('Europe/Paris');
$date = new DateTime('2012-03-09 17:26:30', $tz);//utilisera le bon fuseau horaire
$tzLondres = new DateTimeZone('Europe/London');
$date->setTimezone($tzLondres);//et l'heure est modifiée en fonction :-)

Et voilà, notre DateTime est défini au 9 mars 2012 à 17h26min30sec sur le fuseau de Europe/Paris.

Cela veut dire que notre DateTime est à +2 par rapport à Greenwich (en été, +1 en hiver) !

Ne pas donner le fuseau lors de la création de votre DateTime signifierait que celui-ci va utiliser le fuseau par défaut, celui du serveur. Et en règle générale c'est rarement celui de Paris. Donc vous pouvez préciser le fuseau horaire à chaque fois en donnant le second paramètre.

Cela vous obligera par contre à préciser le premier. C'est pourquoi, si vous désirez dire simplement "aujourd'hui", vous devrez mettre en premier paramètre "now". Pour éviter de préciser tout le temps le fuseau horaire si vous avez décider d'avoir un fuseau fixe, vous pouvez en préciser un par défaut vous-même.

Pour cela deux situations sont possibles :

  • Soit vous avez accès au php.ini et vous changez la propriété default_timezone avec le fuseau horaire de votre choix.Soit vous n'y avez pas accès et vous utilisez la fonction <?php date_default_timezone_set();

  • Si en revanche vous avez décidé de faire plaisir à tous vos utilisateurs quelque soit le pays d'où il se connecte, vous devez donc gérer tous les fuseaux horaires !

Le meilleur moyen donc est de créer le timezone dans une page spécifique de votre application pour que vous n'ayez plus qu'à l'utiliser.

DateInterval pour gérer des intervalles de temps

Intervalle entre deux dates : DateInterval

Il vous est peut-être déjà arrivé d'avoir besoin de gérer un intervalle de temps. Que ce soit pour gérer la durée de construction d'un bâtiment ou de création d'unité dans un jeu de type Ogame ou simplement pour vérifier depuis combien de temps l'utilisateur ne s'est pas connecté ou bien encore pour savoir si l'utilisateur a bien laissé passer 24h avant de revoter.

Toutes ces petites choses peuvent être stockées très facilement dans un DateInterval. L'avantage de cette solution, c'est que DateInterval se marie parfaitement avec un DateTime. Vous l'aurez compris, DateInterval nous servira à déterminer l'espace de temps que l'on souhaitera ajouter ou soustraire à nos DateTime (mais nous le verrons dans la partie suivante). Pour l'heure, apprenons déjà à créer nos DateInterval.

DateInterval permet donc de définir un intervalle de temps. Il a très peu de méthodes et est donc très simple d'utilisation.

  • DateInterval:: __construct     : pour construire l'objet à partir d'un format spécifique

  • DateInterval:: createFromDateString : pour construire l'objet à partir d'un string (en)

  • DateInterval:: format  : pour formater l'intervalle à l'affichage

Le format spécifique d'un DateInterval est stricte mais facile à comprendre. Pour toute la partie date, on commence le format par un P en majuscule et pour toute la partie horaire on commence par un T majuscule. Le reste du format étant très intuitif, il suffit de précéder la lettre du format par un nombre. Voici la liste des formats acceptés :

Type de la période

Format

Un nombre d'années

Y

Un nombre de mois

M

Un nombre de jours

D (incompatible avec W)

Un nombre d'heures

H

Un nombre de minutes

M

Un nombre de secondes

S

Un nombre de semaines

W (incompatible avec D)

 

 

Pour mieux comprendre ce tableau, voici une petite application :

<?php
// On crée un intervalle très complet
$intervalle = new DateInterval('P1Y2W6MT2H35M54S');
/*
 * Ici, on a définit un intervalle de 1 an 2 semaines 6 mois 2 heures 35 minutes et 54 secondes
 * J'ai mis toutes les possibilités mais on peut très bien ne mettre que la partie horaire
 * ou que la partie date ou juste le mois, juste l'année, juste le jour, etc etc
 * Toutes les combinaisons sont possibles sauf l'association des semaines et des jours
 * puisque semaines sera convertir en jours. Du moment que vous n'oubliez pas le P et/ou le T
 * pour séparer la date de l'heure, tout ira bien
 */

$intervalle = new DateInterval('P15D'); // Intervalle de 15 jours
?>

L'alliance des dates et des intervalles

Les opérations sur les DateTime

Quand on manipule des dates, il peut être intéressant de faire certains types d'opérations très facilement.

Par exemple, je veux savoir si cela fait moins d'un mois que l'article a été posté, ou bien je veux savoir s'il reste du temps avant l'expiration de la promotion que je suis en train de faire sur un produit... Pour cela on va devoir jongler avec les objets DateTime et DateInterval qui possèdent des méthodes qui permettent d'additionner ou de soustraire l'un à l'autre ou inversement.

Intervalle entre deux dates

Si je désire connaître la durée qui s'est passée entre deux dates il faudra que j'utilise la fonction diff de DateTime et qui renvoie un DateInterval.

Un exemple pratique serait de prendre la durée de construction d'un bâtiment dans les jeux par navigateur.

Je connais la date de lancement, et je connais le temps (l'intervalle donc) qu'il faut pour construire le bâtiment. Pour savoir si le bâtiment est construit, il suffit que je compare l'intervalle entre aujourd'hui et la date de lancement avec l'intervalle qui correspond au temps de fabrication.

<?php
// Supposons que j'ai un tableau de données issues de ma base de données contenu dans la variable $data
$aujourdhui = new DateTime();
$lancement  = new DateTime($data['date_lancement']);
// On obtient la différence ainsi, 
//diff fait le calcul et retourne le DateInterval donc on peut l'afficher avec format
echo $aujourdhui->diff($lancement)->format('Lancé il y a : %d jours');

Ajouter/soustraire une période à une date

Si on veut savoir la date qu'il sera, ou qu'il était une fois qu'on a ajouté ou retiré un certain intervalle. On se servira des fonctions add et sub pour faire cela.

Elles prennent toutes les deux en argument l'intervalle qu'on désire ajouter ou retirer et vont modifier notre DateTime directement. Reprenons notre exemple de tout à l'heure mais avec nos nouvelles fonctions :

<?php
$aujourdhui = new DateTime();
$lancement  = new DateTime('14-02-2012');
$temps_construction = new DateInterval('P15D');
// Il faut 15 jours pour construire le bâtiment
if($aujourdhui->sub($temps_construction) > $lancement) 
// Si (la date du jour - 15 jours) est supérieure à la date de lancement
{     
    echo 'Bâtiment construit !';
}
else
{
    echo 'Veuillez attendre la fin de la construction';
}

TP : Compte à rebour

Enoncé

Comme nous l'avons dit, les DateInterval peuvent être très utiles quand on parle de compte à rebour. Nous désirons ne pas être en retard à un événement sur le web. Alors nous voulons savoir combien de temps il reste avant le début de cet événement.

Ce dernier aura lieu Demain à 7h du matin heure de Paris.

A vos codes !

Correction

<?php
$DateEvenement = new DateTime("tomorrow +7h",new DateTimezone("Europe/Paris"));//demain, sept heures
$DateNow = new DateTime("now",new DateTimezone("Europe/Paris"));//aujourd'hui
$TempsRestant = $DateNow->diff($DateEvenement);
printf("Il reste %s jour %s heures %s minutes %s secondes",
$TempsRestant->d, $TempsRestant->h,$TempsRestant->i,$TempsRestant->s);

Comparaison de deux dates

Plus récent, plus ancien

Voici un autre avantage de passer des timestamp à DateTime, la manière de comparer les dates ! Imaginez vous que vous ne connaissiez que la version "chaîne de caractères" de la date, par exemple "14/02/2012". Si vous voulez la comparer, sans utiliser les DateTime vous seriez obligé de passer par la fonction strtotime deux fois, de comparer les timestamp puis enfin d'afficher le résultat. Vous avouerez que c'est lourd. Surtout que maintenant vous savez que les timestamps ne sont valides que sur la période allant du 01/01/1970 au 19/01/2038 ;)

Alors qu'avec DateTime on compare deux dates de la même manière qu'un entier, à une toute petite exception près. Imaginons que nous voulions vérifier que le "14/02/2012" est bien antérieur au "12/03/2013".

<?php
// avec strtotime :-(
$date1= strtotime("14/02/2012");
$date2= strtotime("12/03/2013");
if( $date1 < $date2 ){   
    echo date('d/m/Y',$date1);
}
// avec DateTime :-)
$date1 = new DateTime("14/02/2012");
$date2 = new DateTime("12/03/2013");
if( $date1 < $date2 ){
    echo $date2->format('d/m/Y');
}

Les deux codes qui ont été donnés sont équivalents sauf que cette fois-ci vous comparez directement les dates, c'est plus intuitif et donc plus lisible.

Le cas particulier : vérifier que deux dates sont égales

Quoi ? c'est un cas particulier ? je pourrais pas écrire $date1 == $date2 ?

En fait, si, mais attention. Vous ne pourrez l'écrire que si vous êtes sûr(e) que vous êtes en présence de deux DateTime. Si ce n'est pas le cas il faut recourir à une astuce.

En effet PHP est un langage faiblement typé. Ça veut dire qu'on ne connait pas le type d'une variable auquel on a à faire tant que la variable n'a pas été testée. Cela signifie aussi que PHP, pour vérifier si deux contenus sont égaux, va vouloir tout convertir dans un type plus "général".Du coup, j'ai fait le test pour vous, <?php var_dump(new DateTime()==new ArrayObject);//renvoie true!!!

Heureusement, comme je vous l'ai dit, il y a une astuce, qui porte le nom de "triple égal".

Re-testons le code précédent en remplaçant "==" par "===" <?php var_dump(new DateTime()===new ArrayObject);//renvoie false!!!.

Ouf... En fait le "===" vérifie avant tout qu'on a le même type de données de chaque côté.Donc voila ce qu'il faut retenir : pour vérifier que deux dates sont égales, on utilise "===" au lieu de "==".

Une autre solution si le triple égal vous fait peur serait d'utiliser une vérification du type avec instanceof ou avec le typehint.

Allons plus loin : les formats de date et leur internationalisation

La fonction format

Pour afficher les dates comme on le désire, on peut utiliser la fonction format. Cette dernière a un large panel de possibilités et est très simple d'utilisation. Elle se base sur le modèle de la fonction date() qu'on utilisait au temps des timestamp.

L'utiliser avec des styles pré-définis

Avant de détailler comment afficher une date de manière totalement personnalisée, il est toujours sympatique de pouvoir afficher des dates dans des formats très connus. En effet vous serez souvent confronté à des situations dans lesquelles il faut enregistrer une date avec un format spécial. C'est le cas des bases de données, des flux RSS/atom, de la balise html 5<time>...

Imaginez que vous soyez obligés de retenir tous ces formats, parfois complexes. Ca relèverait de l'impossible, et de l'inutile soit dit en passant.Alors php a pensé à vous et possède un catalogue complet de constantes pour afficher une date.

Par exemple, si je veux afficher la date du jour dans un attribut de la balise <time>, je vais écrire <?php $date->format(DateTime::W3C);. Vous voyez qu'il faut utiliser l'opérateur de portée "::" parce que ce sont des constantes de classe. En fait il faut savoir que chacune des constantes de classe de DateTime possède un alias qui a juste le préfixe DATE_.

L'utiliser avec des styles personnalisés

Vous pouvez bien évidemment personnaliser totalement le format des dates. Pour cela php se réserve des caractères tels que d m Y qui signifie pour lui "JJ MM AAAA". Cette fois-ci je ne ferais pas la liste complète des caractères spéciaux, il y en a trop et ça n'aurait aucun intérêt. Vous pourrez retrouver ces derniers sur le manuel php.

Je voulais juste vous préciser certaines choses. Si vous voulez écrire des mots dans votre date (par exemple le JJ/MM/AAAA à 18h50minutes) il faudra dire à PHP "mon "h" et le mot "minutes" sont des mots que tu ne dois pas interpréter. Pour cela on met un antislash (\) devant les lettres qui dérangent ce qui donnerait :

<?php
$date = new DateTime('14-02-2012 15:32:32');
$date ->format('d/m/Y à H\hi\m\i\n\u\t\e\s');

Un autre exemple pourrait être l'insertion d'une date dans votre base de données :

Comme les SGBDR (MySQL entre autres) ont un format spécial pour les dates, je vous propose de créer des constantes:Ce format c'est AAAA-MM-JJ HH:MM:SS pour les données de type DateTime et AAAA-MM-JJ pour les données de type Date.

<?php
define('MYSQL_DATETIME_FORMAT','Y-m-d H:i:s');
define('MYSQL_DATE_FORMAT','Y-m-d');
try{    // On effectue la connexion si nécessaire    
    $db=new PDO('mysql:localhost;db=madb','root','');    
    $db->setAttribute(PDO::ATTR_ERR_MODE,PDO::ERR_MODE_EXCEPTION);
    // On crée un DateTime PHP  
    $date =new DateTime('14/02/12');    
    $req = $db->prepare('INSERT INTO tableName(col_date_time) VALUES(:dt)');    
    $req->bindValue('dt',$date->format(MYSQL_DATETIME_FORMAT));    
    $req->execute();   
}catch(PDOException $e){
    exit($e->getMessage());
}

Ecrire les jours, les mois dans toutes les langues du monde

Imaginez vous une situation :

Vous désirez faire en sorte que votre site, disons un site de vente, soit disponible partout dans le monde, dans quatre langues : anglais, français, allemand, espagnol.

Vous désirez afficher quelque part sur votre site, la date limite de la promotion qui est en cours. Les anglais aiment bien dire "Wednesday, 14th February", les français, "Mercredi 14 février", les espagnols "Miércoles 14 de Febrero"... Tous ont non seulement des noms pour les jours et les mois totalement différents, mais aussi une manière différente de les afficher.

Alors, vous vous dites "je prends mon courage à deux mains, je traduis tous les jours, tous les mois et ensuite je fais des if partout". Oui, ça marche, mais ce genre de réflexe est à éviter : non seulement vous perdez du temps, mais dès que vous désirez ajouter une nouvelle langue, ça devient plus difficile à maintenir. En plus ça alourdit inutilement vos fichiers PHP.

Alors on a créé quelque chose pour vous : IntlDateFormatter. La partie "Intl" veut dire "internationalisation". C'est une extension de PHP très pratique qui permet de formater à peu près tout ce qui vous passe par la tête (des dates, des nombres...) en accord avec la zone du monde qui est ciblée.Cet objet est apparu en même temps que DateTime, donc c'est parfait pour nous.

Cet objet fonctionne d'une manière un peu "spéciale", on ne rencontre pas cette manière de faire tous les jours, en fait il correspond au patron de conception "Strategy" : Cela se passe en plusieurs étapes :

  • On dit "je veux pouvoir afficher une date en français, sans afficher l'heure"

  • PHP crée l'objet qui est capable de faire ça

  • Vous demandez à cet objet "voici une date à afficher : 14/02/2012"

  • PHP vous envoie "14 février 2012"

Maintenant qu'on sait comment ça marche, on va pouvoir créer notre objet qui transformera nos dates.

<?php
$formatter = new IntlDateFormatter('fr_FR',IntlDateFormatter::LONG,
                IntlDateFormatter::NONE,
                'Europe/Paris',
                IntlDateFormatter::GREGORIAN );
$date =new DateTime('14-02-2012');
echo $formatter->format($date);//affiche 14 février 2012

Revenons un peu sur les paramètres:Le premier paramètre, 'fr_FR' correspond au pays et à la langue désirée. Nous voulons du français de France, donc on choisit 'fr_FR', les américains utilisent 'en_US'...Le second paramètre, c'est le niveau de précision pour l'affichage du jour du mois et de l'année,le troisième pour l'affichage de l'heure, il existe plusieurs niveaux :

  • NONE : n'affiche rien

  • SHORT: il n'affiche que le minimum (14/02/2012)

  • MEDIUM: il affiche les mois en abrégé, et seulement le numéro du jour

  • LONG : il affiche les jours, les mois en entier (dans la langue choisie)

  • FULL: il affiche les jours avec le nom du jour et le numéro, les mois en entier (dans la langue choisie) mais aussi le décalage GMT ou le type de date (CEST,UTC...) quand il s'agit du paramètre time

Le quatrième paramètre correspond au fuseau horaire (timezone en anglais). Ici nous choisissons l'heure de Paris. Le cinquième correspond au type de calendrier utilisé. Pour des raisons historiques nous utilisons, comme beaucoup de monde le calendrier grégorien donc choisissons celui là.

Utiliser les formats par défaut vous permet une chose : internationaliser l'ordre des jours/mois/années...), permettant ainsi de coller aux standards de chaque pays.

Si cela ne vous intéresse pas et que vous désirez juste certaines parties de la date, par exemple uniquement le mois ou uniquement le jour, il faudra ajouter une étape intermédiaire :

<?php
$dayFormatter = new IntlDateFormatter('fr_FR',IntlDateFormatter::FULL
                NULL,
                'Europe/Paris',
                IntlDateFormatter::GREGORIAN );
$dayFormatter->setPattern("EE");
$date =new DateTime('14-02-2012');
echo $dayFormatter->format($date);//affiche mardi

Il faut désigner un format un peu différent de ce dont vous avez l'habitude, il est décrit dans ce tableau.

TP : mise en place d'un calendrier dans toutes les langues

Le TP qui suit aura pour but de mettre en place un calendrier à case (style calendrier du facteur) mais qui se traduit automatiquement en la langue demandée.

Le principe est de mettre en avant les jours tels que le dimanche, le jour courant etc.

Le passage au mois suivant se fait via une variable GET.

Captures

Afin de vous donner une idée plus précise, voici ce qu'un exemple basique peut donner, par exemple :

Aperçu lors du mois actuel
Aperçu lors du mois actuel
Aperçu sur un autre mois.
Aperçu sur un autre mois.

Correction

<html>
<head>
    <meta charset="UTF-8"/>
	<title>calendrier</title>
	
	<style type="text/css">
	table th{
		padding : 5px;
		border: 2px groove black;
		width: 75px;
		height: 25px;
	}
	table td{
		padding : 5px;
		text-align : center;
	}
	#today{
		color: blue;
	}
	.dimanche{
		color:red;
	}
	</style>
</head>
<body>
<?php
error_reporting(E_ALL);

define("GET_DATE_FORMAT","Y-m-d");
if(isset($_GET['firstday'])){
	//on vérifie le format de l'entrée GET : n'oubliez pas qu'il ne faut jamais faire confiance aux entrées utilisateur!
	try{
		
		$firstDay = DateTime::createFromFormat(GET_DATE_FORMAT,$_GET['firstday']);//si la donnée est au mauvais format, une exception est lancée
		
		$firstDay->modify("first day of this month");//pour être vraiment sûr que les données sont cohérentes
	}catch(Excpetion $e){
		
		$firstDay = new DateTime("first day of this month");
	}
}else{
	$firstDay = new DateTime("first day of this month");
}



$formatter_semaine = new IntlDateFormatter("fr_FR",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'Europe/Paris',
                IntlDateFormatter::GREGORIAN,"EEEE" );
$formatter_semaine->setPattern("EEEE");
$formatter_mois = new IntlDateFormatter("fr_FR",IntlDateFormatter::FULL,IntlDateFormatter::NONE,'Europe/Paris',
                IntlDateFormatter::GREGORIAN,"MMMM" );
$formatter_mois->setPattern("MMMM");
?>
<h1><?php echo $formatter_mois->format($firstDay);?></h1>
<?php
$lastDay = clone $firstDay;
$lastDay->modify("last day of this month");// le dernier jour du mois
$offset_depart = $firstDay->format("w");// le nombre de jour qu'il faut passer au début du calendrier
$offset_fin = 6 - $lastDay->format("w");// le nombre de jour qu'il reste dans la dernière semaine du calendrier
$firstDay->modify("-$offset_depart days" );
$lastDay->modify("+$offset_fin days");
$dateInitWeek = clone $firstDay;
$endInitWeek = clone $dateInitWeek;
$endInitWeek->modify("+7 days");
$intervalInitWeek = new DateInterval("P1DT0S");
$aujourdhui = new DateTime("today");
?>
<table>
	<tbody>
		<tr>
			<?php 
			foreach(new DatePeriod($dateInitWeek,$intervalInitWeek,$endInitWeek) as $jour){
				 if($jour->format("w")==0){
					echo "<th class=\"dimanche\">",$formatter_semaine->format($jour),"</th>";
				}else{
					echo "<th>",$formatter_semaine->format($jour),"</th>";
				}
				
			}?>
		</tr>

<?php

$lastDay->modify("+1 day");//c'est une astuce pour utiliser DatePeriod 
//qui ne sait pas prendre en compte le dernier jour si on ne fait pas ça
$intervale_iteration = new DateInterval("P1DT0S");
$iterateur = new DatePeriod($firstDay,$intervale_iteration,$lastDay);
$i = 0;
foreach($iterateur as $jour){
	if($i == 0){
		echo "<tr>";
	}
	if($jour == $aujourdhui){
					echo "<td id=\"today\">",$jour->format("d"),"</td>";
				}else if($jour->format("w")==0){
					echo "<td class=\"dimanche\">",$jour->format("d"),"</td>";
				}else{
					echo "<td>",$jour->format("d"),"</td>";
				}
	$i++;
	$i %=7;
	if($i == 0){
		echo "<tr/>";
	}
}
?>
	</tbody>
</table>

</body>
</html>
Exemple de certificat de réussite
Exemple de certificat de réussite