Aller au menu - Aller au contenu

Icône Les dates en SQL

Mise à jour : 03/04/2010
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-SA
133 390 visites depuis 7 jours, dont 2 404 sur ce chapitre classé 2/786
Lorsque nous avons construit nos tables, nous avons utilisé différents types de champs, notamment INT (nombre entier), VARCHAR (texte court) et TEXT (texte long). Vous avez pu découvrir dans phpMyAdmin qu'il existait de nombreux autres types. La plupart ne sont que des variations de ces types, pour stocker par exemple des très petits nombres ou des très grands nombres. La plupart du temps, vous n'aurez pas à vous soucier de tous ces types : INT suffit par exemple amplement pour les nombres entiers.

Les dates sont plus délicates à manier en SQL, et pourtant on en a très souvent besoin. Par exemple, dans le TP du Mini Chat, on pourrait s'en servir pour stocker le jour et l'heure précise où chaque message a été posté. Il en va de même si vous construisez un système de forum ou de news pour votre site : vous aurez besoin d'enregistrer la date à chaque fois.

Nous ferons d'abord le tour des types de champs à connaître pour stocker des dates avec MySQL et nous verrons comment les utiliser. Nous pourrons ensuite découvrir de nouvelles fonctions SQL dédiées aux dates. :)
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Les champs de type date

Dans ce chapitre, je vous propose d'améliorer un peu le Mini Chat que nous avons créé dans un TP précédent.

Saviez-vous qu'il était possible de modifier la structure d'une table après sa création ? Il est en effet possible d'y ajouter ou d'y supprimer des champs à tout moment. Ouvrez la table mini_chat dans phpMyAdmin, onglet "Structure". Cherchez en bas de la page le formulaire "Ajouter 1 champ en fin de table" et cliquez sur le bouton "Exécuter".

Ajout d'un champ dans phpMyAdmin


Un formulaire apparaît, vous proposant de créer un nouveau champ. C'est l'occasion de passer en revue les différents types de champs qui permettent de stocker des dates.

Les différents types de dates



Voici les différents types de dates que peut stocker MySQL :

  • DATE : stocke une date au format AAAA-MM-JJ (Année-Mois-Jour).
  • TIME : stocke un moment de la journée au format HH:MM:SS (Heures:Minutes:Secondes).
  • DATETIME : stocke une combinaison d'une date et d'un moment de la journée au format AAAA-MM-JJ HH:MM:SS. Ce type de champ est donc plus précis.
  • TIMESTAMP : stocke une date et un moment de la journée sous le format AAAAMMJJHHMMSS.
  • YEAR : stocke une année, soit au format AA, soit au format AAAA.


Cela fait beaucoup de choix ! Dans la pratique, je vous invite à retenir surtout DATE (AAAA-MM-JJ) quand le moment de la journée importe peu, et DATETIME (AAAA-MM-JJ HH:MM:SS) quand vous avez besoin du jour et de l'heure précise à la seconde près.

Créez un champ nommé date de type DATETIME comme ceci :

Création d'un champ de date


Bien que cela fonctionne avec MySQL, il est parfois préférable de donner un autre nom au champ que date. En effet, c'est un mot-clé du langage SQL, ce qui peut provoquer des erreurs avec d'autres systèmes de bases de données comme Oracle.
Vous pourriez par exemple nommer le champ comme ceci : date_creation, ou encore date_modification.


Utilisation des champs de date en SQL



Les champs de type date s'utilisent comme des chaînes de caractères : il faut donc les entourer d'apostrophes. Vous devez écrire la date dans le format du champ.

Par exemple, pour un champ de type DATE :

Code : SQL
1
SELECT pseudo, message, date FROM minichat WHERE date = '2010-04-02'


... vous renverra la liste des messages postés le 02/04/2010 (2 avril 2010).

