6.Le langage PHP

6.10.Les dates

6.10.2.Les fonctions natives PHP

6.10.2.1.Déterminer la date et heure courante

Déterminer la date et l'heure courante passe généralement par un appel à la fonction time(). Pour autant, cette dernière est probablement la fonction qui parle le moins à nous autres humains puisqu'elle retourne le nombre de secondes écoulées depuis le 1er Janvier 1970 à 00:00:00 UTC (Epoch). Elle est cependant très souvent utilisée lors des manipulations de dates et a l'avantage de ne pas être dépendante du fuseau horaire ni des changements d'heures d'été et d'hiver.
<?php
echo 'Lorsque cette page a été générée, il s\'était écoulé '. time() . ' secondes'."\n".
     'depuis le 1er Janvier 1970 00:00 (GMT)';
?>
Télécharger time.php

Ce qui donne:
Lorsque cette page a été générée, il s'était écoulé 1711373837 secondes
depuis le 1er Janvier 1970 00:00 (GMT)

6.10.2.2.Formatter (i.e. afficher/retourner) une date

6.10.2.2.1.Avec date()

Pour retourner une date, sous une forme plus lisible, à partir du nombre de secondes depuis Epoch (le 1er Janvier 1970 à 00:00:00 UTC) vous pouvez faire appel à la fonction date(). Cette fonction accepte 2 paramètres, le premier étant le format sous lequel vous souhaitez retourner cette date et le second le nombre de secondes depuis Epoch.
<?php
echo 'Cette page a été générée le '. date('d/m/Y à H:i:s', time()).' (heure locale)';
?>
Télécharger date.php

Ce qui donne:
Cette page a été générée le 25/03/2024 à 14:37:17 (heure locale)
Il se trouve, que le second paramètre est optionnel. Quand celui-ci est omis, il prend par défaut la valeur de time(). L'exemple précédent est donc équivalent à
<?php
echo 'Cette page a été générée le '. date('d/m/Y à H:i:s').' (heure locale)';
?>
date() retourne la date dans le fuseau horaire défini au niveau du script PHP (par défaut, celui du serveur).
Le format de la date peut être défini par concaténation de caractères "libres" ('/' et ' à ' dans notre exemple) et de mots clés ('d' pour le jour, 'm' pour le mois, 'Y' pour l'année, 'H' pour l'heure, 'i' pour les minutes et 's' pour les secondes, dans notre exemple).
Si vous souhaitez utiliser des caractères (pour le caractère qu'il représente) qui se trouvent être des "mots" clés vous devez les faire précéder du caractère d'échappement '\' (anti-slash). Comme dans l'exemple suivant où le caractère 'h' a été utilisé comme raccourci du mot 'heure' alors que ce caractère est un "mot" clé pour indiquer l'heure au format 12h.
<?php
echo 'Cette page a été générée le '. date('d/m/Y à H\hi').' (heure locale)';
?>
Télécharger date_maintenant_2.php

Ce qui donne:
Cette page a été générée le 25/03/2024 à 14h37 (heure locale)
Sans la présence de l'anti-slash, le résultat aurait été
Cette page a été générée le 25/03/2024 à 140237 (heure locale)
L'ensemble des mots clés vous sont présentés dans un paragraphe, un peu plus loin.
Si vous préférez retourner la date GMT vous pouvez faire appel à la fonction gmdate() qui a exactement la même interface (même paramètres).
rem
  • les fonctions date() et gmdate() prenant pour paramètre un entier, les valeurs limites sont comprises entre PHP_INT_MIN (soit ~PHP_INT_MAX pour PHP < 7.0) et PHP_INT_MAX. Par conséquent:
    • sur un système 64 bits, il est normalement possible de manipuler des dates allant de -292277022657-01-27 08:29:52 à 292277026596-12-04 15:30:07 (ce qui semble largement suffisant)
    • sur un système 32 bits, il est normalement possible de manipuler des dates allant de 1901-12-13 20:45:52 à 2038-01-19 03:14:07 (seulement)

6.10.2.2.2.Avec strftime()

La fonction date() est très pratique et compacte mais elle a tout de même une limite, elle ne permet pas l'affichage de dates sous forme de texte (ex: mercredi 12 juillet) dans une langue autre que l'anglais.
Vous serez donc peut-être aménés à privilégier l'emploi de la fonction strftime(). Son utilisation est similaire à date() avec comme premier paramètre une chaîne de caractères précisant le format sous lequel nous souhaitons que la date soit retournée et en second paramètre le nombre de secondes depuis Epoch (si ce paramètre est omis c'est la date et heure courante qui est retournée). En revanche, les mots clés permettant de préciser le format de date sont différents (ce serait trop simple sinon...). Ceux-ci sont décrit dans un tableau au chapitre suivant. Dans notre exemple, nous utilisons %A pour le jour de la semaine en toutes lettres, %d pour le jour du mois, %B pour l'année, %H pourl'heure, %M pour les minutes et enfin %S pour les secondes.
<?php
echo 'Cette page a été générée le '. strftime('%A %d %B %Y à %H:%M:%S').' (heure locale)';
?>
Ah oui... j'ai failli oublier. Par défaut, la langue utilisée par votre script PHP pourrait bien être l'anglais. Pour pouvoir avoir un affichage dans une langue différente vous devez préciser ce que nous appelons une "locale" pour les données associées au temps (LC_TIME). Cette "locale" est à choisir parmi celles définies sur votre machine. La sélection de la "locale" se fait via la fonction PHP setLocale(). Et comme dans notre environnement (linux) nous avons la locale fr_FR.utf8, pour un affichage en Français nous ferons appel à setLocale(LC_TIME, 'fr_FR.utf8'); avant l'appel à strftime().
<?php
setLocale(LC_TIME, 'fr_FR.utf8');
echo 'Cette page a été générée le '. strftime('%A %d %B %Y à %H:%M:%S').' (heure locale)';
?>
Cette page a été générée le lundi 25 mars 2024 à 14:37:17 (heure locale)
Pour un environnement windows (déconseillé), la locale sera plutôt "fra" (au lieu de "fr_FR" ou "fr_FR.utf8").
Si vous préférez retourner la date GMT vous pouvez faire appel à la fonction gmstrftime() qui a exactement la même interface (même paramètres).
rem
  • Constaté sur un système Linux 64 bits, strftime() permet l'utilisation de dates comprises entre -2147483648-01-01 00:00:00 et 2147483647-12-31 23:59:59 (donc une plage de dates inférieure à celle de gmdate() mais largement suffisante)
  • Sous linux, vous pouvez prendre connaissance des locales installées grâce à la commande locale -a
