Comment convertir entre formats horaires
Les formats de temps varient selon les systèmes, les API et les pays. Horodatages Unix dans les réponses d'API, ISO 8601 dans les bases de données, horloges 12 heures aux États-Unis, horloges 24 heures en Europe, convertir entre eux est un besoin constant pour les développeurs et toute personne travaillant avec des données internationales. Comprendre pourquoi chaque format existe, où il brille et où il mord rend la conversion un réflexe rapide plutôt qu'une source récurrente de bugs subtils.
Une brève histoire des formats de temps
Standardiser le temps est plus vieux qu'internet. En 1884, la Conférence internationale du méridien a établi l'heure moyenne de Greenwich et le méridien d'origine, ce qui a donné au monde une référence commune pour la première fois. L'horloge 24 heures s'est répandue dans l'aviation et le militaire pour la même raison : elle supprime l'ambiguïté AM/PM qui transforme une réservation à minuit en vol à midi.
Le temps Unix est arrivé avec le noyau Unix d'origine en 1971, comptant les secondes depuis le 1er janvier 1970 UTC ("l'epoch"). Le choix était pragmatique : un entier 32 bits pouvait couvrir des décennies, trier des horodatages revenait à trier des nombres, et calculer des intervalles était une soustraction. ISO 8601 est arrivé en 1988 pour standardiser le côté lisible : année-mois-jour en ordre gros-boutiste, T comme séparateur date/heure, et Z pour UTC. RFC 3339 (2002) est un profil plus restrictif d'ISO 8601 conçu pour les protocoles internet. RFC 2822 (2001) définit le format style courriel avec noms de jours et offsets. Chaque format résout un vrai problème ; aucun ne remplace les autres entièrement.
Formats de temps courants
Six formats couvrent presque tout ce que vous rencontrerez dans la nature. La première colonne est le nom que vous verrez dans la documentation ; la colonne d'exemple montre à quoi ressemble 14:30 le 7 avril 2024 UTC.
| Format | Exemple | Utilisé par |
|---|---|---|
| Horodatage Unix (secondes) | 1712502600 | API, bases de données, jetons JWT, lignes de log |
| Horodatage Unix (ms) | 1712502600000 | JavaScript, Java, Android |
| Horodatage Unix (microsecondes) | 1712502600000000 | Postgres, Kafka, OpenTelemetry |
| ISO 8601 / RFC 3339 | 2024-04-07T14:30:00Z | API JSON, bases de données, logs |
| RFC 2822 | Sun, 07 Apr 2024 14:30:00 +0000 | En-têtes de courriel, en-têtes HTTP |
| 24 heures | 14:30 | Europe, militaire, aviation |
| 12 heures | 2:30 PM | US, usage informel |
| Jour de l'année (julien) | 2024-098 | Avionique, données scientifiques |
| Date semaine | 2024-W14-7 | Planification industrielle, banque |
La plupart des équipes se fixent sur les millisecondes Unix pour le stockage et ISO 8601 pour le transit, avec des formats d'affichage choisis par locale. Le choix compte moins que la cohérence : choisissez un format principal, documentez-le, et convertissez aux bords.
Référence rapide de conversion
12 heures vers 24 heures
L'horloge 12 heures a deux particularités : 12 AM est minuit (le début du jour) et 12 PM est midi. Le tableau ci-dessous couvre les cas qui piègent les gens.
| 12 heures | 24 heures |
|---|---|
| 12:00 AM (minuit) | 00:00 |
| 1:00 AM | 01:00 |
| 11:59 AM | 11:59 |
| 12:00 PM (midi) | 12:00 |
| 12:01 PM | 12:01 |
| 1:00 PM | 13:00 |
| 6:00 PM | 18:00 |
| 11:59 PM | 23:59 |
Horodatages vers dates
Le convertisseur epoch traduit instantanément les horodatages Unix en dates lisibles et inversement. Le convertisseur détecte automatiquement les formats secondes (10 chiffres) et millisecondes (13 chiffres), vous pouvez donc coller une valeur de n'importe quelle source sans vous soucier de l'unité.
Une vérification de bon sens utile : divisez par 86400 (secondes dans un jour) puis ajoutez 1970 jours pour localiser mentalement n'importe quel horodatage. 1712502600 / 86400 ~ 19820 jours, soit environ 54 ans après 1970, ce qui place en 2024. Pas précis mais assez pour attraper les erreurs de facteur 1000 d'un coup d'œil.
Exemples de conversion en code
La plupart des développeurs ont éventuellement besoin de convertir des horodatages en code. Les API principales sont courtes :
- JavaScript,
new Date(1712502600 * 1000).toISOString()retourne2024-04-07T14:30:00.000Z. N'oubliez pas de multiplier par 1000 car leDateJavaScript attend des millisecondes. Dans l'autre sens :Math.floor(Date.now() / 1000)donne un horodatage en secondes. - Python,
datetime.fromtimestamp(1712502600, tz=timezone.utc).isoformat()retourne2024-04-07T14:30:00+00:00. Évitezutcfromtimestamp(); il retourne un datetime naïf que le reste de votre code traitera à tort comme local. - Go,
time.Unix(1712502600, 0).UTC().Format(time.RFC3339)retourne2024-04-07T14:30:00Z. Le paquet time de Go est inhabituel mais cohérent une fois que vous avez intégré la disposition de référenceMon Jan 2 15:04:05 MST 2006. - Shell,
date -u -d @1712502600 +"%Y-%m-%dT%H:%M:%SZ"sur GNU/Linux, oudate -u -r 1712502600 +"%Y-%m-%dT%H:%M:%SZ"sur BSD/macOS. La différence de drapeau est l'un des pièges multiplateformes les plus googlés. - Rust,
chrono::DateTime::<chrono::Utc>::from_timestamp(1712502600, 0).unwrap().to_rfc3339()retourne la même chaîne ISO. La bibliothèque standard a maintenantSystemTimemais chrono reste le choix pratique pour le formatage. - SQL (Postgres),
SELECT to_timestamp(1712502600) AT TIME ZONE 'UTC';retourne untimestamptz. MySQL utiliseFROM_UNIXTIME(); SQLite utilisedatetime(1712502600, 'unixepoch').
Un outil de conversion est plus rapide que n'importe lequel de ces one-liners quand vous n'avez qu'une seule valeur à traduire, ce qui est le cas la plupart du temps en débogage.
Pourquoi ISO 8601 gagne pour le stockage
ISO 8601 (et le profil RFC 3339) se trie correctement en tant que simple chaîne. 2024-04-07T14:30:00Z vient alphabétiquement avant 2024-04-07T15:00:00Z, qui vient avant 2024-04-08T00:00:00Z. Cette propriété vous permet de trier des horodatages sans les parser, de grouper des lignes de log avec sort | uniq -c, et de raisonner sur des plages avec de simples comparaisons de chaînes.
C'est aussi sans ambiguïté d'une manière que les formats régionaux ne sont pas. 04/07/2024 pourrait être le 7 avril (USA) ou le 4 juillet (la plupart de l'Europe) ; 2024-04-07 est le même dans toutes les locales. Pour l'échange machine à machine, ce manque d'ambiguïté vaut plus que toute autre considération de formatage.
Pièges courants à éviter
- Oublier le fuseau horaire,
2026-04-07 14:30est ambigu sans fuseau. Incluez toujoursZou un offset+00:00lors du stockage de chaînes ISO, et ne vous fiez jamais au fuseau par défaut du lecteur. - Mélanger secondes et millisecondes, un horodatage Unix à 10 chiffres est en secondes, un à 13 chiffres en millisecondes. Les mélanger produit des dates soit en 1970 soit dans un futur lointain. Les microsecondes (16 chiffres) et nanosecondes (19 chiffres) s'infiltrent aussi, anticipez-les.
- Compter sur l'heure locale dans les serveurs, si votre serveur est en UTC et votre utilisateur à Tokyo, stockez UTC et convertissez à l'affichage. Laisser le serveur deviner la locale mène presque toujours à des bugs quand les utilisateurs voyagent ou que l'heure d'été change.
- Parser avec de l'arithmétique de chaîne, ne découpez et ne concaténez pas les chaînes de date. Utilisez
Date.parse(),dateutil.parser,chrono, ou la bibliothèque standard de votre langage. Le parsing manuel casse sur les dates extrêmes, les années bissextiles et les offsets de fuseau. - Faire confiance à
new Date("2024-04-07"), JavaScript parse les chaînes de date seule comme minuit UTC, mais les chaînes date-heure sans fuseau comme minuit local. Le comportement diffère selon les navigateurs et versions Node. Incluez toujours unZou offset explicite. - Années à deux chiffres,
04/07/24pourrait être 1924, 2024 ou 2124 selon l'implémentation. Utilisez partout des années à quatre chiffres. - Transitions d'heure d'été, l'horloge locale saute une heure au printemps et en répète une à l'automne. Un ordonnanceur naïf peut exécuter une tâche deux fois ou pas du tout ces jours-là. Utilisez UTC pour la logique de planification et convertissez seulement pour l'affichage.
- Secondes intercalaires, le temps Unix prétend qu'elles n'existent pas en lissant ou répétant la seconde affectée. Le code qui compare des "secondes écoulées" peut brièvement diverger d'une horloge murale qui respecte les secondes intercalaires.
- Le problème de l'an 2038, le
time_tsigné 32 bits déborde le 19 janvier 2038. La plupart des systèmes modernes utilisent un temps 64 bits, mais les appareils embarqués hérités et les anciennes colonnes de base de données peuvent encore le rencontrer. Auditez partout où vous voyezINT4ouint32utilisé pour stocker des horodatages. - Formatage dépendant de la locale,
toLocaleString()en JavaScript et les fonctions équivalentes dans d'autres langages produisent des sorties différentes sur des machines différentes. Pour les horodatages lisibles par machine, utiliseztoISOString()ou équivalent ; pour l'affichage, formatez explicitement.
Outils et bibliothèques alternatives
Un convertisseur gère le cas ponctuel ; pour le code de production vous allez chercher une bibliothèque.
| Outil / bibliothèque | Langage | Force | À surveiller |
|---|---|---|---|
| Convertisseur web | Navigateur | Instantané, sans installation, gère les ambiguïtés courantes | Une valeur à la fois |
dateutil | Python | Parser tolérant, conscient des fuseaux | Plus lent que datetime pour le travail en masse |
arrow | Python | API conviviale, défauts ISO | Dépendance supplémentaire pour petits projets |
date-fns | JavaScript | Tree-shakable, immuable | Chaque fonction est son propre import |
dayjs | JavaScript | Petit, API compatible moment | Modèle de plugin pour les extras |
luxon | JavaScript | Fuseaux IANA de première classe | Bundle plus gros |
chrono | Rust | Types riches, RFC 3339 natif | Rythme de maintenance variable |
Joda-Time / java.time | Java | Le design de référence qui a influencé les autres | Évitez les vieux Date et Calendar |
NodaTime | C#/.NET | Instants, durées, calendriers proprement séparés | La migration depuis DateTime n'est pas triviale |
GNU date | Shell Linux | Parsing flexible avec -d | BSD/macOS utilise des drapeaux incompatibles |
La bonne bibliothèque dépend de votre stack ; la bonne discipline est la même partout : stocker UTC, transmettre ISO 8601, formater uniquement pour l'affichage, et ne jamais faire confiance à un horodatage sans fuseau explicite.
Vie privée et le convertisseur
Le convertisseur de format de temps tourne entièrement dans votre navigateur. Les horodatages que vous collez et les dates que vous générez ne quittent jamais la page. Il n'y a aucun journal serveur des valeurs converties, aucune analytique sur les formats populaires, et aucun moyen pour quiconque de lier une requête à votre IP. Les conversions de temps ne sont pas des données personnelles en elles-mêmes, mais les horodatages dans vos logs (heures de connexion, heures de transaction, fenêtres de planification) le sont souvent, et les passer par un convertisseur tiers pourrait divulguer des détails opérationnels. Faire le travail côté client garde cette information sur votre machine où elle appartient. Pour une tâche aussi routinière que basculer entre secondes et ISO 8601, le réglage de vie privée par défaut devrait être aucune transmission, aucune journalisation, aucun tiers dans la boucle.
Questions fréquentes
Qu'est-ce que le format ISO 8601 ?
ISO 8601 est le standard international pour représenter dates et heures. Il ressemble à 2026-04-07T14:30:00Z, où T sépare la date et l'heure, et Z indique l'UTC. Il est sans ambiguïté quelle que soit la locale.
Pourquoi les API utilisent-elles des horodatages Unix plutôt que des dates lisibles ?
Les horodatages Unix sont un seul nombre, facile à stocker, trier et comparer. Ils sont neutres vis-à-vis du fuseau horaire (toujours UTC) et prennent moins de place qu'une chaîne de date formatée. Le compromis : ils ne sont pas lisibles pour un humain.
Que signifie le Z en fin d'horodatage ?
Le Z signifie « Zulu time », un autre nom pour l'UTC (Coordinated Universal Time). Un horodatage finissant par Z est en UTC, pas en heure locale.
Comment convertir une heure 24 h en 12 h ?
Pour les heures 1-12, l'heure reste la même (ajoutez AM pour 0-11, PM pour 12). Pour 13-23, soustrayez 12 et ajoutez PM. 00:00 devient 12:00 AM (minuit). 12:00 devient 12:00 PM (midi).
What is the Year 2038 problem?
32-bit signed Unix timestamps overflow on 19 January 2038 at 03:14:07 UTC, after which they wrap around to negative values that look like dates in 1901. Most modern systems use 64-bit timestamps and are unaffected, but legacy embedded devices, old databases, and 32-bit time_t in some C code still need to be audited.
How are leap seconds handled in Unix time?
Unix time pretends leap seconds do not exist. The clock simply repeats or stretches the affected second, so a Unix timestamp is not a strict count of elapsed SI seconds. For most applications this is fine, but precision-timing code (astronomy, GPS, high-frequency trading) needs TAI or UTC with explicit leap-second handling.