Avant de plonger tête la première dans les fonctions temporelles, il convient de faire un bref rappel sur les différents types de données temporelles, qui sont au nombre de cinq : DATE
, TIME
, DATETIME
, TIMESTAMP
et YEAR
.
Ensuite, nous verrons avec quelles fonctions il est possible d'obtenir la date actuelle, l'heure actuelle, ou les deux.
Etat actuel de la base de données
Note : les tables de test ne sont pas reprises.
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | SET NAMES utf8; DROP TABLE IF EXISTS Animal; DROP TABLE IF EXISTS Race; DROP TABLE IF EXISTS Espece; CREATE TABLE Espece ( id smallint(6) unsigned NOT NULL AUTO_INCREMENT, nom_courant varchar(40) NOT NULL, nom_latin varchar(40) NOT NULL, description text, prix decimal(7,2) unsigned DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY nom_latin (nom_latin) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; LOCK TABLES Espece WRITE; INSERT INTO Espece VALUES (1,'Chien','Canis canis','Bestiole à quatre pattes qui aime les caresses et tire souvent la langue',200.00),(2,'Chat','Felis silvestris','Bestiole à quatre pattes qui saute très haut et grimpe aux arbres',150.00),(3,'Tortue d''Hermann','Testudo hermanni','Bestiole avec une carapace très dure',140.00), (4,'Perroquet amazone','Alipiopsitta xanthops','Joli oiseau parleur vert et jaune',700.00),(5,'Rat brun','Rattus norvegicus','Petite bestiole avec de longues moustaches et une longue queue sans poils',10.00); UNLOCK TABLES; CREATE TABLE Race ( id smallint(6) unsigned NOT NULL AUTO_INCREMENT, nom varchar(40) NOT NULL, espece_id smallint(6) unsigned NOT NULL, description text, prix decimal(7,2) unsigned DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1; LOCK TABLES Race WRITE; INSERT INTO Race VALUES (1,'Berger allemand',1,'Chien sportif et élégant au pelage dense, noir-marron-fauve, noir ou gris.',485.00),(2,'Berger blanc suisse',1,'Petit chien au corps compact, avec des pattes courtes mais bien proportionnées et au pelage tricolore ou bicolore.',935.00),(3,'Singapura',2,'Chat de petite taille aux grands yeux en amandes.',985.00), (4,'Bleu russe',2,'Chat aux yeux verts et à la robe épaisse et argentée.',835.00),(5,'Maine coon',2,'Chat de grande taille, à poils mi-longs.',735.00),(7,'Sphynx',2,'Chat sans poils.',1235.00), (8,'Nebelung',2,'Chat bleu russe, mais avec des poils longs...',985.00),(9,'Rottweiller',1,'Chien d''apparence solide, bien musclé, à la robe noire avec des taches feu bien délimitées.',600.00); UNLOCK TABLES; CREATE TABLE Animal ( id smallint(6) unsigned NOT NULL AUTO_INCREMENT, sexe char(1) DEFAULT NULL, date_naissance datetime NOT NULL, nom varchar(30) DEFAULT NULL, commentaires text, espece_id smallint(6) unsigned NOT NULL, race_id smallint(6) unsigned DEFAULT NULL, mere_id smallint(6) unsigned DEFAULT NULL, pere_id smallint(6) unsigned DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY ind_uni_nom_espece_id (nom,espece_id) ) ENGINE=InnoDB AUTO_INCREMENT=63 DEFAULT CHARSET=utf8; LOCK TABLES Animal WRITE; INSERT INTO Animal VALUES (1,'M','2010-04-05 13:43:00','Rox','Mordille beaucoup',1,1,18,22),(2,NULL,'2010-03-24 02:23:00','Roucky',NULL,2,NULL,40,30),(3,'F','2010-09-13 15:02:00','Schtroumpfette',NULL,2,4,41,31), (4,'F','2009-08-03 05:12:00',NULL,'Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(5,NULL,'2010-10-03 16:44:00','Choupi','Né sans oreille gauche',2,NULL,NULL,NULL),(6,'F','2009-06-13 08:17:00','Bobosse','Carapace bizarre',3,NULL,NULL,NULL), (7,'F','2008-12-06 05:18:00','Caroline',NULL,1,2,NULL,NULL),(8,'M','2008-09-11 15:38:00','Bagherra',NULL,2,5,NULL,NULL),(9,NULL,'2010-08-23 05:18:00',NULL,'Bestiole avec une carapace très dure',3,NULL,NULL,NULL), (10,'M','2010-07-21 15:41:00','Bobo',NULL,1,NULL,7,21),(11,'F','2008-02-20 15:45:00','Canaille',NULL,1,NULL,NULL,NULL),(12,'F','2009-05-26 08:54:00','Cali',NULL,1,2,NULL,NULL), (13,'F','2007-04-24 12:54:00','Rouquine',NULL,1,1,NULL,NULL),(14,'F','2009-05-26 08:56:00','Fila',NULL,1,2,NULL,NULL),(15,'F','2008-02-20 15:47:00','Anya',NULL,1,NULL,NULL,NULL), (16,'F','2009-05-26 08:50:00','Louya',NULL,1,NULL,NULL,NULL),(17,'F','2008-03-10 13:45:00','Welva',NULL,1,NULL,NULL,NULL),(18,'F','2007-04-24 12:59:00','Zira',NULL,1,1,NULL,NULL), (19,'F','2009-05-26 09:02:00','Java',NULL,1,2,NULL,NULL),(20,'M','2007-04-24 12:45:00','Balou',NULL,1,1,NULL,NULL),(21,'F','2008-03-10 13:43:00','Pataude',NULL,1,NULL,NULL,NULL), (22,'M','2007-04-24 12:42:00','Bouli',NULL,1,1,NULL,NULL),(24,'M','2007-04-12 05:23:00','Cartouche',NULL,1,NULL,NULL,NULL),(25,'M','2006-05-14 15:50:00','Zambo',NULL,1,1,NULL,NULL), (26,'M','2006-05-14 15:48:00','Samba',NULL,1,1,NULL,NULL),(27,'M','2008-03-10 13:40:00','Moka',NULL,1,NULL,NULL,NULL),(28,'M','2006-05-14 15:40:00','Pilou',NULL,1,1,NULL,NULL), (29,'M','2009-05-14 06:30:00','Fiero',NULL,2,3,NULL,NULL),(30,'M','2007-03-12 12:05:00','Zonko',NULL,2,5,NULL,NULL),(31,'M','2008-02-20 15:45:00','Filou',NULL,2,4,NULL,NULL), (32,'M','2009-07-26 11:52:00','Spoutnik',NULL,3,NULL,52,NULL),(33,'M','2006-05-19 16:17:00','Caribou',NULL,2,4,NULL,NULL),(34,'M','2008-04-20 03:22:00','Capou',NULL,2,5,NULL,NULL), (35,'M','2006-05-19 16:56:00','Raccou','Pas de queue depuis la naissance',2,4,NULL,NULL),(36,'M','2009-05-14 06:42:00','Boucan',NULL,2,3,NULL,NULL),(37,'F','2006-05-19 16:06:00','Callune',NULL,2,8,NULL,NULL), (38,'F','2009-05-14 06:45:00','Boule',NULL,2,3,NULL,NULL),(39,'F','2008-04-20 03:26:00','Zara',NULL,2,5,NULL,NULL),(40,'F','2007-03-12 12:00:00','Milla',NULL,2,5,NULL,NULL), (41,'F','2006-05-19 15:59:00','Feta',NULL,2,4,NULL,NULL),(42,'F','2008-04-20 03:20:00','Bilba','Sourde de l''oreille droite à 80%',2,5,NULL,NULL),(43,'F','2007-03-12 11:54:00','Cracotte',NULL,2,5,NULL,NULL), (44,'F','2006-05-19 16:16:00','Cawette',NULL,2,8,NULL,NULL),(45,'F','2007-04-01 18:17:00','Nikki','Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(46,'F','2009-03-24 08:23:00','Tortilla','Bestiole avec une carapace très dure',3,NULL,NULL,NULL), (47,'F','2009-03-26 01:24:00','Scroupy','Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(48,'F','2006-03-15 14:56:00','Lulla','Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(49,'F','2008-03-15 12:02:00','Dana','Bestiole avec une carapace très dure',3,NULL,NULL,NULL), (50,'F','2009-05-25 19:57:00','Cheli','Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(51,'F','2007-04-01 03:54:00','Chicaca','Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(52,'F','2006-03-15 14:26:00','Redbul','Insomniaque',3,NULL,NULL,NULL), (54,'M','2008-03-16 08:20:00','Bubulle','Bestiole avec une carapace très dure',3,NULL,NULL,NULL),(55,'M','2008-03-15 18:45:00','Relou','Surpoids',3,NULL,NULL,NULL),(56,'M','2009-05-25 18:54:00','Bulbizard','Bestiole avec une carapace très dure',3,NULL,NULL,NULL), (57,'M','2007-03-04 19:36:00','Safran','Coco veut un gâteau !',4,NULL,NULL,NULL),(58,'M','2008-02-20 02:50:00','Gingko','Coco veut un gâteau !',4,NULL,NULL,NULL),(59,'M','2009-03-26 08:28:00','Bavard','Coco veut un gâteau !',4,NULL,NULL,NULL), (60,'F','2009-03-26 07:55:00','Parlotte','Coco veut un gâteau !',4,NULL,NULL,NULL),(61,'M','2010-11-09 00:00:00','Yoda',NULL,2,5,NULL,NULL),(62,'M','2010-11-05 00:00:00','Pipo',NULL,1,9,NULL,NULL); UNLOCK TABLES; ALTER TABLE Race ADD CONSTRAINT fk_race_espece_id FOREIGN KEY (espece_id) REFERENCES Espece (id) ON DELETE CASCADE; ALTER TABLE Animal ADD CONSTRAINT fk_race_id FOREIGN KEY (race_id) REFERENCES Race (id) ON DELETE SET NULL; ALTER TABLE Animal ADD CONSTRAINT fk_espece_id FOREIGN KEY (espece_id) REFERENCES Espece (id); ALTER TABLE Animal ADD CONSTRAINT fk_mere_id FOREIGN KEY (mere_id) REFERENCES Animal (id) ON DELETE SET NULL; ALTER TABLE Animal ADD CONSTRAINT fk_pere_id FOREIGN KEY (pere_id) REFERENCES Animal (id) ON DELETE SET NULL; |
Rappels
Nous allons rapidement revoir les cinq types de données temporelles disponibles pour MySQL. Pour plus de détails, je vous renvoie au chapitre consacré à ceux-ci, ou à la documentation officielle.
Date
On peut manipuler une date (jour, mois, année) avec le type DATE
. Ce type représente la date sous forme de chaîne de caractères 'AAAA-MM-JJ'
(A = année, M = mois, J = jour). Par exemple : le 21 octobre 2011 sera représenté '2011-10-21'
.
Lorsque l'on crée une donnée de type DATE
, on peut le faire avec une multitude de formats différents, que MySQL convertira automatiquement. Il suffit de donner l'année (en deux ou quatre chiffres), suivie du mois (deux chiffres) puis du jour (deux chiffres). Avec une chaîne de caractères, n'importe quel caractère de ponctuation (ou aucun caractère) peut être utilisé pour séparer l'année du mois et le mois du jour. On peut aussi utiliser un nombre entier pour initialiser une date (pour autant qu'il ait du sens en tant que date bien sûr).
MySQL supporte des DATE
allant de '1001-01-01'
à '9999-12-31'
.
Heure
Pour une heure, ou une durée, on utilise le type TIME
, qui utilise également une chaîne de caractères pour représenter l'heure : '[H]HH:MM:SS'
(H = heures, M = minutes, S = secondes).
MySQL supporte des TIME
allant de '-838:59:59'
à '838:59:59'
. Ce n'est en effet pas limité à 24h, puisqu'il est possible de stocker des durées.
Pour créer un TIME
, on donne d'abord les heures, puis les minutes, puis les secondes, avec : entre chaque donnée. On peut éventuellement aussi spécifier un nombre de jours avant les heures (suivi cette fois d'une espace, et non d'un :) : 'J HH:MM:SS'
.
Date et heure
Sans surprise, DATETIME
est le type de données représentant une date et une heure, toujours stockées sous forme de chaîne de caractères : 'AAAA-MM-JJ HH:MM:SS'
. Les heures doivent ici être comprises entre 00 et 23, puisqu'il ne peut plus s'agir d'une durée.
Comme pour DATE
, l'important dans DATETIME
est l'ordre des données : année, mois, jour, heures, minutes, secondes ; chacune avec deux chiffres, sauf l'année pour laquelle on peut aussi donner quatre chiffres. Cela peut être un nombre entier, ou une chaîne de caractères, auquel cas les signes de ponctuation entre chaque partie du DATETIME
importent peu.
MySQL supporte des DATETIME
allant de '1001-01-01 00:00:00'
à '9999-12-31 23:59:59'
.
Timestamp
Le timestamp d'une date est le nombre de secondes écoulées depuis le 1er janvier 1970, 0h0min0s (TUC) et la date en question. Mais attention, ce qui est stocké par MySQL dans une donnée de type TIMESTAMP
n'est pas ce nombre de secondes, mais bien la date, sous format numérique : AAAAMMJJHHMMSS
(contrairement à DATE
, TIME
et DATETIME
qui utilisent des chaînes de caractères).
Un timestamp est limité aux dates allant du 1er janvier 1970 00h00min00s au 19 janvier 2038 03h14min07s.
Année
Le dernier type temporel est YEAR
, qui stocke une année sous forme d'entier. Nous n'en parlerons pas beaucoup dans cette partie.
YEAR
peut contenir des années comprises entre 1901 et 2155.
Date actuelle
Il existe deux fonctions permettant d'avoir la date actuelle (juste la date, sans l'heure, donc au format DATE
) :
CURDATE()
;CURRENT_DATE()
, qui peut également s'utiliser sans parenthèses, comme plusieurs autres fonctions temporelles.
1 | SELECT CURDATE(), CURRENT_DATE(), CURRENT_DATE; |
CURDATE() |
CURRENT_DATE() |
CURRENT_DATE |
---|---|---|
2011-10-25 |
2011-10-25 |
2011-10-25 |
Heure actuelle
À nouveau, deux fonctions existent, extrêmement similaires aux fonctions permettant d'avoir la date actuelle. Il suffit en effet de remplacer DATE
par TIME
dans le nom de la fonction.
1 | SELECT CURTIME(), CURRENT_TIME(), CURRENT_TIME; |
CURTIME() |
CURRENT_TIME() |
CURRENT_TIME |
---|---|---|
18:04:20 |
18:04:20 |
18:04:20 |
Date et heure actuelles
Les fonctions
Pour obtenir la date et l'heure actuelles (format DATETIME
), c'est Byzance : vous avez le choix entre cinq fonctions différentes !
NOW() et SYSDATE()
NOW()
est sans doute la fonction MySQL la plus utilisée pour obtenir la date du jour. C'est aussi la plus facile à retenir (bien que les noms des fonctions soient souvent explicites en SQL), puisque now veut dire "maintenant" en anglais. SYSDATE()
("system date") est aussi pas mal utilisée.
1 | SELECT NOW(), SYSDATE(); |
NOW() |
SYSDATE() |
---|---|
2011-10-26 09:40:18 |
2011-10-26 09:40:18 |
Et les autres
Les trois autres fonctions peuvent s'utiliser avec ou sans parenthèses.
CURRENT_TIMESTAMP
ouCURRENT_TIMESTAMP()
LOCALTIME
ouLOCALTIME()
LOCALTIMESTAMP
ouLOCALTIMESTAMP()
1 | SELECT LOCALTIME, CURRENT_TIMESTAMP(), LOCALTIMESTAMP; |
LOCALTIME |
CURRENT_TIMESTAMP() |
LOCALTIMESTAMP |
---|---|---|
2011-10-26 10:02:31 |
2011-10-26 10:02:31 |
2011-10-26 10:02:31 |
Qui peut le plus, peut le moins
Il est tout à fait possible d'utiliser une des fonctions donnant l'heure et la date pour remplir une colonne de type DATE
, ou de type TIME
. MySQL convertira simplement le DATETIME
en DATE
, ou en TIME
, en supprimant la partie inutile.
Exemple
Créons une table de test simple, avec juste trois colonnes. Une de type DATE
, une de type TIME
, une de type DATETIME
. On peut voir que l'insertion d'une ligne en utilisant NOW()
pour les trois colonnes donne le résultat attendu.
1 2 3 4 5 6 7 8 9 10 11 | -- Création d'une table de test toute simple CREATE TABLE testDate ( dateActu DATE, timeActu TIME, datetimeActu DATETIME ); INSERT INTO testDate VALUES (NOW(), NOW(), NOW()); SELECT * FROM testDate; |
dateActu |
timeActu |
datetimeActu |
---|---|---|
2011-10-26 |
11:22:10 |
2011-10-26 11:22:10 |
Timestamp Unix
Il existe encore une fonction qui peut donner des informations sur la date et l'heure actuelle, sous forme de timestamp Unix ; ce qui est donc le nombre de secondes écoulées depuis le premier janvier 1970, à 00:00:00. Il s'agit de UNIX_TIMESTAMP()
.
Je vous la donne au cas où, mais j'espère que vous ne vous en servirez pas pour stocker vos dates sous forme d'INT
avec un timestamp Unix !
1 | SELECT UNIX_TIMESTAMP(); |
UNIX_TIMESTAMP() |
---|
1319621754 |
En résumé
- La date du jour peut s'obtenir avec
CURDATE()
etCURRENT_DATE()
. - L'heure actuelle peut s'obtenir avec
CURTIME()
etCURRENT_TIME()
. - L'heure et la date actuelles peuvent s'obtenir avec
NOW()
,SYSDATE()
,LOCALTIME()
,CURRENT_TIMESTAMP()
,LOCALTIMESTAMP()
. - On peut insérer un
DATETIME
dans une colonneDATE
ouTIME
. MySQL ôtera la partie inutile.