warning
  • On prendra bien soin d'utiliser la constante LC_TIME (sans guillemet ni appostrophe) et non pas la chaîne de caractères 'LC_TIME', l'usage des chaînes de caractères pour préciser la catégorie de locale n'étant plus supporté depuis PHP 7.0
  • Sous windows, les scripts PHP sont généralement executés dans un environnement multi-threadé et non pas multi-process. L'utilisation de setLocale() est par conséquent déconseillé dans cet environnement

6.10.2.2.3.Mots clés pour date() et strftime()

Description date() strftime() Exemple
Jour
Jour de la semaine sous forme de texte (en Anglais pour date(), dans la locale pour strftime()). l %A "Thursday" ou "jeudi"
Jour de la semaine sous forme de texte limité à 3 lettres, éventuellement suivies d'un point (en anglais pour date(), dans la locale pour strftime()). D %a "Thu" ou "jeu."
Numéro du jour de la semaine (ISO-8601). Lundi=1, Dimanche=7 N %u
Numéro du jour de la semaine avec Dimanche=0, Samedi=6 w %w
Jour du mois (sur 1 ou 2 chiffres) j
Jour du mois sur 2 caractères (le nombre étant précédé d'un espace si nécessaire) %e
Jour du mois sur 2 chiffres (le nombre étant précédé d'un zéro si nécessaire) d %d
Jour de l'année avec 1er jour = 0 z
Jour de l'année avec 1er jour = 1 et sur 3 chiffres (le nombre étant précédé de zéros si nécessaire). %j
Mois
Mois de l'année sous forme de texte (en Anglais pour date(), dans la locale pour strftime()). F %B "June" ou "juin"
Mois de l'année sous forme de texte raccourci (en Anglais et limité à 3 lettres pour date(), dans la locale pour strftime() et limité à 3 lettres en Anglais, à 5 caractères en Français). M %b ou %h "Jun" (en) ou "mai", "juin", "juil." (fr)
Mois de l'année (sur 1 ou 2 chiffres) n
Mois de l'année sur 2 chiffres (le nombre étant précédé d'un zéro si nécessaire) m %m
Année
Année sur 2 chiffres y "97" (pour 1897, 1997, 2097, etc.), "05" (pour 1905, 2005, etc.)
Année (sur 4 chiffres) Y %Y "2030", "0101"
Année ISO 8601 sur 2 chiffres (basé sur la semaine). Non disponible sous windows %g "09" pour 29/12/2008, "16" pour 01/01/2017
Année ISO 8601 (basé sur la semaine). Non disponible sous windows Y %G "2009" pour 29/12/2008, "2016" pour 01/01/2017, "101"
Heure
Heure sur 24h (sur 1 ou 2 chiffres) g
Heure sur 24h sur 2 caractères (le nombre étant précédé d'un espace si nécessaire) %k
Heure sur 24h sur 2 chiffres (le nombre étant précédé d'un zéro si nécessaire) H %H
Heure sur 12h (sur 1 ou 2 chiffres). Ex "3" au lieu de "15". g
Heure sur 12h sur 2 caractères (le nombre étant précédé d'un espace si nécessaire) %l " 3" (au lieu de "15")
Heure sur 12h sur 2 chiffres (le nombre étant précédé d'un zéro si nécessaire) h %I "03" (au lieu de "15")
Fraction de la journée (Avant midi = Anté méridien [AM], Après midi = Post méridien [PM]) en majuscules. Attention retourne une chaîne vide, avec strftime() si l'option n'est pas supportée dans la locale comme en Français. a %P
Fraction de la journée (Avant midi = Anté méridien [am], Après midi = Post méridien [pm]) en minuscules. Attention retourne une chaîne vide, avec strftime() si l'option n'est pas supportée dans la locale comme en Français. A %p
Minutes sur 2 chiffres (le nombre étant précédé d'un zéro si nécessaire) i %M "03" (au lieu de "3")
Secondes sur 2 chiffres (le nombre étant précédé d'un zéro si nécessaire) s %S "03" (au lieu de "3")
Fuseau horaire et heure d'été
Fuseau horaire e "GMT", "Europe/Paris"
Fuseau horaire abrégé avec notion d'heure d'été T %Z "CET" (heure hiver en Europe Centrale), "CEST" (heure d'été en Europe Centrale)
0 = heure hiver, 1 = heure été I
Ecart par rapport à l'heure GMT (cumul du décalage par le fuseau horaire + heure été) O %z +0100
Ecart par rapport à l'heure GMT avec 2 points entre heures et minutes (cumul du décalage par le fuseau horaire + heure été) P +01:00
Date complète
Date "complète" au format ISO 8601 c 2021-01-16T23:10:00+01:00
Informations complémentaires
Nombre de jours dans le mois t
1 pour les années bissextiles, 0 sinon L

6.10.2.3.Convertir une date quelconque en nombre de secondes depuis Epoch

6.10.2.3.1.Introduction

Comme nous l'avons vu dans le paragraphe précédent, à partir du moment où nous disposons d'une date en nombre de secondes depuis Epoch, nous sommes capables de la formatter comme bon nous semble grâce aux fonctions date() et strftime(). En conséquence, si l'on souhaite modifier le format d'affichage d'une date (ou réaliser d'autres opérations), l'enjeu va être, d'être capable de convertir une date que l'on récupère sous un forme "quelconque" en un nombre de secondes depuis Epoch.
Quand je parle d'une date au format quelconque, j'exagère sans doute un peu. Des formats de date, il n'y en a pas cent non plus. Pour une date saisie par un utilisateur sur un site Français la date sera probablement au format jour/mois/année (ex "25/12/2020") éventuellement suivi d'une heure au format heure:minute, avec ou sans précision de secondes. Pour une date récupérée d'une base de données (disons MySQL), elle sera sans doute plus au format année-mois-jour (ex:2020-12-25) accompagnée ou non d'une heure au format heure:minutes:secondes.
Pour ce type de dates, vous pouvez envisager:
  • de faire appel à la magie d'une fonction de type strToTime() quand cela est possible
  • de découper (parser) la chaîne de caractères afin d'en extraire les différents champs: année, jour, mois, heure, minute, seconde, soit à la main soit via une fonction de type date_parse_from_format() ou strptime() puis faire appel à une fonction de type mktime()

6.10.2.3.2.En utilisant strToTime()

La fonction strToTime() propose d'analyser la chaîne de caractères représentant une date pour la retourner en nombre de secondes depuis Epoch. Cela fonctionne particulièrement bien avec des dates au format annee-mois-jour comme dans l'exemple suivant:
<?php
$date = '1981-01-16 12:30';
$time = strToTime($date);
echo 'La chaîne ['.$date.'] convertie en seconde depuis Epoch puis'."\n".
     'en date lisible (format Français) donne: '.date('d/m/Y H:i:s', $time);
?>
Télécharger strtotime.php

Ce qui donne:
La chaîne [1981-01-16 12:30] convertie en seconde depuis Epoch puis
en date lisible (format Français) donne: 16/01/1981 12:30:00
En revanche, si l'on applique la même fonction à la date suivante "01/11/2000 12:30" (en considérant qu'il s'agit d'une date au format jour/mois/année), on obtient
La chaîne [01/11/2000 12:30] convertie en seconde depuis Epoch puis
en date lisible (format Français) donne: 11/01/2000 12:30:00
Le 1er novembre est devenu 11 janvier (quelque soit la "locale" choisie).
warning La fonction strToTime() n'est donc pas adaptée au traitement des dates au format Français
Dans le cas d'une date au format jour/mois/annee mieux vaut envisager de "parser" la chaîne de caractères comme décrit dans le paragraphe suivant.
Et pourtant strToTime() est une fonction assez puissante, comme le montre l'exemple suivant avec une date exprimée sous la forme "June 3rd, 2000" mais voilà, en dehors des dates au format annee-mois-jour (ou annee/mois/jour et variantes), elle est surtout adaptée aux dates au format Américain:
<?php
$date = 'June 3rd, 2000';
$time = strToTime($date);
echo 'La chaîne ['.$date.'] convertie en seconde depuis Epoch puis'."\n".
     'en date lisible (format Français) donne: '.date('d/m/Y H:i:s', $time);
?>
Télécharger strtotime_2.php

Ce qui donne:
La chaîne [June 3rd, 2000] convertie en seconde depuis Epoch puis
en date lisible (format Français) donne: 03/06/2000 00:00:00

6.10.2.3.3.En découpant (i.e. parsant) la chaîne de caractères représentant une date

En découpant (i.e. parsant) une date, vous ne récupérez généralement pas directement une date en nombre de secondes depuis Epoch mais plutôt un ensemble de données tels que jour, mois, année, heure, minutes, secondes, etc.
Ensuite, soit vous serez en mesure de faire les manipulations voulues à partir de ces données, soit vous devrez les convertir en nombre de secondes avec la fonction mktime() ou gmmktime().
Ces 2 étapes sont décrites dans les chapitres suivants.
Ici vous pouvez apprendre :
1.Introduction
2.Installation de PHP
3.Exécuter un script PHP
4.Configuration et environnement d'exécution de PHP
5.L'environnement de développement
6.Le langage PHP
6.1.Introduction
6.2.Mon premier script
6.3.La syntaxe
6.4.Les boucles (for, while, foreach, do) en PHP
6.5.Les tableaux (array) en PHP
6.6.Les fonctions
6.7.Include
6.8.Programmation orientée objet
6.9.Les fonctions de manipulation de tableaux
6.10.Les dates
6.10.1.Introduction
6.10.2.Les fonctions natives PHP
6.10.2.1.Déterminer la date et heure courante
6.10.2.2.Formatter (i.e. afficher/retourner) une date
6.10.2.3.Convertir une date quelconque en nombre de secondes depuis Epoch
6.10.2.4.Découper (i.e. parser) une chaîne de caractères représentant une date
6.10.2.5.Convertir jour, mois, année, etc. en secondes depuis Epoch avec mktime() ou gmmktime()
6.10.2.6.Contrôler la validité d'une date
6.10.2.7.Le temps à la microseconde près
6.10.2.8.Mise en pratique
6.10.3.Les classes PHP
6.11.Fichiers et répertoires
6.12.Les paramètres d'entrée d'un script PHP
6.13.Utilisation de la librairie graphique
6.14.JpGraph pour tracer courbes et diagrammes
6.15.Utilisation de bases de données avec PHP
6.16.LDAP
6.17.Parser un document XML
6.18.Génération de documents PDF en PHP
6.19.Envoyer un mail
6.20.Créer un webmail avec IMAP
6.21.Droits utilisateurs: chmod 777
6.22.Localization (l10n) et Traduction
7.PHP pour le web
8.Internationalisation (i18n) et encodage en PHP
9.Créer un fichier de logs/traces
10.Déboguer une application PHP
11.Programmer en PHP en toute sécurité
12.Bibilothèque PEAR
13.Zend Framework 2 et 3
14.Installation de Zend Framework 2
15.Joomla
16.Composer
17.PHPUnit
18.PHPDocumentor
19.Mesure de temps d'exécution (benchmark) d'une fonction PHP
20.Exemples de scripts PHP
21.Erreurs fréquentes et les solutions
22.Archives
Version imprimable: imprimer