Si le champ est de type DATETIME (comme c'est le cas pour notre nouveau Mini Chat), il faut aussi indiquer précisément les heures, minutes et secondes :

Code : SQL
1
SELECT pseudo, message, date FROM minichat WHERE date = '2010-04-02 15:28:22'


... vous renverra la liste des messages postés le 02/04/2010 à 15h28min22s.

Bon je reconnais que c'est un peu précis, il est peu probable que beaucoup de messages aient été postés à ce moment exact. :p

En revanche, et c'est là que les champs de date deviennent réellement intéressants, vous pouvez utiliser d'autres opérateurs que le signe égal. Par exemple, on peut obtenir la liste de tous les messages postés après cette date :

Code : SQL
1
SELECT pseudo, message, date FROM minichat WHERE date >= '2010-04-02 15:28:22'


Ou même la liste de tous les messages postés entre le 02/04/2010 et le 18/04/2010 :

Code : SQL
1
SELECT pseudo, message, date FROM minichat WHERE date >= '2010-04-02 00:00:00' AND date <= '2010-04-18 00:00:00'


En SQL, pour récupérer des données comprises entre 2 intervalles comme ici, il y a une syntaxe plus simple et plus élégante avec le mot-clé BETWEEN qui signifie "Entre". On pourrait écrire la requête précédente comme ceci :

Code : SQL
1
SELECT pseudo, message, date FROM minichat WHERE date BETWEEN '2010-04-02 00:00:00' AND '2010-04-18 00:00:00'


Cela signifie : récupérer tous les messages dont la date est comprise entre 2010-04-02 00:00:00 et 2010-04-18 00:00:00. Vous pouvez aussi utiliser cette syntaxe sur les champs contenant des nombres.


Si vous voulez insérer une entrée contenant une date, il suffit là encore de respecter le format de date de la base de données :

Code : SQL
1
INSERT INTO minichat(pseudo, message, date) VALUES('Mateo', 'Message !', '2010-04-02 16:32:22')

Les fonctions de gestion des dates

Il existe de très nombreuses fonctions de manipulation des dates. Utilisées sur des champs de type DATE ou DATETIME par exemple, elles permettent d'extraire très facilement toutes sortes d'informations utiles sur les dates, comme l'année, le numéro du jour du mois, le numéro du jour dans l'année, etc. Il est aussi possible d'effectuer des opérations sur les dates.

Il est impossible de lister toutes les fonctions de gestion des dates, mais vous trouverez la liste complète dans la documentation de MySQL sur les dates au besoin. Cette introduction aux dates devrait être suffisante pour que vous puissiez vous débrouiller tous seuls par la suite. ;)

NOW() : obtenir la date et l'heure actuelles



C'est probablement une des fonctions que vous utiliserez le plus souvent. Lorsque vous insérez un nouveau message dans la base, 99% du temps vous souhaiterez enregistrer la date actuelle. Pour cela, rien de plus simple avec la fonction NOW() :

Code : SQL
1
INSERT INTO minichat(pseudo, message, date) VALUES('Mateo', 'Message !', NOW())


La date sera alors automatiquement remplacée par la date et l'heure actuelle, au format AAAA-MM-JJ HH:MM:SS.

Notez qu'il existe aussi les fonctions CURDATE() et CURTIME() qui retournent respectivement uniquement la date (AAAA-MM-JJ) et l'heure (HH:MM:SS).

DAY(), MONTH(), YEAR() : extraire le jour, le mois ou l'année



Extraire des informations d'une date ? C'est facile ! Voici un exemple d'utilisation :

Code : SQL
1
SELECT pseudo, message, DAY(date) AS jour FROM minichat


On récupèrera 3 champs : le pseudo, le message et le numéro du jour où il a été posté.

HOUR(), MINUTE(), SECOND() : extraire les heures, minutes, secondes



De la même façon, avec ces fonctions il est possible d'extraire les heures, minutes et secondes d'un champ de type DATETIME ou TIME.

Code : SQL
1
SELECT pseudo, message, HOUR(date) AS heure FROM minichat


DATE_FORMAT : formater une date



