Skip to content
Retour au blog
Tutoriels

Que contient réellement une colonne timestamp PostgreSQL ?

Guide pratique sur le stockage timestamp vs timestamptz dans PostgreSQL, les pièges des fuseaux horaires et comment choisir le bon type.

Go Tools Team 6 min de lecture

Que contient réellement une colonne timestamp de PostgreSQL ?

PostgreSQL stocke à la fois timestamp et timestamptz sous forme d’un entier 64 bits représentant le nombre de microsecondes depuis le 1er janvier 1970 à 00:00:00 UTC. La différence réside uniquement dans l’étiquetage lors de l’affichage.

Pourquoi est-ce si trompeur ?

  • Deux colonnes peuvent afficher des résultats différents pour le même instant
  • Votre application insère 2025-07-29 10:00, mais une autre équipe lit 02:00
  • Les chaînes ISO du frontend ne correspondent pas aux logs du backend

Deux bocaux de pêches : l’un nu, l’autre étiqueté

Type SQLNom officielValeur stockéeComportement au SELECT
timestamptimestamp without time zonecompteur de microsecondes brutRestitué tel quel — Postgres ne devine jamais un fuseau
timestamptztimestamp with time zonemême compteurPostgres applique le TimeZone de session avant envoi

L’analogie

  • timestamp = un bocal de pêches sans étiquette d’origine. Vous savez que c’est du fruit, mais pas d’où ça vient.
  • timestamptz = un bocal fièrement tamponné « Made in UTC+8 ». Celui qui l’ouvre peut décider de convertir.

Sous le capot : un simple gros nombre

2000-01-01 00:00:00 UTC  → 0
2000-01-01 00:00:01 UTC  → 1 000 000
  • Unité : microseconde (un millionième de seconde)
  • Plage : 4713 av. J.-C. – 294 276 ap. J.-C.
  • Le stockage est identique pour les deux types ; seule l’interprétation change

Démo express : 15 secondes chrono

-- Le client pense en heure de Shanghai
SET TimeZone = 'Asia/Shanghai';

CREATE TABLE demo (
  created_ts timestamp,
  created_tz timestamptz
);

INSERT INTO demo VALUES ('2025-07-29 10:00', '2025-07-29 10:00');
RequêteRésultatExplication
SELECT created_ts FROM demo;2025-07-29 10:00:00Valeur brute, sans calcul TZ
SELECT created_tz FROM demo;2025-07-29 10:00:00+08Étiquette appliquée à la sortie
Après SET TimeZone = 'UTC';2025-07-29 02:00:00+00Même instant, autre regard

Pièges fréquents & remèdes rapides

1. Chaque utilisateur a sa montre

  • Cause : chaque client définit son propre TimeZone avec timestamptz
  • Remède : soit tout passer en timestamp avec un fuseau de référence, soit forcer SET TimeZone = 'UTC' à la connexion

2. Conserver l’heure « murale » avec le mauvais type

  • Agendas locaux (horaires de magasin, échéances) → timestamp
  • Flux internationaux (commandes, logs) → stockez l’UTC en timestamptz

3. APIs qui dérivent

  • Expédiez toujours les timestamptz en ISO 8601 avec l’offset (Z ou +08:00)
  • Le front formate selon le navigateur de l’utilisateur

Mémo : quel type choisir ?

Calendrier local → timestamp
Besoin mondial   → timestamptz (stockez en UTC)
  • Rapports financiers, plannings de cours → timestamp
  • Logs d’audit, commandes e-commerce → timestamptz

Vérification rapide avec Go Tools

BesoinOutilMode d’emploi
Inspecter la valeur epochConvertisseur d’époqueColler 1690622400, cliquer Convert
Comparer deux fuseauxConvertisseur de fuseauSaisir 10:00 Asia/Shanghai
Nettoyer un JSON rempli de datesFormateur JSONColler la charge, cliquer Embellir

Tous les utilitaires s’exécutent entièrement dans le navigateur — aucune donnée ne quitte votre machine.

En résumé

  • Les deux types temporels de Postgres sont des compteurs de microsecondes ; seule l’étiquette fait la différence
  • Se tromper de type mène à des horloges folles et des calculs erronés
  • Testez, convertissez et validez avec les bons outils pour gagner des heures de débogage

Articles connexes

Voir tous les articles