Comparer des dates et tester la validité d’une date en PHP

Dans cette nouvelle leçon, nous allons comprendre les défis de la comparaison de deux dates et allons voir comment les contourner. Nous apprendrons également à tester la validité d’une date.

 

La comparaison de dates en PHP

La comparaison de dates est une chose difficile en informatique et particulièrement en PHP.

La raison principale à cela est qu’une date peut être écrite sous de multiples formats : soit tout en chiffres, soit tout en lettres, soit avec un mélange de chiffres et de lettres, avec les mois avant ou après les jours, etc.

Lorsqu’on utilise un opérateur de comparaison, les deux opérandes (ce qui se situe d’un côté et de l’autre de l’opérateur) vont être comparés caractère par caractère. Cela rend impossible la comparaison de dates dont le format n’est pas strictement identique ainsi que la comparaison de dates écrites avec des lettres.

Nous allons donc ici généralement privilégier la comparaison des Timestamp liés aux dates puisque les Timestamp sont des nombres et qu’il est très facile de comparer deux nombres en PHP.

On va donc procéder en deux étapes : on va déjà commencer par récupérer les Timestamp liés aux dates qu’on souhaite comparer avec une fonction comme strtotime() par exemple puis on va comparer les Timestamp.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            setlocale(LC_TIME, ['fr', 'fra', 'fr_FR']);
            
            $d1 = '25-01-2019';
            $d2 = '30-June 2018';

            $tmstp1 = strtotime($d1);
            $tmstp2 = strtotime($d2);
            
            $dfr1 = strftime('%A %d %B %Y', $tmstp1);
            $dfr2 = strftime('%A %d %B %Y', $tmstp2);
            
            if($tmstp1 < $tmstp2){
                echo 'Le ' .$dfr1. ' est avant le ' .$dfr2;
            }elseif($tmstp1 == $tmstp2){
                echo 'Les deux dates sont les mêmes';
            }else{
                 echo 'Le ' .$dfr2. ' est avant le ' .$dfr1;
            }
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On peut facilement comparer des dates en PHP en comparant leur timestamp unix

 

La validation de dates : en quoi est-ce utile ?

Jusqu’à présent, nous n’avons travaillé qu’en local, c’est-à-dire sur nos propres machines et pour nous-mêmes. Comme nous créons et testons nos codes nous-mêmes, nous n’avons aucun problème de sécurité / validité.

Cependant, l’objectif reste de pouvoir par la suite créer de véritables sites dynamiques, avec des formulaires, des espaces clients, etc. Dans ces cas-là, bien souvent, vous allez demander aux utilisateurs de vous envoyer des données.

Cela va être par exemple le cas si vous créez un formulaire d’inscription sur votre site, ou si vous possédez un site marchand. Vous demanderez alors certainement les nom, prénom, adresse mail, numéro de téléphone, date de naissance, etc. des utilisateurs.

Il va alors falloir être très précautionneux car vous ne devez jamais vous attendre à recevoir des données valides de la part de vos utilisateurs.

En effet, certains vous faire des fautes, d’autres seront étourdis, d’autres encore vont refuser de remplir certaines données et un petit pourcentage va même potentiellement être composé d’utilisateurs mal intentionnés qui essaieront d’exploiter des possibles failles dans votre site, en tenant de vous envoyer (ou “injecter”) des bouts de code par exemple.

Pour ces raisons, nous testerons et traiterons toujours les informations envoyées par nos utilisateurs, et notamment les dates.

 

Tester la validité d’une date

La manière la plus robuste de vérifier la validité d’une date en PHP est d’utiliser la fonction checkdate() qui a été créée dans ce but précis.

Cette fonction va accepter trois chiffres en arguments : le premier représente le mois de la date à tester, le deuxième représente le jour et le troisième représente l’année.

Pour que la date soit considérée valide, elle devra remplir les critères suivants :

  • Le mois doit être compris entre 1 et 12 ;
  • Le jour doit être un jour autorisé par le mois donné (le 30 février, le 31 avril ou le 45 juin seront considérés invalides par exemple). Notez que les années bissextiles sont prises en compte ;
  • L’année doit être comprise entre l’an 1 et l’an 32767.

Si checkdate() valide la date passée, alors elle renverra le booléen true. Dans le cas contraire, elle renverra false.

Notez bien ici que cette fonction va nous permettre d’écarter les valeurs aberrantes de dates, c’est-à-dire les dates qui n’existent pas dans le calendrier mais ne va bien évidemment pas nous permettre de vérifier la cohérence d’une date.

