Guide pratique · PostgreSQL · BigQuery · Snowflake ·
Lecture : ~20 min
Teste ton niveau sur modai-lab.com/test-sql/
Pourquoi ce guide existe Un champ date stocké en VARCHAR. Une timezone ignorée dans un TIMESTAMP. Un DATEPART() appelé sur une chaßne de caractÚres.
Résultat : des dashboards faux. Sans message d'erreur. Sans alerte. Des KPIs qui mentent depuis des semaines.
Pourtant c'est Ă©vitable Ă 100%. Chaque format de date a un usage prĂ©cis â et les confondre coĂ»te des dĂ©cisions entiĂšres Ă revoir.
Ce guide couvre :
Les 5 formats et quand les utiliser exactement
Les erreurs de conversion les plus courantes
La gestion des timezones sur PostgreSQL, BigQuery et Snowflake
Un prompt Claude pour auditer tes champs date en 2 minutes
đ§Ș Calibre ton niveau avant de commencer Sais-tu dĂ©jĂ quelle est la diffĂ©rence entre TIMESTAMP et TIMESTAMPTZ ? Fais le test en 5 minutes et reçois ton score instantanĂ©ment. đ Faire le test sur modai-lab.com/test-sql/
Résultat en direct · Niveau calibré · Parcours personnalisé_
Ce que c'est : une date sans heure. Pas de timezone. Pas d'heure. Juste le jour.
Plage : 0001-01-01 â 9999-12-31
-- â
Créer une colonne DATE
CREATE TABLE events (
id INT ,
date_evenement DATE -- ex: 2024-11-03
);
Â
-- â
Usages typiques
SELECT * FROM orders WHERE date_commande = '2024-11-03' ;
SELECT * FROM employees WHERE date_naissance BETWEEN '1990-01-01' AND '2000-12-31' ;
SELECT DATE '2024-11-03' + INTERVAL '30 days' ; -- calcul de date
formats-date-sql-guide-complet · 01 Quand l'utiliser :
Dates d'anniversaire, dates de naissance
Dates de commande (quand l'heure n'a pas d'importance métier)
Dates de reporting (fin de mois, trimestre, exercice fiscal)
Dates d'échéance (factures, contrats, abonnements)
Quand NE PAS l'utiliser :
Logs et Ă©vĂ©nements systĂšme â TIMESTAMP
Interactions utilisateur avec heure prĂ©cise â DATETIME ou TIMESTAMP
Tout ce qui implique des fuseaux horaires diffĂ©rents â TIMESTAMPTZ
Ce que c'est : une heure sans date. Rarement utilisé seul en analytique.
-- â
Usages légitimes (rares)
CREATE TABLE schedules (
heure_ouverture TIME , -- ex: 09:00:00
heure_fermeture TIME
);
Â
-- Calculer la durée d'ouverture
SELECT heure_fermeture - heure_ouverture AS duree FROM schedules;
formats-date-sql-guide-complet · 02 Quand l'utiliser : horaires récurrents indépendants de la date (horaires d'ouverture, plannings hebdomadaires).
En pratique : trĂšs peu utilisĂ© en data analytics. Si tu as besoin d'une heure, elle est presque toujours associĂ©e Ă une date â TIMESTAMP.
Ce que c'est : une date ET une heure, stockées telles quelles, sans information de timezone.
Attention : le nom varie selon le SGBD.
SGBD
Nom du type
Stockage
PostgreSQL
TIMESTAMP
Date + heure, pas de timezone
MySQL
DATETIME
Date + heure, pas de timezone
BigQuery
DATETIME
Date + heure civile, pas de timezone
Snowflake
TIMESTAMP_NTZ
Date + heure, no timezone
SQL Server
DATETIME2
Date + heure, pas de timezone
-- â
Usages typiques
CREATE TABLE blog_posts (
id INT ,
published_at TIMESTAMP -- ex: 2024-11-03 14:30:00
);
Â
-- Filtrer par période
SELECT * FROM blog_posts
WHERE published_at >= '2024-01-01 00:00:00'
AND published_at < '2025-01-01 00:00:00' ;
Â
-- Tronquer à la journée
SELECT DATE_TRUNC('day' , published_at) AS jour, COUNT (*) AS nb_articles
FROM blog_posts
GROUP BY ;
formats-date-sql-guide-complet · 03 Quand l'utiliser :
Données d'une seule région géographique (pas de timezone ambiguë)
Dates d'import ETL, dates de transformation
ĂvĂ©nements dont la timezone est dĂ©jĂ normalisĂ©e en amont
PiĂšge classique :
-- â Stocker des Ă©vĂ©nements de plusieurs pays en TIMESTAMP sans timezone
-- Un user de Paris (UTC+1) et un de New York (UTC-5) ont tous les deux
-- un login Ă "09:00:00" â mais ce n'est pas le mĂȘme moment
Â
-- â
Utiliser TIMESTAMPTZ pour les événements multi-régions
formats-date-sql-guide-complet · 04 · PiÚge classique : Ce que c'est : une date, une heure ET une timezone. Le type le plus robuste pour les applications multi-pays.
SGBD
Nom du type
Comportement
PostgreSQL
TIMESTAMPTZ
Stocke en UTC, affiche en timezone locale
BigQuery
TIMESTAMP
Stocke en UTC
Snowflake
TIMESTAMP_TZ
Stocke l'offset timezone
SQL Server
DATETIMEOFFSET
Stocke avec offset
-- â
Création
CREATE TABLE user_sessions (
id INT ,
started_at TIMESTAMPTZ , -- ex: 2024-11-03 14:30:00+01
ended_at TIMESTAMPTZ
);
Â
-- PostgreSQL : conversion de timezone
SELECT
started_at AT TIME ZONE 'UTC' AS heure_utc,
started_at AT TIME ZONE 'Europe/Paris' AS heure_paris,
started_at AT TIME ZONE 'America/New_York' AS heure_ny
FROM user_sessions;
Â
-- BigQuery : conversion de timezone
SELECT
started_at,
DATETIME(started_at, 'Europe/Paris' ) AS heure_paris
FROM user_sessions;
formats-date-sql-guide-complet · 05 Quand l'utiliser :
Applications avec des utilisateurs dans plusieurs fuseaux horaires
Logs serveur et événements systÚme
Toute donnée qui sera analysée dans différents fuseaux horaires
ĂvĂ©nements critiques oĂč le moment exact compte (transactions financiĂšres, audits)
đĄ RĂšgle gĂ©nĂ©rale : en cas de doute, utilise TIMESTAMPTZ. Stocker en UTC et convertir Ă l'affichage est toujours plus sĂ»r que l'inverse.
Ce que c'est : une durée, pas un moment. La différence entre deux dates.
-- â
Créer des intervalles
SELECT INTERVAL '30 days' ;
SELECT INTERVAL '2 hours 30 minutes' ;
SELECT INTERVAL '1 year 3 months' ;
Â
-- â
Ajouter une durée à une date
SELECT '2024-01-01' ::DATE + INTERVAL '30 days' ; -- 2024-01-31
SELECT NOW () - INTERVAL '7 days' ; -- il y a 7 jours
Â
-- â
Calculer une durée entre deux dates
SELECT
user_id,
created_at,
first_order_at,
first_order_at - created_at AS delai_premier_achat
FROM users
JOIN (SELECT user_id, MIN (created_at) AS first_order_at FROM orders GROUP BY user_id) o
USING (user_id);
Â
-- â
Filtrer par durée relative
SELECT * FROM orders WHERE created_at > NOW () - INTERVAL '30 days' ;
SELECT * FROM users WHERE created_at BETWEEN NOW () - INTERVAL '1 year' AND NOW ();
formats-date-sql-guide-complet · 06 Quand l'utiliser :
Calculs de délais (temps entre inscription et premier achat)
Filtres relatifs ("les 30 derniers jours")
Calculs de durée d'abonnement, de cycle de vente
đ§Ș Teste tes rĂ©flexes sur les 5 formats
Les formats de date sont systématiquement testés en entretien data.
Modai Lab te soumet des cas rĂ©els avec des donnĂ©es imparfaites â score immĂ©diat.
đ Pratiquer sur modai-lab.com Exercices interactifs · Datasets rĂ©els · Feedback instantanĂ©
PARTIE 2 â Les erreurs de conversion les plus courantes â Erreur 1 â Date stockĂ©e en VARCHAR (l'erreur la plus coĂ»teuse) Le problĂšme
-- â Colonne date stockĂ©e en texte
CREATE TABLE orders (
id INT ,
order_date VARCHAR () -- ex: "2024-11-03" ou "03/11/2024" ou "Nov 3, 2024"
);
Â
-- Tri faux : ordre alphabétique, pas chronologique
SELECT * FROM orders ORDER BY order_date;
-- "2024-09-01" > "2024-11-03" en VARCHAR car "9" > "1"
Â
-- Calcul impossible
SELECT order_date + INTERVAL '30 days' FROM orders; -- erreur
Â
-- Comparaison piégeuse
SELECT * FROM orders WHERE order_date > '2024-10-01' ;
-- Fonctionne par chance si le format est YYYY-MM-DD
-- Ăchoue silencieusement si le format est DD/MM/YYYY
formats-date-sql-guide-complet · 07 · Le problÚme La correction
-- â
Migration : VARCHAR â DATE
-- Ătape 1 : vĂ©rifier les formats prĂ©sents
SELECT DISTINCT
CASE
WHEN order_date ~ '^\d{4}-\d{2}-\d{2}$' THEN 'YYYY-MM-DD'
WHEN order_date ~ '^\d{2}/\d{2}/\d{4}$' THEN 'DD/MM/YYYY'
WHEN order_date ~ '^\d{2}-\d{2}-\d{4}$' THEN 'DD-MM-YYYY'
ELSE 'Format inconnu : ' || order_date
END AS format_detecte,
COUNT (*) AS n
FROM orders
GROUP BY ;
Â
-- Ătape 2 : convertir selon le format
ALTER TABLE orders ADD COLUMN order_date_clean DATE ;
Â
UPDATE orders
SET order_date_clean =
CASE
WHEN order_date ~ '^\d{4}-\d{2}-\d{2}$'
THEN TO_DATE(order_date, 'YYYY-MM-DD' )
WHEN order_date ~ '^\d{2}/\d{2}/\d{4}$'
THEN TO_DATE(order_date, 'DD/MM/YYYY' )
END ;
Â
-- Ătape 3 : valider avant de supprimer l'ancienne colonne
SELECT COUNT (*) AS null_apres_conversion FROM orders WHERE order_date_clean IS NULL ;
formats-date-sql-guide-complet · 08 · La correction â Erreur 2 â Timezone ignorĂ©e dans les calculs Le problĂšme
-- â Comparer des timestamps de timezones diffĂ©rentes sans conversion
-- Table orders : created_at en UTC
-- Rapport : "commandes du jour" pour une équipe parisienne
Â
SELECT COUNT (*) AS commandes_aujourd_hui
FROM orders
WHERE DATE (created_at) = CURRENT_DATE;
-- Si le serveur est en UTC et l'équipe est à Paris (UTC+1) :
-- Les commandes de 23h00 à 00h00 heure de Paris sont assignées au mauvais jour
formats-date-sql-guide-complet · 09 · Le problĂšme -- â
Toujours convertir avant de tronquer à la journée
Â
-- PostgreSQL
SELECT COUNT (*) AS commandes_aujourd_hui
FROM orders
WHERE DATE (created_at AT TIME ZONE 'Europe/Paris' ) = CURRENT_DATE;
Â
-- BigQuery
SELECT COUNT (*) AS commandes_aujourd_hui
FROM orders
WHERE DATE (created_at, 'Europe/Paris' ) = CURRENT_DATE();
Â
-- Snowflake
SELECT COUNT (*) AS commandes_aujourd_hui
FROM orders
WHERE DATE (CONVERT_TIMEZONE('UTC' , 'Europe/Paris' , created_at)) = CURRENT_DATE();
formats-date-sql-guide-complet · 10 L'impact concret :
-- Mesurer l'écart entre les deux approches
WITH
sans_tz AS (
SELECT DATE (created_at) AS jour, COUNT (*) AS n
FROM orders
GROUP BY
),
avec_tz AS (
SELECT DATE (created_at AT TIME ZONE 'Europe/Paris' ) AS jour, COUNT (*) AS n
FROM orders
GROUP BY
)
SELECT
s.jour,
s.n AS sans_conversion,
a.n AS avec_conversion_paris,
s.n - a.n AS ecart
FROM sans_tz s
JOIN avec_tz a ON s.jour = a.jour
WHERE s.n != a.n
ORDER BY s.jour;
formats-date-sql-guide-complet · 11 · L'impact concret : â Erreur 3 â Conversion implicite VARCHAR â DATE Le problĂšme
-- â Comparaison qui force une conversion implicite
SELECT * FROM orders WHERE created_at = '2024-11-03' ;
-- created_at est TIMESTAMP, '2024-11-03' est une chaĂźne
-- Selon le SGBD, ça peut fonctionner... ou pas, ou donner un résultat faux
Â
-- â Fonction de date sur une chaĂźne de caractĂšres
SELECT YEAR(order_date) FROM orders;
-- Si order_date est VARCHAR, certains SGBD convertissent silencieusement
-- d'autres retournent NULL, d'autres plantent
formats-date-sql-guide-complet · 12 · Le problĂšme -- â
Toujours caster explicitement
SELECT * FROM orders
WHERE created_at >= '2024-11-03' ::DATE
AND created_at < '2024-11-04' ::DATE ;
Â
-- Ou avec BETWEEN sur des dates castées
SELECT * FROM orders
WHERE DATE (created_at) = '2024-11-03' ::DATE ;
Â
-- Caster une chaĂźne en date proprement
SELECT TO_DATE('03/11/2024' , 'DD/MM/YYYY' ) AS date_convertie; -- PostgreSQL
SELECT PARSE_DATE('%d/%m/%Y' , '03/11/2024' ) AS date_convertie; -- BigQuery
SELECT TO_DATE('03/11/2024' , 'DD/MM/YYYY' ) AS date_convertie; -- Snowflake
formats-date-sql-guide-complet · 13 Le problÚme
-- DATE_TRUNC : tronque Ă un niveau de granularitĂ© â retourne une date/timestamp
-- EXTRACT (ou DATE_PART) : extrait un composant â retourne un nombre
Â
-- â Confondre les deux dans une agrĂ©gation
SELECT EXTRACT('month' FROM created_at) AS mois, SUM (montant)
FROM orders
GROUP BY
ORDER BY ;
-- Retourne les mois 1 à 12, mais mélange TOUTES les années
-- Janvier 2023 + Janvier 2024 = un seul "mois 1"
Â
-- â
DATE_TRUNC pour grouper par période sans mélanger les années
SELECT DATE_TRUNC('month' , created_at) AS mois, SUM (montant)
FROM orders
GROUP BY
ORDER BY ;
-- Retourne une ligne par mois/année : 2023-01, 2023-02, ..., 2024-01
formats-date-sql-guide-complet · 14 · Le problÚme -- Référence complÚte des fonctions par SGBD
Â
-- TRONQUER Ă UNE PĂRIODE
-- PostgreSQL
DATE_TRUNC('year' /'month' /'week' /'day' /'hour' , col)
Â
-- BigQuery
DATE_TRUNC(col, YEAR/MONTH/WEEK/DAY)
TIMESTAMP_TRUNC(col, YEAR/MONTH/WEEK/DAY/HOUR)
Â
-- Snowflake
DATE_TRUNC('year' /'month' /'week' /'day' /'hour' , col)
Â
-- EXTRAIRE UN COMPOSANT
-- PostgreSQL
EXTRACT(year/month/day/hour FROM col)
DATE_PART('year' /'month' /'day' /'hour' , col)
Â
-- BigQuery
EXTRACT(YEAR/MONTH/DAY/HOUR FROM col)
Â
-- Snowflake
EXTRACT(year/month/day/hour FROM col)
DATE_PART('year' /'month' /'day' /'hour' , col)
YEAR(col) / MONTH(col) / DAY(col)
formats-date-sql-guide-complet · 15 â Erreur 5 â Calcul de durĂ©e avec soustraction directe Le problĂšme
-- â Soustraction qui retourne un type inattendu selon le SGBD
SELECT created_at - first_order_at FROM users;
-- PostgreSQL : retourne un INTERVAL
-- MySQL : retourne un nombre (différence en secondes ou en jours selon les types)
-- BigQuery : retourne une erreur sur TIMESTAMP, nécessite TIMESTAMP_DIFF
Â
-- â Comparer des durĂ©es sans normaliser
SELECT user_id, created_at - first_order_at AS delai
FROM users
WHERE created_at - first_order_at > ;
-- "30" en quoi ? Jours ? Secondes ? Heures ?
-- Comportement non déterministe selon le SGBD
formats-date-sql-guide-complet · 16 · Le problĂšme -- â
Calculer des durées de façon explicite et portable
Â
-- PostgreSQL : EXTRACT sur un INTERVAL
SELECT
user_id,
EXTRACT(EPOCH FROM (first_order_at - created_at)) / AS delai_jours
FROM users;
Â
-- BigQuery : TIMESTAMP_DIFF ou DATE_DIFF
SELECT
user_id,
TIMESTAMP_DIFF(first_order_at, created_at, DAY) AS delai_jours
FROM users;
Â
-- Snowflake : DATEDIFF
SELECT
user_id,
DATEDIFF('day' , created_at, first_order_at) AS delai_jours
FROM users;
Â
-- SQL Server : DATEDIFF
SELECT
user_id,
DATEDIFF(day, created_at, first_order_at) AS delai_jours
FROM users;
formats-date-sql-guide-complet · 17 PARTIE 3 â Gestion des timezones par SGBD PostgreSQL â Le plus complet -- Voir la timezone du serveur
SHOW timezone;
Â
-- Changer de timezone pour une session
SET timezone = 'Europe/Paris' ;
Â
-- Voir toutes les timezones disponibles
SELECT * FROM pg_timezone_names ORDER BY name;
Â
-- Convertir un TIMESTAMP en TIMESTAMPTZ
SELECT '2024-11-03 14:30:00' ::TIMESTAMP AT TIME ZONE 'Europe/Paris' ;
-- Retourne : 2024-11-03 13:30:00+00 (converti en UTC)
Â
-- Convertir d'une timezone Ă une autre
SELECT created_at AT TIME ZONE 'UTC' AT TIME ZONE 'America/New_York' AS heure_ny
FROM orders;
Â
-- AT TIME ZONE sur un TIMESTAMP (sans tz) : interprÚte comme étant dans cette tz
-- AT TIME ZONE sur un TIMESTAMPTZ : convertit vers cette tz
-- Attention : deux usages diffĂ©rents du mĂȘme opĂ©rateur !
Â
-- Tronquer par jour dans la timezone du user
SELECT
user_id,
DATE_TRUNC('day' , created_at AT TIME ZONE user_timezone) AS jour_local,
COUNT (*) AS nb_events
FROM events e
JOIN users u ON e.user_id = u.id
GROUP BY , ;
formats-date-sql-guide-complet · 18 BigQuery â Timezone dans chaque fonction -- BigQuery n'a pas de timezone de session
-- La timezone se spécifie dans chaque fonction
Â
-- TIMESTAMP stocké en UTC, toujours
-- DATETIME = valeur civile sans timezone (à éviter pour les données globales)
Â
-- Convertir un TIMESTAMP vers une timezone
SELECT
event_timestamp,
DATETIME(event_timestamp, 'Europe/Paris' ) AS heure_paris,
DATE (event_timestamp, 'Europe/Paris' ) AS date_paris
FROM events;
Â
-- Tronquer par semaine dans une timezone
SELECT
TIMESTAMP_TRUNC(event_timestamp, WEEK, 'Europe/Paris' ) AS semaine_paris,
COUNT (*) AS nb_events
FROM events
GROUP BY ;
Â
-- Créer un TIMESTAMP à partir d'une DATETIME locale
SELECT TIMESTAMP ('2024-11-03 14:30:00' , 'Europe/Paris' ) AS ts_utc;
-- Retourne : 2024-11-03 13:30:00 UTC
Â
-- Différence entre deux TIMESTAMP dans une timezone
SELECT TIMESTAMP_DIFF(
TIMESTAMP ('2024-11-03 18:00:00' , 'Europe/Paris' ),
TIMESTAMP ('2024-11-03 09:00:00' , 'Europe/Paris' ),
HOUR
) AS heures_travaillees; -- retourne 9
formats-date-sql-guide-complet · 19 Snowflake â Trois types de TIMESTAMP -- Snowflake a 3 types de TIMESTAMP :
-- TIMESTAMP_NTZ : pas de timezone (équivalent DATETIME)
-- TIMESTAMP_LTZ : timezone locale (session parameter)
-- TIMESTAMP_TZ : stocke l'offset timezone avec la valeur
Â
-- Voir et changer la timezone de session
SHOW PARAMETERS LIKE 'TIMEZONE' ;
ALTER SESSION SET TIMEZONE = 'Europe/Paris' ;
Â
-- Convertir une timezone
SELECT CONVERT_TIMEZONE('UTC' , 'Europe/Paris' , created_at) AS heure_paris
FROM events;
Â
-- Convertir de Paris vers New York
SELECT CONVERT_TIMEZONE('Europe/Paris' , 'America/New_York' , created_at) AS heure_ny
FROM events;
Â
-- Tronquer par jour dans une timezone
SELECT
DATE_TRUNC('day' , CONVERT_TIMEZONE('Europe/Paris' , created_at)) AS jour_paris,
COUNT (*) AS nb_events
FROM events
GROUP BY ;
Â
-- DATEDIFF dans Snowflake
SELECT DATEDIFF('day' , '2024-01-01' ::DATE , '2024-12-31' ::DATE ) AS nb_jours;
-- Retourne : 365
formats-date-sql-guide-complet · 20 Tableau de rĂ©fĂ©rence â Les fonctions date par SGBD OpĂ©ration
PostgreSQL
BigQuery
Snowflake
Tronquer à la journée
DATE_TRUNC('day', col)
DATE_TRUNC(col, DAY)
DATE_TRUNC('day', col)
Extraire l'année
EXTRACT(year FROM col)
EXTRACT(YEAR FROM col)
YEAR(col)
Différence en jours
EXTRACT(EPOCH FROM (b-a))/86400
DATE_DIFF(b, a, DAY)
DATEDIFF('day', a, b)
Ajouter 30 jours
col + INTERVAL '30 days'
DATE_ADD(col, INTERVAL 30 DAY)
DATEADD('day', 30, col)
Convertir timezone
col AT TIME ZONE 'tz'
DATETIME(col, 'tz')
CONVERT_TIMEZONE('tz', col)
Date courante
CURRENT_DATE
CURRENT_DATE()
CURRENT_DATE()
Timestamp courant
NOW()
CURRENT_TIMESTAMP()
CURRENT_TIMESTAMP()
Cast chaĂźne â date
TO_DATE(col, 'fmt')
PARSE_DATE('%fmt', col)
TO_DATE(col, 'fmt')
đ§Ș Teste la gestion des timezones en conditions rĂ©elles
Les erreurs de timezone sont les plus difficiles Ă dĂ©tecter â les rĂ©sultats semblent plausibles.
Modai Lab simule ces cas avec des données multi-pays et des timestamps UTC.
đ Tester sur modai-lab.com/test-sql/
Score immédiat · Explication des erreurs · Niveau calibré
PARTIE 4 â Prompt Claude pour auditer tes champs date en 2 minutes Copie ce prompt avec le schĂ©ma de ta table pour obtenir un audit complet.
Prompt d'audit complet Tu es un expert SQL data quality. Audite les champs date du schéma suivant
et identifie tous les risques potentiels.
Â
SCHĂMA Ă AUDITER :
[coller ton CREATE TABLE ou la liste de tes colonnes]
Â
CONTEXTE :
- SGBD utilisé : [PostgreSQL / BigQuery / Snowflake / autre]
- Utilisateurs dans : [une seule région / plusieurs pays / global]
- Usage principal : [reporting interne / dashboard client / ETL / autre]
Â
Analyse les points suivants :
Â
1. TYPES DE COLONNES
- Quels champs date sont stockés en VARCHAR ou en type incorrect ?
- Quels champs devraient utiliser TIMESTAMPTZ plutĂŽt que TIMESTAMP ?
- Y a-t-il des champs durée stockés en INT ou VARCHAR ?
Â
2. RISQUES TIMEZONE
- Quels champs sont à risque si les données viennent de plusieurs fuseaux ?
- Quelle timezone de référence recommandes-tu pour ce contexte ?
- Comment convertir les champs existants sans casser les données ?
Â
3. CALCULS Ă RISQUE
- Quelles requĂȘtes sur ces champs sont susceptibles de mĂ©langer les annĂ©es ?
- Y a-t-il des risques de conversion implicite VARCHAR â DATE ?
- Comment calculer des durées de façon portable entre SGBD ?
Â
4. RECOMMANDATIONS PRIORITAIRES
- Les 3 modifications les plus urgentes
- La requĂȘte de migration pour chaque modification
- Comment valider que la migration n'a pas cassé les données
Â
Format : une section par point, â pour les risques identifiĂ©s, â
pour les bonnes pratiques.
formats-date-sql-guide-complet · 21 Prompt rapide (version 30 secondes) Audite les champs date de ce schéma SQL pour identifier :
- Les types incorrects (VARCHAR, INT Ă la place de DATE/TIMESTAMP)
- Les risques timezone (TIMESTAMP sans tz sur données multi-pays)
- Les calculs de durée non portables
- Les recommandations prioritaires avec les requĂȘtes de migration
Â
SGBD : [PostgreSQL / BigQuery / Snowflake]
Schéma : [coller]
formats-date-sql-guide-complet · 22 RequĂȘtes de diagnostic Ă lancer sur ta base -- PostgreSQL : inspecter les types des colonnes date
SELECT
table_name,
column_name,
data_type,
CASE
WHEN data_type IN ('character varying' , 'text' , 'char' ) THEN 'â ïž Potentiellement une date stockĂ©e en texte'
WHEN data_type = 'timestamp without time zone' THEN 'â ïž VĂ©rifier si timezone nĂ©cessaire'
WHEN data_type = 'timestamp with time zone' THEN 'â
Timezone gérée'
WHEN data_type = 'date' THEN 'â
Date sans heure'
WHEN data_type = 'integer' THEN 'â ïž Potentiellement un timestamp Unix stockĂ© en INT'
ELSE data_type
END AS recommandation
FROM information_schema.columns
WHERE table_schema = 'public'
AND (
data_type IN ('date' , 'timestamp without time zone' , 'timestamp with time zone' )
OR column_name ILIKE '%date%'
OR column_name ILIKE '%time%'
OR column_name ILIKE '%at'
OR column_name ILIKE '%_on'
)
ORDER BY table_name, column_name;
formats-date-sql-guide-complet · 23 -- Détecter les colonnes VARCHAR qui contiennent des dates
SELECT
column_name,
COUNT (*) AS total,
COUNT (CASE WHEN value ~ '^\d{4}-\d{2}-\d{2}' THEN END ) AS format_iso,
COUNT (CASE WHEN value ~ '^\d{2}/\d{2}/\d{4}' THEN END ) AS format_fr,
COUNT (CASE WHEN value ~ '^\d{2}-\d{2}-\d{4}' THEN END ) AS format_eu,
COUNT (CASE WHEN value !~ '\d' THEN END ) AS non_numerique
FROM (
-- Adapter avec ta colonne VARCHAR suspectée
SELECT 'order_date' AS column_name, order_date::TEXT AS value FROM orders
) t
GROUP BY column_name;
formats-date-sql-guide-complet · 24 Format
Usage
Timezone
Exemple
DATE
ĂvĂ©nements sans heure
Non
2024-11-03
TIME
Horaires récurrents
Non
09:00:00
TIMESTAMP
ĂvĂ©nements mono-rĂ©gion
Non
2024-11-03 14:30:00
TIMESTAMPTZ
ĂvĂ©nements multi-pays
Oui (UTC)
2024-11-03 13:30:00+00
INTERVAL
Durées et calculs
N/A
30 days / 2 hours
â
Checklist d'audit de tes champs date â Aucun champ date n'est stockĂ© en VARCHAR ou INT
â Les Ă©vĂ©nements multi-rĂ©gions utilisent TIMESTAMPTZ (pas TIMESTAMP)
â Les dashboards convertissent vers la timezone locale avant de tronquer Ă la journĂ©e
â DATE_TRUNC est utilisĂ© pour grouper par pĂ©riode (pas EXTRACT qui mĂ©lange les annĂ©es)
â Les calculs de durĂ©e utilisent les fonctions natives du SGBD (pas la soustraction directe)
â Les imports de donnĂ©es valident le format date avant insertion
â Une timezone de rĂ©fĂ©rence est documentĂ©e pour chaque table de faits
đ Pratiquer sur Modai Lab Les erreurs de date ne se voient pas dans le code. Elles se voient dans les donnĂ©es â quand il est trop tard. La seule façon de les Ă©viter est de les avoir rencontrĂ©es en pratique avant.
đ modai-lab.com/test-sql/ â Exercices SQL sur des donnĂ©es rĂ©elles avec des dates imparfaites
Guide offert suite au post LinkedIn · EntraĂźnez-vous sur modai-lab.com/test-sql/ · Partagez librement â»ïž