Avec les fonctions que l'on vient de découvrir à l'instant, on pourrait extraire tous les éléments de la date comme ceci :

Code : SQL
1
SELECT pseudo, message, DAY(date) AS jour, MONTH(date) AS mois, YEAR(date) AS annee, HOUR(date) AS heure, MINUTE(date) AS minute, SECOND(date) AS seconde FROM minichat


On pourrait ensuite afficher la date dans l'ordre que l'on souhaite en PHP à l'aide du découpage en champs qu'on vient de faire :

Code : PHP
1
2
3
<?php
echo $donnees['jour'] . '/' . $donnees['mois'] . '/' . $donnees['annee'] . '...';
?>


C'est cependant un peu compliqué et il y a plus simple. La fonction DATE_FORMAT vous permet d'adapter directement la date au format que vous préférez. Il faut dire que le format par défaut de MySQL (AAAA-MM-JJ HH:MM:SS) n'est pas très courant en France. :-°

Voici comment on pourrait l'utiliser :

Code : SQL
1
SELECT pseudo, message, DATE_FORMAT(date, '%d/%m/%Y %Hh%imin%ss') AS date FROM minichat


Ainsi, on récupèrerait les dates avec un champ nommé date sous la forme 11/03/2010 15h47min49s.

Comment ça marche ce bazar ? o_O


Les symboles %d, %m, %Y (etc.) sont remplacés par le jour, le mois, l'année, etc. Les autres symboles et lettres sont affichés tels quels.

Il existe beaucoup d'autres symboles, pour extraire par exemple le nom du jour (la plupart du temps en anglais malheureusement, comme "Saturday"), le numéro du jour dans l'année, etc. La liste des symboles disponibles est dans la doc à la section DATE_FORMAT.

DATE_ADD et DATE_SUB : ajouter ou soustraire des dates



Il est possible d'ajouter ou soustraire des heures, minutes, secondes, jours, mois ou années à une date. Il faut envoyer 2 paramètres à la fonction : la date sur laquelle travailler et le nombre à ajouter ainsi que son type.

Par exemple, supposons que l'on souhaite afficher une date d'expiration du message. Cette date correspond à la date où a été posté le message + 15 jours. Voici comment écrire la requête :

Code : SQL
1
SELECT pseudo, message, DATE_ADD(date, INTERVAL 15 DAY) AS date_expiration FROM minichat


Le champ date_expiration correspond à la date de l'entrée + 15 jours. Le mot-clé INTERVAL ne doit pas être changé, en revanche vous pouvez remplacer DAY par MONTH, YEAR, HOUR, MINUTE, SECOND, etc. Par conséquent, si vous souhaitez que les messages expirent dans 2 mois :

Code : SQL
1
SELECT pseudo, message, DATE_ADD(date, INTERVAL 2 MONTH) AS date_expiration FROM minichat


Juste un petit rappel pour être sûr qu'on se comprend bien : cette requête ne commande pas la suppression des messages dans 2 mois ! On crée juste un champ virtuel date_expiration qui correspond à la date du message + 2 mois. Cela serait utile pour informer l'utilisateur quand son message va expirer, mais ce serait à vous de faire en sorte que votre site supprime le message au bout de 2 mois !

Q.C.M.

Que permet de stocker le type DATE ?
Quel est le format du type DATETIME ?
Quelle est la fonction la plus adaptée pour remplir un champ de type DATETIME avec la date et l'heure actuelles ?
Je souhaite retirer 30 minutes à mon champ de date. Comment faire ?

Statistiques de réponses au QCM

Ce tour d'horizon des dates vous sera rapidement très utile. On peut effectuer de nombreuses opérations sur les dates à l'aide de fonctions comme vous venez de le découvrir, ce qui nous fait gagner du temps et nous permet d'obtenir en PHP directement les informations que l'on souhaite dans la forme qui nous convient le mieux.
Chapitre précédent Sommaire Chapitre suivant

Partager

