Doctrine, Symfony | Différence entre deux dates sous MySQL (Jour, mois, années…)

Comment connaître la différence entre deux dates sous MySQL avec Symfony et Doctrine ?

Doctrine est un ORM intégré à Symfony qui permets de faire facilement des opérations MySQL.

Les opérations de types dates requièrent souvent d’utiliser des fonctions MySQL native, vous pouvez retrouver la liste de ces fonctions sur le lien officiel MySQL.

Il vous faut utiliser la méthode TimeStampDiff qui prends 3 paramètres (l’unité, la première date, la seconde date) et vous retourne un chiffre correspondant à la différence d’unité entre les dates.

Exemple : 

//Année
TIMESTAMPDIFF(YEAR, 2019-01-01, 2022-01-01)
Sortie : 3 pour les 3 ans de différence

//Mois 
TIMESTAMPDIFF(MONTH, 2019-01-01, 2019-06-01)
Sortie : 5 pour les 5 mois de différence

//Jour
TIMESTAMPDIFF(DAY, 2019-01-01, 2019-01-16)
Sortie : 15 pour les 15 jours de différence

//Minutes
TIMESTAMPDIFF(MINUTE, 2019-01-01 12:45:00, 2019-01-16 13:45:00)
Sortie : 60 pour les 60 minutes de différence

Voir plus de détails sur ce lien qui explique en détails la fonction SQL TIMESTAMPDIFF

Comment utiliser la fonction SQL TimeStampDiff sous Doctrine avec Symfony ?

Il vous faut pour cela installer le package Beberlei Doctrine Extensions qui est un package complet et facile à prendre en main pour utiliser les fonctions SQL sous Doctrine.

Une fois le package installé, il faut initialiser chaque fonctions que vous souhaitez utiliser dans le fichier de config de Doctrine qui est au format YAML comme ceci : 

doctrine:
     dbal: ...
     orm: ...
     dql: 
         datetime_functions:
             TimestampDiff: DoctrineExtensions\Query\Mysql\TimestampDiff

Il est possible de retrouver toutes les fonctions du package Beberlei dans le dossier vendor à son nom.

Ensuite pour utiliser la fonction dans une requete DQL dans un Repository Symfony :

Exemple d’une requête pour récupérer des utilisateurs en fonction de la date de connexion : 

public function getUsersDateConnexion(){
        $query = $this->createQueryBuilder('users')
                      ->join('u.historiqueConnexions', "connexion")
                      ->having("TIMESTAMPDIFF(MONTH, MAX(connexion.dateConnexion), CURRENT_DATE()) >= 36");
        return $query->getQuery()->getResult();
}

Cette fonction permet dans cet exemple de récupérer des utilisateurs non connectés depuis 36 mois, nous voyons dans le ->having que nous pouvons utiliser la fonction SQL TimeStampDiff.

Nous retournons ensuite à partir de $query->getQuery()->getResult() le résultat de la requête SQL.