Menu

Dates en SQLite : strftime, date(), datetime() et modificateurs

Comment SQLite stocke et manipule les dates : les cinq fonctions date/heure, les formats, les modificateurs et les bons choix de stockage pour garder vos requêtes rapides.

Cette page contient des éditeurs exécutables — modifiez, exécutez et voyez la sortie instantanément.

SQLite n'a pas vraiment de type date

C'est le piège classique quand on arrive de Postgres ou MySQL. SQLite ne connaît que cinq classes de stockage — NULL, INTEGER, REAL, TEXT, BLOB — et c'est tout. Pas de DATE, pas de DATETIME, pas de TIMESTAMP. Vous pouvez très bien écrire created_at DATETIME dans votre CREATE TABLE : SQLite l'acceptera sans broncher, mais la valeur finira stockée sous forme de texte ou de nombre.

En revanche, SQLite fournit toute une série de fonctions qui savent manipuler trois formats conventionnels :

  • Texte ISO 8601'2026-04-23', '2026-04-23 10:15:00', '2026-04-23T10:15:00.123Z'.
  • Timestamp Unix — nombre de secondes depuis le 1er janvier 1970 UTC, stocké en entier.
  • Jour julien — nombre de jours fractionnaires depuis 4714 av. J.-C., stocké en réel.

Choisissez-en un et tenez-vous-y. Le texte ISO 8601 reste le plus lisible et se trie correctement en tant que chaîne : c'est pour ça qu'il fait office de format par défaut.

Quatre manières de demander « maintenant » — date en texte, datetime en texte, secondes Unix, jour julien. Toutes désignent le même instant.

Les cinq fonctions de date

SQLite met à disposition cinq fonctions natives qui couvrent à peu près tous les besoins :

  • date(time, ...) — renvoie YYYY-MM-DD.
  • time(time, ...) — renvoie HH:MM:SS.
  • datetime(time, ...) — renvoie YYYY-MM-DD HH:MM:SS.
  • julianday(time, ...) — renvoie un réel (parfait pour calculer des écarts).
  • strftime(format, time, ...) — renvoie une chaîne au format de votre choix.

Chacune prend une valeur temporelle en premier argument, suivie d'autant de modificateurs que vous voulez.

À noter : 'unixepoch'. C'est le modificateur qui indique aux fonctions de date que l'entier passé est un timestamp Unix, et non un jour julien. Sans ce modificateur, SQLite considère par défaut que le nombre est un jour julien.

strftime : formater une date sur mesure

strftime est la fonction à tout faire pour le format de date sous SQLite. On retrouve les mêmes codes % qu'en C ou en Python :

Les codes que vous utiliserez le plus souvent :

  • %Y — année sur quatre chiffres.
  • %m — mois (01-12).
  • %d — jour du mois (01-31).
  • %H, %M, %S — heures, minutes, secondes.
  • %w — jour de la semaine (0=dimanche).
  • %j — jour de l'année (001-366).
  • %s — timestamp Unix.
  • %f — secondes fractionnaires (SS.SSS).

strftime sert aussi à extraire des morceaux d'une date — il n'existe pas de fonction EXTRACT ou YEAR() dédiée en SQLite. Il suffit de formater la date jusqu'à la partie qui vous intéresse, puis de la convertir en nombre si besoin :

strftime renvoie toujours du texte. Si vous voulez faire des calculs ou des comparaisons numériques, pense à l'envelopper dans CAST(... AS INTEGER).

Modificateurs : du calcul de dates sans opérateur

C'est cette fonctionnalité qui rend la gestion des dates en SQLite vraiment agréable. Après l'argument temporel, vous pouvez enchaîner autant de chaînes modificatrices que vous voulez : elles s'appliquent dans l'ordre où vous les écrivez.

Les modificateurs que vous utiliserez en permanence :

  • '+N days', '-N days', et leurs équivalents pour hours, minutes, seconds, months, years.
  • 'start of day', 'start of month', 'start of year' — pour tronquer à la borne correspondante.
  • 'weekday N' — saute au prochain jour de la semaine indiqué (0 = dimanche).
  • 'localtime' et 'utc' — pour passer d'un fuseau à l'autre.

L'astuce du « dernier jour du mois » — début du mois, plus un mois, moins un jour — vaut le coup d'être retenue par cœur. SQLite n'a pas de fonction LAST_DAY, mais en chaînant les modificateurs on obtient exactement le même résultat.

UTC ou heure locale dans SQLite

'now' renvoie toujours l'heure UTC. Si vous voulez l'heure locale, il faut le demander explicitement :

Le modificateur 'localtime' convertit une valeur UTC vers le fuseau local du système. À l'inverse, 'utc' part du principe que l'entrée est en heure locale et la convertit en UTC.