36 commentaires pour "Les dates en SQL"
Note moyenne : 3.61 / 4 (2518 votes)
Pseudo Commentaire
Hors ligne cout # Posté le 20/10/2011 à 14:48:09

Très facile d'ajouter la date.

minichat_post :

Code : PHP
1
2
$req = $bdd->prepare('INSERT INTO mini_chat (pseudo, message, date_message) VALUES (?, ?, NOW())');
    $req->execute(array($_POST['pseudo'], $_POST['message']));


Dans VALUES suffit d'ajouer "NOW()".

minichat.php

Code : PHP
1
2
3
4
5
while($donnees = $req->fetch())
   {
   
	echo '<strong><br /><span class="date">' . '(' . $donnees['date_message'] . ') <br/></span>' . htmlspecialchars($donnees['pseudo']) . ': <br /></strong> ' . htmlspecialchars($donnees['message']) ; ?> <br /> <?php
   }


pour afficher la date, il suffit d'utiliser l'array puis le champ dans l'array :D
Connecté superzero3 # Posté le 29/10/2011 à 19:20:55
Je suis un superzero
Groupe : Bannis

Bonjour, mon minichat ne marche pas. Regardez mon code Minichat.php.Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <head>
        <title>Mini-chat</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <style type="text/css">
    form,h1
    {
        text-align:center;
    }
    </style>
    <body>
    
    <h1>Voici le mini chat</h1><form action="minichat_post.php" method="post">
        <p>
        <label for="pseudo">Pseudo</label> : <input type="text" name="pseudo" id="pseudo" 
		value="" /><br /><br />
        <label for="message">Message</label> : <textarea name="message" rows="4" cols="45">
</textarea><hr />

        <input type="submit" value="Envoyer votre message" />
	</p>
    </form>

<?php
mysql_connect("localhost", "");
mysql_select_db("test");

if(isset($_POST['pseudo']) AND isset($_POST['message']))
{
        $pseudo = htmlentities($_POST['pseudo'], ENT_QUOTES);
        $message = htmlentities($_POST['message'], ENT_QUOTES);
		$date_creation = htmlentities($_POST['date_creation'], ENT_QUOTES);
        

        if($pseudo != NULL AND $message != NULL)
        {
                mysql_query("INSERT INTO minichat VALUES('', '$pseudo', '$message', '$date_creation')")Parse error: syntax error, unexpected '<' in C:\wamp\www\tests\Minichat.php on line 50
;
        }
        
        else
        {
                print "<strong><em>Vous devez remplir tous les champs avant d'envoyer votre message.</em></strong><br />";
        }
}
$infos = mysql_query ("SELECT * FROM minichat ORDER BY id DESC LIMIT 0, 9");
while($donnees = $req->fetch())
   {
	echo '<strong><br /><span class="date">' . '(' . $donnees['date_creation'] . ') <br/></span>' . htmlspecialchars($donnees['pseudo']) . ': <br /></strong> ' . htmlspecialchars($donnees['message']) ; <br /> 
   } 
mysql_close();

Et voici l'erreur qu'ils indiquent.
Parse error: syntax error, unexpected '<' in C:\wamp\www\tests\Minichat.php on line 50
Hors ligne louisn # Posté le 23/01/2012 à 10:16:09

Moi perso il me dit qu'il connaît pas NOW() Je fais quoi ?
Code : Autre
1
Fatal error: Call to undefined function NOW() in minichat_post.php on line 1


Merci d'avance
Louis
Hors ligne majid200 # Posté le 23/02/2012 à 06:07:09

Avis : Bon

je commence sur ce site le truc mini chat je l 'ai pas fais comment vais je fiare merci
Hors ligne brouchka # Posté le 29/03/2012 à 14:26:21
Avatar

Bonjour,voila j'ai envie d'inclure un calendrier pour mon administrateur pour qu’il puisse donner une date d'examen lorsqu'il clique sur le bouton ok la date sera envoyé dans le champ date_exam de ma table exam_prop de ma BDD si quelqu'un peut me répondre sa serai sympa!

Voir tous les commentaires