Comme nous venons de le voirs, le traitement des dates et du temps repose sur l'utilisation du nombre de secondes écoulées depuis le 01/01/1970. Ce nombre sert de base à toutes les fonctions traitant des dates et qui permettent d'extraire les informations pertinentes : année, mois, jour, heures, minutes, secondes, semaine, nom du jour, numéro du jour dans l'année, année bissextile ou non, etc.

### La fonction mktime()

Définir une date revient à déterminer son timestamp. Pour cela PHP nous fournit la fonction mktime() qui accepte en paramètres, dans l'ordre suivant, heures, minutes, secondes, mois, jour et année de la date choisie.

Exemple : définir une date
<?php require('bib_fonctions.php'); htmlDebut('Définir une date'); htmlInfo('Timestamp du 1er janvier 2000'); echo mktime(0, 0, 0, 1, 1, 2000); htmlInfo('Timestamp du 1er décembre 1994 à 12h30'); echo mktime(12, 30, 0, 12, 1, 1994); htmlFin(); ?>

L'exemple suivant calcule le timestamp de votre date de naissance et affiche le nom du jour où vous êtes né.

Exemple : définir une date
<?php require('bib_fonctions.php'); htmlDebut('Définir une date'); // Modifiez les variables $JJ, $MM et $AA pour // les adapter à votre date de naissance $JJ = 25; $MM = 8; $AA = 1958; $t = mktime(12, 0, 0, $MM, $JJ, $AA); // Tableau des jours $jours = array('dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'); echo 'Le ', date('d/m/Y', $t), ' était un ', $jours[date('w', $t)]; htmlFin(); ?>

### Définir une date future ou passée

Nous pouvons obtenir une date passée ou une date future en utilisant les fonctions mktime() et getdate() ou date().

L'exemple suivant calcule à quelle date nous serons dans 45 jours et 18 heures.

Exemple : définir une date dans le futur
<?php require('bib_fonctions.php'); htmlDebut('Définir une date dans le futur'); // Eléments du jour $j = getdate(time()); $t = mktime($j['hours'] + 18, $j['minutes'], $j['seconds'], $j['mon'], $j['mday'] + 45, $j['year']); echo 'Dans 45 jours et 18 heures, nous serons le ', date('d/m/Y \à H:i:s', $t); htmlFin(); ?>

Ce qui est agréable, c'est que la fonction mktime() fait automatiquement les bons calculs de mois et d'heures avec les arguments qu'on lui passe.

Dans l'exemple précédent nous commençons par récupérer les éléments constituant la date du jour avec la fonction getdate() qui comme nous l'avons vu précédemment renvoie un tableau de ces divers constituants. Par exemple $j['mday'] contient le numéro du jour actuel et $j['hours'] contient l'heure du moment.
Pour calculer la date future dans 45 jours, il nous suffit d'ajouter 45 au jour actuel : $j['mday'] + 45.
Même chose pour calculer la date dans 18 heures, il suffit d'ajouter 18 à l'heure actuelle : $j['hours'] + 18.
Pour récupérer le timestamp de la date dans 45 jours et 18 heures, il suffit donc de passer les paramètres suivant à la fonction mktime() :
mktime($j['hours'] + 18, $j['minutes'], $j['seconds'], $j['mon'], $j['mday'] + 45, $j['year']);

Nous pourrions aussi utiliser la fonction date() à la place de getdate() :
mktime(date('H') + 18, date('i'), date('s'), date('m'), date('d') + 45, date('Y'));
Cette solution, si elle est identique en terme de résultat, est par contre beaucoup plus consommatrice en temps de traitement car la fonction date() est appelée 6 fois de suite.

Le même principe peut être utilisé pour calculer une date passée. L'exemple suivant calcule la date d'il y a 1 an, 6 mois et 3 jours.

Exemple : définir une date dans le passé
<?php require('bib_fonctions.php'); htmlDebut('Définir une date dans le passé'); // Eléments du jour $j = getdate(time()); $t = mktime($j['hours'], $j['minutes'], $j['seconds'], $j['mon'] - 6, $j['mday'] - 3, $j['year'] - 1); echo 'Il y a 1 an, 6 mois et 3 jours, nous étions le ', date('d/m/Y', $t); htmlFin(); ?>

### Exercice : fonction d'ajout de temps

PHP ne fournit pas directement une fonction qui permette d'ajouter ou de retrancher un certain laps de temps à une date. Vous allez donc écrire la fonction newTimestamp() qui retroune un timestamp par ajout ou soustraction.

La fonction accepte trois paramètres :

- le laps de temps
- le type du temps à ajouter / retrancher
- le timestamp de la date à laquelle nous voulons ajouter/retrancher le temps.

Le type du temps à ajouter est un caractère alphabétique qui peut avoir les valeurs suivantes:

a
  : pour un nombre d'années
t
  : pour un nombre de trimestres
m
  : pour un nombre de mois
j
  : pour un nombre de jours
w
  : pour un nombre de semaines
h
  : pour un nombre d'heures
i
  : pour un nombre de minutes
s
  : pour un nombre de secondes.

La fonction newTimestamp() renvoie un timestamp.

Une solution possible

Exercice : fonction d'ajout de temps
<?php require('bib_fonctions.php'); htmlDebut('Fonction d\'ajout de temps'); /** * Ajoute ou retranche un laps de temps à un timestamp * * @param integer $nbre nombre d'unités * @param string $unite unité : h, i, s, a, m, j, t, w * @param integer $debut timestamp de départ du calcul * @return integer nouveau timestamp */ function newTimestamp($nbre, $unite, $debut) { $d = getdate($debut); $h = $d['hours']; $i = $d['minutes']; $s = $d['seconds']; $a = $d['year']; $m = $d['mon']; $j = $d['mday']; switch ($unite) { case('a'): return mktime($h, $i, $s, $m, $j, $a + $nbre); case('t'): return mktime($h, $i, $s, $m + ($nbre * 3), $j, $a); case('m'): return mktime($h, $i, $s, $m + $nbre, $j, $a); case('j'): return mktime($h, $i, $s, $m, $j + $nbre, $a); case('w'): return mktime($h, $i, $s, $m, $j + ($nbre * 7), $a); case('h'): return mktime($h + $nbre, $i, $s, $m, $j, $a); case('i'): return mktime($h, $i + $nbre, $s, $m, $j, $a); case('s'): return mktime($h, $i, $s + $nbre, $m, $j, $a); } // Si on est ici c'est que le 2éme paramètre // n'était pas bon. On retourne -1. return -1; } //------------------------------------------------------ // Utilisation de la fonction htmlInfo('Dans 15 jours'); echo date('d/m/Y', newTimestamp(15, 'j', time())); htmlInfo('Dans 18 heures'); echo date('d/m/Y H:i:s', newTimestamp(18, 'h', time())); htmlInfo('Dans 3 semaines'); echo date('d/m/Y', newTimestamp(3, 'w', time())); htmlInfo('Il y a 90 minutes'); echo date('H:i:s', newTimestamp(-90, 'i', time())); htmlInfo('15 jours avant le 01/01/2000'); $debut = mktime(0,0,0,1,1,2000); echo date('D d/m/Y', newTimestamp(-15, 'j', $debut)); htmlFin(); ?>

### Exercice : fonction de différence de temps

Avec le principe du timestamp, il est très facile de calculer la différence de temps entre 2 dates. Ecrivez la fonction getTimeDiff() qui permet de calculer le laps de temps écoulé entre 2 dates. La fonction accepte trois paramètres :

- le type du temps retourné
- le timestamp de la date de début
- le timestamp de la date de fin.

Le type du temps retourné est un caractère alphabétique qui peut avoir les valeurs suivantes:

j
  : pour un nombre de jours
w
  : pour un nombre de semaines
h
  : pour un nombre d'heures
i
  : pour un nombre de minutes
s
  : pour un nombre de secondes.

Si la fonction est appelée avec seulement 2 paramètres, c'est le timestamp de la date du jour qui est utilisé comme date de fin.

La fonction getTimeDiff() renvoie le nombre d'unités inférieure le plus proche (floor()).

Une solution possible

Exercice : fonction de différence de temps
<?php require('bib_fonctions.php'); htmlDebut('Fonction différence de temps'); /** * Calcul de la différence entre 2 timestamp * * @param string $unite unité : w , j, h, i, s * @param integer $debut timestamp date début * @param integer $fin timsetamp date de fin * @return integer nombre d'unité de différence */ function getTimeDiff($unite, $debut) { if (func_num_args() == 2) { $fin = time(); } else { $fin = func_get_arg(2); } $diff = $fin - $debut; switch ($unite) { case 'w': return floor($diff / 604800); case 'j': return floor($diff / 86400); case 'h': return floor($diff / 3600); case 'i': return floor($diff / 60); case 's': return $diff; } return -1; } //------------------------------------------------------ // Utilisation de la fonction htmlInfo('Nombre de jours depuis ma naissance'); echo getTimeDiff('j', mktime(0, 0, 0, 8, 25, 1958)); htmlInfo('Nombre de minutes depuis le début de ce jour'); $debut = mktime(0,0,0, date('m'), date('d'), date('Y')); echo getTimeDiff('i', $debut); htmlInfo('Nombre de semaines avant Noël'); $fin = mktime(0,0,0, 12, 25, date('Y')); echo getTimeDiff('w', time(), $fin); htmlFin(); ?>