Si vous avez un formulaire demandant la date de naissance des utilisateurs sur votre site, par exemple, ce sera à vous d’ajouter des contraintes sur la date de naissance pour écarter par exemple les dates de naissance fantaisistes comme les dates dans le futur ou les dates avant 1900.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            setlocale(LC_TIME, ['fr', 'fra', 'fr_FR']);
            
            if(checkdate(1,25,2019)){
                echo 'Le 25 janvier 2019 est une date valide <br>';
            }
            if(checkdate(1,35,2019)){
                echo 'Le 35 janvier 2019 est une date valide <br>';
            }
            if(checkdate(2,29,2015)){
                echo 'Le 29 février 2015 est une date valide <br>';
            }
            if(checkdate(2,29,2016)){
                echo 'Le 29 février 2016 est une date valide <br>';
            }
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On teste la validité d'une date en PHP avec la fonction checkdate

Ici, on teste différentes dates avec checkdate(). Si la date passée à checkdate() est validée par la fonction, alors la fonction renvoie la date et le test de notre condition va être validé et on va donc echo la date formatée localement grâce à setlocale().

 

Tester la validité d’un format de date locale

On va également pouvoir vérifier si un format de date locale nous convient, c’est-à-dire vérifier la validité d’une date générée par la fonction strftime() en utilisant cette fois-ci la fonction strptime()</code.

On va passer la chaine de type date renvoyée par strftime() à la fonction strptime() ainsi que le format de date utilisé par strftime().

La fonction strptime() va alors soit retourner un tableau contenant les différentes informations liées à la date si celle-ci a été jugée valide, soit la valeur false en cas d’erreur sur la date.

Si la date est validée, le tableau renvoyé sera de la forme suivante :

Type de donnéesSignification
tm_secReprésente les secondes
tm_minReprésente les minutes
tm_hourReprésente l’heure de 0 à 23
tm_mdayLe jour du mois en chiffres sans le zéro initial
tm_monReprésente le mois sous forme de chiffres (janvier = 0, décembre = 11)
tm_yearLe nombre d’années écoulées depuis 1900
tm_wdayLe numéro du jour de la semaine (Dimanche = 0, Samedi= 6)
tm_ydayLe jour de l’année en chiffres (1er janvier = 0)
unparsedLa partie de la date qui n’a pas été reconnue
<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            setlocale(LC_TIME, ['fr', 'fra', 'fr_FR']);
            
            $format1 = '%A %d %B %Y %H:%M:%S';
            $format2 = '%H:%M:%S';
            
            $date1 = strftime($format1);
            $date2 = strftime($format1);
            $date3 = strftime($format2);
            
            echo $date1. '<br>' .$date2. '<br>' .$date3. '<br>';
            
            if(strptime($date1, $format1)){
                echo '<pre>';
                print_r(strptime($date1, $format1));
                echo '</pre><br>';
            }
            if(strptime($date2, '%A %d %B %Y')){
                echo '<pre>';
                print_r(strptime($date2, '%A %d %B %Y'));
                echo '</pre><br>';
            }
            if(strptime($date3, '%A %d %B %Y')){
                echo '<pre>';
                print_r(strptime($date3, '%A %d %B %Y'));
                echo '</pre>';
            }
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

Tester la validité d'un format de date locale en PHP avec strptime

Ici, on commence par définir une constante de date locale avec setlocale() puis on définit les formats de date %A %d %B %Y %H:%M:%S et %H:%M:%S qu’on va passer à strftime().

On demande ensuite à strftime() de nous renvoyer trois dates en utilisant nos différents formats et on place les résultats dans trois variables $date1, $date2 et $date3 pour bien voir avec quelles dates on travaille.

On crée ensuite trois conditions. Dans notre première condition, on appelle strptime() en lui passant notre variable $date1 et le même format que celui utilisé avec strftime()

La date contenue dans $date1 est la date courante et les formats utilisés sont les mêmes pour strftime() et strptime(). Toutes les informations de date vont bien être affichées.

Dans notre deuxième condition, en revanche, on passe un format de date différent à strptime(). Ici, seuls les éléments communs aux formats passés à strftime() et à strptime() seront renvoyés dans les « bons » éléments du tableau créé par strptime(). Le reste de la date sera associé à la clef unparsed car non reconnu.

Finalement, on utilise un format totalement différent pour tester notre troisième date. Ici, une erreur va être renvoyée et donc strptime() va renvoyer false et le test de notre condition va échouer.

Laisser un commentaire