La règle d'or : stocker en UTC partout, et ne convertir en heure locale qu'au moment de l'affichage. Mélanger les fuseaux dans la base, c'est s'exposer à des bugs qui ressortent pile deux fois par an, quand l'heure d'été ou d'hiver change.

Comparer des dates et filtrer des intervalles en SQLite

Si vous stockez vos dates au format texte ISO 8601, les comparaisons et le BETWEEN fonctionnent tout seuls : l'ordre lexicographique de l'ISO 8601 correspond exactement à l'ordre chronologique. C'est précisément pour ça que c'est le format par défaut.

L'intervalle semi-ouvert (>= début, < fin) est un bon réflexe à prendre — ça évite tout de suite la question piège du genre « est-ce que minuit le 30 est compté ou pas ? ».

Pour récupérer « les 7 derniers jours », laissez SQLite calculer la borne pour vous :

Différences entre deux dates

SQLite n'a pas de DATEDIFF. Mais avec deux astuces, on couvre tous les cas :

Les écarts calculés avec julianday() sont exprimés en jours (avec une précision décimale). Il suffit donc de multiplier par 24 pour obtenir des heures, ou par 1440 pour des minutes. Avec strftime('%s', ...), les différences sont en secondes — pratique quand on veut un entier directement.

CAST(... AS INTEGER) tronque la partie fractionnaire des jours si vous souhaitez un nombre de jours entier :

Stocker les dates : choisissez un format et tenez-vous-y

Trois options raisonnables, classées selon la fréquence à laquelle vous devriez les choisir :

  1. Texte ISO 8601 (TEXT). Lisible dans les dumps, tri correct, compatible avec toutes les fonctions de date SQLite. Le choix par défaut.
  2. Secondes Unix (INTEGER). Compact, comparaisons rapides, aucune ambiguïté de fuseau horaire. Pratique quand vous avez des millions de lignes. Pour le relire, il faudra passer par datetime(col, 'unixepoch').
  3. Jour julien (REAL). Rarement utile, sauf si vous faites beaucoup d'arithmétique sur les dates et que vous voulez la précision sous-seconde dans une seule colonne.

Ce qu'il ne faut surtout pas faire : mélanger les formats dans une même colonne. Les fonctions de date avaleront les deux sans broncher, mais les index, les tris et les comparaisons partiront en vrille.

DEFAULT (datetime('now')) est l'équivalent SQLite de DEFAULT CURRENT_TIMESTAMP : chaque nouvelle ligne est automatiquement horodatée à l'heure UTC actuelle, sans la moindre ligne de code côté application.

Regrouper par période avec strftime

C'est précisément là que strftime prend tout son sens : pour regrouper les lignes par mois, par semaine ou par heure.

Même principe pour « commandes par heure de la journée », « inscriptions par jour de la semaine » ou « événements par minute » : on choisit une chaîne de format qui ne capture que la granularité voulue, on regroupe dessus, puis on agrège.

La suite : les fonctions d'agrégation

Tiens, puisqu'on parle de regroupement — ce COUNT(*) n'est que la plus simple des fonctions d'agrégation de SQLite. On va voir dans la prochaine section l'ensemble complet : SUM, AVG, MIN, MAX, et comment elles condensent plusieurs lignes en une seule valeur récapitulative.

Questions fréquentes

SQLite a-t-il un type DATE ou DATETIME ?

Non, SQLite n'a aucun type dédié pour les dates. On les stocke soit en TEXT au format ISO 8601 ('2026-04-23 10:15:00'), soit en INTEGER sous forme de timestamp Unix, soit en REAL sous forme de jour julien. Les fonctions intégrées acceptent ces trois formats et renvoient par défaut du texte ISO 8601.

Comment récupérer la date et l'heure courantes en SQLite ?

Utilisez date('now') pour la date du jour, time('now') pour l'heure, datetime('now') pour les deux, et strftime('%s', 'now') pour un timestamp Unix. Par défaut, le résultat est en UTC : ajoutez le modificateur 'localtime' pour passer en heure locale, comme datetime('now', 'localtime').

Comment ajouter des jours ou des mois à une date ?

Il suffit de passer un modificateur à n'importe quelle fonction date : date('2026-04-23', '+7 days'), date('now', '-1 month'), ou encore datetime('now', '+2 hours', '+30 minutes'). Les modificateurs s'enchaînent dans l'ordre, et les unités disponibles sont days, hours, minutes, seconds, months et years.

Comment calculer la différence entre deux dates ?

Pour des jours, faites julianday(end) - julianday(start) : les jours juliens étant des flottants, vous obtenez aussi les fractions de journée. Pour des secondes, soustrayez les timestamps Unix : strftime('%s', end) - strftime('%s', start). SQLite n'a pas de DATEDIFF, mais ces deux astuces couvrent à peu près tous les cas.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER