Timestamp Unix : secondes ou millisecondes ?
Distinguez les timestamps Unix en secondes et millisecondes, évitez les dates de 1970 et convertissez chaque unité sans ambiguïté.
Tout développeur a déjà rencontré cette anomalie déroutante : vous enregistrez un horodatage dans votre base de données, vous le transmettez à votre interface web, et au lieu d'afficher la date d'aujourd'hui, l'écran affiche 20 janvier 1970 ou 31 décembre 1969. Dans l'autre sens, un service backend peut rejeter la valeur comme hors plage.
Ces anomalies proviennent d'une source unique et omniprésente de confusion en ingénierie logicielle : la divergence entre les timestamps Unix exprimés en secondes et ceux exprimés en millisecondes.
Bien que les deux formats mesurent le temps écoulé depuis l'époque Unix (le 1er janvier 1970 à minuit UTC), les systèmes d'exploitation historiques, les bibliothèques C et de nombreuses APIs comptent ce temps en secondes, tandis que JavaScript et Java utilisent couramment les millisecondes. Transmettre un timestamp à 10 chiffres à une fonction qui en attend 13 induit un facteur d'erreur de 1 000.
Vous pouvez analyser, convertir et formater vos horodatages dans les deux échelles instantanément à l'aide du Convertisseur de Timestamp de ToolPorta. Ce guide décortique le fonctionnement de l'époque Unix, détaille les fondements mathématiques séparant les horodatages à 10 et 13 chiffres, analyse les causes racines des bugs les plus fréquents en production, fournit un algorithme de détection heuristique automatique et détaille les meilleures pratiques pour concevoir des APIs temporelles robustes.
Qu'est-ce qu'un timestamp Unix ?#
Un timestamp Unix (également appelé temps POSIX ou temps Epoch) est un entier représentant la durée totale écoulée depuis l'époque Unix :
Par convention, les secondes intercalaires sont ignorées ; chaque journée en temps Unix correspond rigoureusement à 86 400 secondes.
Le temps Unix est fondamentalement indépendant des fuseaux horaires. Un timestamp représente un instant absolu et universel sur l'ensemble du globe. Qu'un utilisateur consulte cet instant depuis Tokyo, Paris, Londres ou Montréal, la valeur numérique sous-jacente est rigoureusement identique. Les fuseaux horaires, les passages à l'heure d'été/hiver et le formatage du calendrier ne sont que des opérations de présentation destinées à la lecture humaine.
La différence fondamentale : 10 chiffres vs 13 chiffres#
La distinction essentielle entre les deux formats repose sur l'unité de granularité retenue :
| Attribut | Secondes Unix (s) | Millisecondes Unix (ms) |
|---|---|---|
| Unité de mesure | Seconde (1 s) | Milliseconde (0,001 s) |
| Longueur standard | 10 chiffres (ère contemporaine) | 13 chiffres (ère contemporaine) |
| Exemple pour 2026-10-01 00:00:00 UTC | 1790812800 | 1790812800000 |
| Ordre de grandeur | Environ 1,7 × 10^9 | Environ 1,7 × 10^12 |
| Opération de conversion | Multiplier par 1 000 pour obtenir les ms | Diviser par 1 000 pour obtenir les s |
| Précision | Résolution à la seconde | Résolution sub-seconde (milliseconde) |
| Écosystèmes dominants | Linux, C/POSIX, Python time.time(), MySQL, PHP | JavaScript/Node.js, Java, Android, MongoDB |
L'échelle à 10 chiffres : les secondes Unix#
Pendant plus de cinq décennies, les systèmes d'exploitation Unix, les bibliothèques C standard (time_t) et les normes POSIX ont mesuré le temps exclusivement en secondes. À notre époque, tout timestamp Unix en secondes comporte exactement 10 chiffres décimaux, débutant par 1 (par exemple, 1704067200 correspond au 1er janvier 2024 à 00:00:00 UTC).
Les horodatages en secondes conserveront cette longueur de 10 chiffres jusqu'au 20 novembre 2286, date à laquelle le compteur atteindra 10000000000 (11 chiffres).
L'échelle à 13 chiffres : les millisecondes Unix#
Avec l'avènement des interfaces graphiques, des mesures de latence réseau et des environnements d'exécution modernes comme Java (1995) et JavaScript (1995), la granularité à la seconde est devenue insuffisante. Les cycles de rafraîchissement d'affichage, les interactions utilisateur et les transactions en base de données exigeaient une précision sub-seconde.
Les fonctions System.currentTimeMillis() de Java et Date.now() de JavaScript renvoient des millisecondes. Comme chaque seconde compte 1 000 millisecondes, la conversion s'effectue en multipliant les secondes par 1 000. Les trois derniers chiffres peuvent alors représenter une précision sub-seconde ; ils ne sont pas nécessairement des zéros.
À l'époque contemporaine, tous les horodatages en millisecondes mesurent 13 chiffres décimaux (par exemple, 1704067200000).
Au-delà des millisecondes : microsecondes et nanosecondes#
Les systèmes distribués à très haute fréquence utilisent des échelles encore plus fines :
- Microsecondes (µs, souvent 16 chiffres aujourd'hui) : un millionième de seconde. PostgreSQL stocke les timestamps avec une précision en microsecondes, même si ses fonctions d'extraction peuvent renvoyer des secondes décimales.
- Nanosecondes (ns, souvent 19 chiffres aujourd'hui) : un milliardième de seconde. Go propose
time.Now().UnixNano()et Pythontime.time_ns(). Une horloge monotone commeCLOCK_MONOTONICmesure une durée, pas un instant Unix.
Deux bugs de production majeurs causés par la confusion d'unités#
Lorsque deux composants d'une architecture échangent des horodatages sans expliciter leur unité de mesure, des dysfonctionnements sévères se manifestent.
Bug 1 : L'affichage inopiné du « 20 janvier 1970 » côté frontend#
Il s'agit du bug temporel le plus répandu du développement web.
Une API backend (développée en Python, Go ou PHP) renvoie un timestamp de création en secondes :
Le développeur frontend récupère cette valeur et la passe directement au constructeur d'objet Date de JavaScript :
Pourquoi ce résultat ?
Le développeur souhaitait afficher le 1er janvier 2024. Cependant, comme new Date(valeur) attend des millisecondes, le moteur a interprété 1704067200 comme 1 704 067 200 millisecondes après l'époque Unix.
En convertissant, 1 704 067 200 ms représentent 1 704 067,2 secondes, soit environ 19,72 jours après le début de l'époque Unix. On arrive donc au 20 janvier 1970.
Une date inattendue en janvier 1970 est donc un indice fort qu'une valeur en secondes a été interprétée comme des millisecondes.
Bug 2 : date hors plage ou dépassement côté backend#
L'erreur inverse se produit lorsqu'une application cliente ou un service Java envoie un timestamp à 13 chiffres à un backend qui attend des secondes.
Considérons une requête envoyant 1704067200000 à une application Python :
Dans une colonne SQL INT signée 32 bits, la valeur 1704067200000 dépasse la limite maximale de 2 147 483 647. Selon le moteur et sa configuration, l'insertion est rejetée, tronquée ou signalée comme hors plage ; elle ne doit pas être décrite comme un « crash » garanti.
Panorama des écosystèmes : qui utilise quoi ?#
Les langages de programmation et les bases de données possèdent des conventions bien ancrées :
| Écosystème / Outil | Unité par défaut | Fonction / Méthode | Exemple (2026) |
|---|---|---|---|
| JavaScript / TypeScript | Millisecondes | Date.now() / new Date().getTime() | 1790812800000 |
| Navigateurs web | Durée monotone en millisecondes | performance.now() | 1423.800000 (pas un timestamp Unix) |
| Java | Millisecondes | System.currentTimeMillis() | 1790812800000 |
| Python | Secondes (Flottant) | time.time() | 1790812800.41295 |
| Go | Secondes / Nanos | time.Now().Unix() / UnixNano() | 1790812800 |
| PHP | Secondes | time() | 1790812800 |
| C / C++ | Secondes | time(NULL) | 1790812800 |
| Ruby | Secondes (Flottant) | Time.now.to_f | 1790812800.125 |
| MySQL / MariaDB | Secondes | UNIX_TIMESTAMP() | 1790812800 |
| PostgreSQL | Secondes (Flottant) | EXTRACT(EPOCH FROM NOW()) | 1790812800.681 |
| MongoDB ObjectId | Date dérivée de secondes | ObjectId.getTimestamp() | objet Date à la seconde près |
| API Stripe | Secondes | Propriété created | 1790812800 |
La règle générale est simple : les systèmes proches du système d'exploitation, du noyau Linux ou des normes C/POSIX utilisent les secondes. Les environnements orientés navigateur, interface utilisateur ou machine virtuelle JVM utilisent les millisecondes.
Détection défensive d'un timestamp ambigu#
Lorsque votre application traite des données issues de webhooks externes, de fichiers CSV importés ou de microservices hétérogènes, vous ne connaissez pas toujours l'unité de l'entier reçu.
Les ordres de grandeur peuvent aider pour des données contemporaines, mais ils ne prouvent pas l'unité : les dates anciennes, négatives ou très futures sont ambiguës. Une API doit déclarer son unité ; un importeur peut utiliser des plages explicites et rejeter le reste.
Implémentation en JavaScript et TypeScript#
Implémentation en Python#
Bonnes pratiques pour l'architecture d'APIs et de bases de données#
Afin d'éviter définitivement les corruptions d'horodatages dans vos systèmes :
- Explicitez l'unité dans le nom du champ : Dans vos schémas JSON et vos colonnes SQL, incluez systématiquement l'unité. Préférez
created_at_msouexpiration_epoch_secà des dénominations ambiguës commetimestampoutime. - Adoptez la norme ISO 8601 pour vos APIs publiques : Pour vos interfaces REST et GraphQL destinées à des tiers, privilégiez les chaînes au format ISO 8601 (ex.
2026-10-01T12:00:00.000Z). Ces chaînes sont auto-explicatives, lisibles dans les logs réseaux et suppriment tout risque de mauvaise interprétation d'unité. - Utilisez des entiers 64 bits en base de données : N'employez jamais de colonnes
INT32 bits pour stocker des dates. Utilisez systématiquement le typeBIGINT(8 octets) pour garantir la compatibilité avec les millisecondes et vous prémunir du bug de l'an 2038. - Imposez le temps UTC sur le serveur : Tous les calculs et stockages temporels doivent être effectués en UTC. N'appliquez jamais de décalage horaire local aux valeurs stockées dans la base de données.
Foire aux questions#
Comment déterminer si un timestamp est en secondes ou en millisecondes ?#
Pour une date positive contemporaine, 10 chiffres indiquent généralement des secondes et 13 chiffres des millisecondes. Il s'agit d'un indice, pas d'une règle universelle : une date ancienne, négative ou très future exige une unité explicite. Un résultat en 1970 obtenu avec new Date() constitue un indice fort que des secondes ont été fournies à la place de millisecondes.
Pourquoi JavaScript utilise-t-il les millisecondes alors qu'Unix utilise les secondes ?#
Unix a été conçu entre 1969 et 1971 pour des systèmes d'exploitation et des systèmes de fichiers où une précision à la seconde était amplement suffisante et où la mémoire était très limitée (registres 32 bits). JavaScript a été conçu en 1995 pour les interfaces de navigation web, les animations et la gestion des événements utilisateurs, contextes où une granularité sub-seconde est indispensable.
Un timestamp Unix peut-il être négatif ?#
Oui. Les timestamps négatifs représentent les dates antérieures au 1er janvier 1970. Par exemple, la valeur -315619200 correspond au 1er janvier 1960 à 00:00:00 UTC. Les entiers signés 64 bits gèrent sans aucune difficulté des dates négatives remontant à des centaines de millions d'années dans le passé.
Les timestamps Unix intègrent-ils les secondes intercalaires ?#
Non. La norme POSIX stipule explicitement que chaque journée civile comprend rigoureusement 86 400 secondes. Lors de l'ajout officiel d'une seconde intercalaire par l'IERS, les horloges Unix répètent généralement une seconde ou appliquent un lissage d'horloge (« leap second smearing ») sur 24 heures pour éviter d'insérer une 61e seconde dans le compteur numérique.
Que se passe-t-il lors de la conversion entre flottants et entiers ?#
Python et PostgreSQL représentent fréquemment les horodatages en secondes décimales (ex. 1704067200.500). Pour obtenir des millisecondes entières, multipliez d'abord par 1 000, puis choisissez explicitement un arrondi ou une troncature, par exemple Math.floor(secondesFlottantes * 1000). Convertir d'abord en entier supprimerait la précision sub-seconde.
Outils ToolPorta complémentaires#
Inspectez, convertissez et validez vos données temporelles en toute confidentialité dans votre navigateur :
- Utilisez le Convertisseur de Timestamp pour basculer instantanément entre secondes Unix, millisecondes, chaînes ISO 8601 et dates calendaires.
- Utilisez le Générateur d'UUID pour créer des identifiants UUIDv7 triables par ordre chronologique intégrant un timestamp en millisecondes sur 48 bits.
- Utilisez le Formateur JSON pour inspecter et formater vos réponses d'API contenant des champs temporels.
- Consultez notre guide JavaScript sur les timestamps et notre guide Python sur les timestamps pour obtenir des exemples de code directement intégrables dans vos projets.