Introduction
Les secondes intercalaires sont des ajustements ponctuels d’une seconde ajoutés à l’UTC pour le maintenir synchronisé avec la rotation de la Terre. C’est l’un des aspects les plus complexes de la gestion du temps en développement logiciel.
Résumé rapide : l’UTC ajoute des secondes intercalaires pour rester à moins de 0,9 seconde d’UT1 (temps solaire). En janvier 2026, 37 secondes intercalaires ont été ajoutées depuis 1972, ce qui place l’UTC 37 secondes derrière le Temps Atomique International (TAI).
Que sont les secondes intercalaires ?
Définition
Une seconde intercalaire est un ajustement d’une seconde appliqué à l’UTC pour tenir compte de :
- La décélération de la rotation de la Terre
- Des irrégularités de rotation
- L’écart UT1‑UTC : maintenir l’UTC à ±0,9 seconde du temps solaire (UT1)
TEXT1Leap Second Formula: 2 If UT1 - UTC > 0.9 seconds → Add positive leap second 3 If UT1 - UTC < -0.9 seconds → Add negative leap second 4 5Result: UTC stays synchronized with Earth's rotation
Comment fonctionnent les secondes intercalaires
Lorsqu’une seconde intercalaire est ajoutée, la dernière minute d’une journée UTC a 61 secondes au lieu de 60 :
TEXT1Normal Day (no leap second): 2 23:59:58 UTC 3 23:59:59 UTC 4 00:00:00 UTC (next day) 5 6Leap Second Day: 7 23:59:58 UTC 8 23:59:59 UTC 9 23:59:60 UTC ← Leap second! 10 00:00:00 UTC (next day)
Note : les secondes intercalaires négatives ne se sont jamais produites en pratique, bien qu’elles soient théoriquement possibles.
Histoire des secondes intercalaires
Chronologie
| Année | Événement | Décalage UTC‑TAI |
|---|---|---|
| 1972 | Première seconde intercalaire | +10 secondes |
| 1972-1984 | 12 secondes ajoutées | +22 secondes |
| 1985-1995 | 8 secondes ajoutées | +29 secondes |
| 1996-2005 | 3 secondes ajoutées | +32 secondes |
| 2008-2016 | 3 secondes ajoutées | +35 secondes |
| 2017 | Dernière seconde intercalaire | +36 secondes |
| 2025 | Seconde intercalaire future | +37 secondes |
Secondes intercalaires récentes
TEXT1All Leap Seconds (1972 - 2025): 2 - 1972-06-30: +1 second (UTC-TAI = +11s) 3 - 1972-12-31: +1 second (UTC-TAI = +12s) 4 - 1973-12-31: +1 second (UTC-TAI = +13s) 5 - 1974-12-31: +1 second (UTC-TAI = +14s) 6 - 1975-12-31: +1 second (UTC-TAI = +15s) 7 - 1976-12-31: +1 second (UTC-TAI = +16s) 8 - 1977-12-31: +1 second (UTC-TAI = +17s) 9 - 1978-12-31: +1 second (UTC-TAI = +18s) 10 - 1979-12-31: +1 second (UTC-TAI = +19s) 11 - 1981-06-30: +1 second (UTC-TAI = +20s) 12 - 1982-06-30: +1 second (UTC-TAI = +21s) 13 - 1983-06-30: +1 second (UTC-TAI = +22s) 14 - 1985-06-30: +1 second (UTC-TAI = +23s) 15 - 1987-12-31: +1 second (UTC-TAI = +24s) 16 - 1988-12-31: +1 second (UTC-TAI = +25s) 17 - 1989-12-31: +1 second (UTC-TAI = +26s) 18 - 1990-12-31: +1 second (UTC-TAI = +27s) 19 - 1992-06-30: +1 second (UTC-TAI = +28s) 20 - 1993-06-30: +1 second (UTC-TAI = +29s) 21 - 1994-06-30: +1 second (UTC-TAI = +30s) 22 - 1995-12-31 +1 second (UTC-TAI = +31s) 23 - 1997-12-31 +1 second (UTC-TAI = +32s) 24 - 1998-12-31 +1 second (UTC-TAI = +33s) 25 - 1999-12-31 +1 second (UTC-TAI = +34s) 26 - 2000-12-31 +1 second (UTC-TAI = +35s) 27 - 2005-12-31 +1 second (UTC-TAI = +36s) 28 - 2008-12-31: +1 second (UTC-TAI = +37s)
Futur des secondes intercalaires
L’Union internationale des télécommunications (UIT) envisage de supprimer les secondes intercalaires d’ici 2035, ce qui simplifierait la gestion du temps.
Important : si elles sont supprimées, l’UTC dérivera progressivement du temps solaire. C’est un sujet controversé pour les astronomes, développeurs et organismes de mesure du temps.
TAI vs UTC
Temps Atomique International (TAI)
Le TAI est une échelle de temps basée sur la moyenne pondérée d’horloges atomiques. Il n’inclut jamais de secondes intercalaires, ce qui le rend parfaitement uniforme.
TEXT1TAI Characteristics: 2 - Based on: 400+ atomic clocks worldwide 3 - Precision: ±0.000000001 seconds (1 nanosecond) 4 - Leap Seconds: Never 5 - Usage: Scientific research, precise synchronization 6 7Current TAI-UTC Offset: +37 seconds (as of January 2026)
Conversion entre TAI et UTC
JAVASCRIPT1// Convert TAI timestamp to UTC timestamp 2const TAI_OFFSET_SECONDS = 37; // As of 2026 3 4function taiToUtc(taiTimestamp) { 5 return taiTimestamp - TAI_OFFSET_SECONDS; 6} 7 8function utcToTai(utcTimestamp) { 9 return utcTimestamp + TAI_OFFSET_SECONDS; 10} 11 12// Example 13const taiTs = 1735689637; 14const utcTs = taiToUtc(taiTs); // 1735689600 15 16console.log('TAI Timestamp:', taiTs); 17console.log('UTC Timestamp:', utcTs);
PYTHON1from datetime import datetime, timezone, timedelta 2 3TAI_OFFSET_SECONDS = 37 # As of 2026 4 5def tai_to_utc(tai_timestamp): 6 return tai_timestamp - TAI_OFFSET_SECONDS 7 8def utc_to_tai(utc_timestamp): 9 return utc_timestamp + TAI_OFFSET_SECONDS 10 11# Example 12tai_ts = 1735689637 13utc_ts = tai_to_utc(tai_ts) # 1735689600 14 15print(f'TAI Timestamp: {tai_ts}') 16print(f'UTC Timestamp: {utc_ts}')
Gérer les secondes intercalaires en programmation
JavaScript
L’objet Date de JavaScript ne gère pas directement les secondes intercalaires. Il répète 23:59:60 comme 23:59:59.
JAVASCRIPT1// Leap second handling in JavaScript 2const leapSecondDate = new Date('2016-12-31T23:59:60Z'); 3 4// JavaScript treats this as 23:59:59Z 5console.log(leapSecondDate.toISOString()); // "2016-12-31T23:59:59.000Z" 6 7// Workaround: Use a library that supports leap seconds 8import { unix } from 'dayjs'; 9import utc from 'dayjs/plugin/utc'; 10import customParseFormat from 'dayjs/plugin/customParseFormat'; 11 12// Note: Day.js also doesn't support leap seconds natively 13// Consider using specialized time libraries for leap second support
Python
Le module datetime de Python prend en charge de façon limitée les secondes intercalaires. La bibliothèque standard ne représente pas 23:59:60.
PYTHON1# Leap second handling in Python 2from datetime import datetime, timezone, timedelta 3 4# Standard datetime doesn't support leap seconds 5try: 6 leap_second = datetime(2016, 12, 31, 23, 59, 60, tzinfo=timezone.utc) 7except ValueError as e: 8 print(f'Error: {e}') # ValueError: second must be in 0..59 9 10# Workaround: Use specialized libraries 11# For true leap second support, consider: 12# - astropy.time for scientific applications 13# - specialized time handling libraries
Java
java.time (Java 8+) prend en charge les secondes intercalaires dans Instant.
JAVA1import java.time.Instant; 2import java.time.temporal.ChronoUnit; 3 4// Leap second handling in Java 5Instant leapSecondInstant = Instant.parse("2016-12-31T23:59:60Z"); 6 7// Java correctly handles leap second in Instant 8System.out.println("Leap Second: " + leapSecondInstant); 9 10// Check if a timestamp contains a leap second 11Instant timestamp = Instant.parse("2016-12-31T23:59:60Z"); 12boolean isLeapSecond = timestamp.getNano() == 0 && 13 timestamp.getEpochSecond() % 60 == 59; 14 15System.out.println("Is Leap Second: " + isLeapSecond);
Go
Le package time de Go ne prend pas en charge les secondes intercalaires nativement.
GO1package main 2 3import ( 4 "fmt" 5 "time" 6) 7 8func main() { 9 // Go doesn't support leap seconds natively 10 leapSecondStr := "2016-12-31T23:59:60Z" 11 _, err := time.Parse(time.RFC3339, leapSecondStr) 12 13 if err != nil { 14 fmt.Println("Error:", err) 15 // Go will reject leap second timestamps 16 } 17}
Lissage du temps (time smearing)
Qu’est‑ce que le time smearing ?
Le time smearing consiste à répartir l’ajustement de la seconde intercalaire sur une période (généralement 12‑24 heures) au lieu de l’appliquer instantanément.
TEXT1Traditional Leap Second: 2 23:59:58 UTC 3 23:59:59 UTC 4 23:59:60 UTC ← Instant jump 5 00:00:00 UTC (next day) 6 7Smeared Leap Second (24-hour smear): 8 Each second is ~1.16ms longer for 24 hours 9 No instant jump, smooth transition
Implémentations de smearing
| Système | Méthode | Durée |
|---|---|---|
| Google TrueTime | Smearing linéaire | 24 heures |
| Amazon Time Sync Service | Smearing linéaire | 24 heures |
| Pools NTP | Smearing optionnel | 1-24 heures |
| Linux | Ajustement kernel (sans smear) | Instantané |
Note : le smearing évite les problèmes de synchronisation mais crée un temps non standard qui ne se convertit pas proprement vers d’autres systèmes.
Recommandations IETF RFC 8536
RFC 8536 fournit des lignes directrices pour gérer les secondes intercalaires :
Recommandations clés
- Utiliser TAI en interne : stocker des timestamps TAI pour la précision
- Convertir en UTC uniquement pour l’affichage
- Utiliser NTP pour la synchronisation
- Documenter la gestion des secondes intercalaires
- Tester les événements de seconde intercalaire
Bonnes pratiques
TEXT1For Most Applications: 2 ✓ Use UTC timestamps (ignore leap seconds in storage) 3 ✓ Apply leap second offset only when needed (rare cases) 4 ✓ Test with historical leap second dates 5 ✓ Document your leap second policy 6 7For High-Precision Applications: 8 ✓ Store TAI timestamps 9 ✓ Maintain leap second table 10 ✓ Convert to UTC for display 11 ✓ Use NTP for synchronization
Problèmes courants et solutions
Problème 1 : saut de temps pendant la seconde intercalaire
Problème : le système subit un saut d’une seconde.
Solution : utiliser le smearing ou gérer explicitement la seconde intercalaire.
JAVASCRIPT1// Time smearing example (simplified) 2function smearedTime(timestamp, leapSecondDate) { 3 const diffHours = (timestamp - leapSecondDate) / (1000 * 60 * 60); 4 const smearDuration = 24; // 24 hours 5 const smearFactor = Math.min(Math.max(diffHours / smearDuration, 0), 1); 6 7 return timestamp + smearFactor * 1000; // Add up to 1 second over 24 hours 8}
Problème 2 : échec des requêtes en base
Problème : les requêtes échouent car 23:59:60 est invalide dans la plupart des bases.
Solution : stocker sans secondes intercalaires et documenter le comportement.
SQL1-- Store standard UTC timestamps (without leap second) 2CREATE TABLE events ( 3 id INT PRIMARY KEY, 4 event_timestamp TIMESTAMP WITHOUT TIME ZONE, -- Standard UTC 5 description TEXT 6); 7 8-- Handle leap second by using a range 9SELECT * FROM events 10WHERE event_timestamp BETWEEN '2016-12-31T23:59:59Z' AND '2017-01-01T00:00:01Z';
Problème 3 : erreurs de logs
Problème : les logs affichent des timestamps doublés ou hors ordre.
Solution : utiliser des timestamps haute résolution et un identifiant unique.
PYTHON1# Logging with leap second awareness 2import time 3from datetime import datetime 4 5def log_event(message): 6 # Use millisecond precision to handle leap seconds 7 timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] 8 sequence_id = time.time_ns() # Nanosecond precision 9 10 print(f'[{timestamp}] [{sequence_id}] {message}')
Exemples de code par scénario
Scénario 1 : conversion avec offset de seconde intercalaire
JAVASCRIPT1const LEAP_SECONDS = 37; // As of 2026 2 3// Convert TAI timestamp to human-readable UTC 4function taiToUtcString(taiTimestamp) { 5 const utcTimestamp = taiTimestamp - LEAP_SECONDS; 6 const date = new Date(utcTimestamp * 1000); 7 return date.toISOString(); 8} 9 10// Example 11const taiTs = 1735689637; 12console.log(taiToUtcString(taiTs)); // "2026-01-01T00:00:00.000Z"
PYTHON1from datetime import datetime, timezone, timedelta 2 3LEAP_SECONDS = 37 # As of 2026 4 5def tai_to_utc_string(tai_timestamp): 6 utc_timestamp = tai_timestamp - LEAP_SECONDS 7 utc_time = datetime.fromtimestamp(utc_timestamp, timezone.utc) 8 return utc_time.isoformat() 9 10# Example 11tai_ts = 1735689637 12print(tai_to_utc_string(tai_ts)) # "2026-01-01T00:00:00Z"
Scénario 2 : vérifier une date de seconde intercalaire
JAVASCRIPT1const LEAP_SECOND_DATES = [ 2 '1972-06-30', '1972-12-31', '1973-12-31', '1974-12-31', 3 '1975-12-31', '1976-12-31', '1977-12-31', '1978-12-31', 4 '1979-12-31', '1981-06-30', '1982-06-30', '1983-06-30', 5 '1985-06-30', '1987-12-31', '1989-12-31', '1990-12-31', 6 '1992-06-30', '1993-06-30', '1994-06-30', '1995-12-31', '1997-06-30', 7 '1998-12-31', '1999-12-31', '2000-12-31', '2005-12-31', 8 '2008-12-31', '2012-06-30', '2015-06-30', '2025-12-31', 9 '2017-12-31', '2018-06-30', '2019-12-31', '2025-12-31' 10]; 11 12function isLeapSecondDate(date) { 13 const dateStr = date.toISOString().split('T')[0]; 14 return LEAP_SECOND_DATES.includes(dateStr); 15} 16 17// Example 18const date = new Date('2016-12-31T23:59:59Z'); 19console.log(isLeapSecondDate(date)); // true
PYTHON1from datetime import datetime 2 3LEAP_SECOND_DATES = [ 4 datetime(1972, 6, 30), datetime(1972, 12, 31), 5 datetime(1973, 12, 31), datetime(1974, 12, 31), 6 datetime(1975, 12, 31), datetime(1976, 12, 31), 7 datetime(1977, 12, 31), datetime(1978, 12, 31), 8 datetime(1979, 12, 31), datetime(1981, 6, 30), 9 datetime(1982, 6, 30), datetime(1983, 6, 30), 10 datetime(1985, 6, 30), datetime(1987, 12, 31), 11 datetime(1989, 12, 31), datetime(1990, 12, 31), 12 datetime(1992, 6, 30), datetime(1993, 6, 30), 13 datetime(1994, 6, 30), datetime(1995, 12, 31), 14 datetime(1997, 12, 31), datetime(1998, 12, 31), 15 datetime(1999, 12, 31), datetime(2000, 12, 31), 16 datetime(2001, 6, 30), datetime(2002, 6, 30), 17 datetime(2003, 6, 30), datetime(2004, 6, 30), 18 datetime(2005, 12, 31), datetime(2008, 12, 31) 19] 20 21def is_leap_second_date(date): 22 return any( 23 date.year == leap_date.year and 24 date.month == leap_date.month and 25 date.day == leap_date.day 26 for leap_date in LEAP_SECOND_DATES 27 ) 28 29# Example 30date = datetime(2016, 12, 31, 23, 59, 59) 31print(is_leap_second_date(date)) # True
Tester la gestion des secondes intercalaires
Cas de test
TEXT1Test 1: Verify leap second offset 2 Input: TAI = 1735689637 3 Expected: UTC = 1735689600 (difference = 37 seconds) 4 Status: PASS if difference equals current UTC-TAI offset 5 6Test 2: Handle leap second timestamp 7 Input: "2016-12-31T23:59:60Z" 8 Expected: System handles gracefully (no crash, no data corruption) 9 Status: PASS if no errors 10 11Test 3: Convert leap second date range 12 Input: Range [2016-12-31T23:59:59Z, 2017-01-01T00:00:01Z] 13 Expected: All events in range, including leap second events 14 Status: PASS if all events returned 15 16Test 4: Verify time smearing 17 Input: Timestamp near leap second 18 Expected: Smooth transition, no instant jump 19 Status: PASS if transition is smooth
Résumé des bonnes pratiques
Pour la plupart des applications
- Ignorer les secondes intercalaires en stockage (UTC standard)
- Documenter la politique de secondes intercalaires
- Tester avec des dates historiques de secondes intercalaires
- Utiliser UTC comme standard principal
Pour les applications de haute précision
- Stocker des timestamps TAI pour les calculs internes
- Maintenir une table de secondes intercalaires
- Utiliser NTP pour la synchronisation
- Implémenter la gestion des secondes intercalaires sur les chemins critiques
Outils associés
- TAI Time Converter - Conversion entre TAI, UTC et temps GPS
- Current Timestamp - Heure UTC actuelle avec précision
- Unix Timestamp Converter - Gérer plusieurs précisions de timestamp
- GPS Time Converter - Temps GPS avec gestion des secondes intercalaires
FAQ
Q : À quelle fréquence les secondes intercalaires ont‑elles lieu ?
R : Elles se sont produites 27 fois depuis 1972 (environ tous les 1‑2 ans), mais la fréquence a diminué récemment.
Q : Les secondes intercalaires vont‑elles disparaître ?
R : L’UIT discute d’une suppression d’ici 2035, ce qui arrêterait leur ajout mais ferait dériver l’UTC du temps solaire.
Q : Dois‑je gérer les secondes intercalaires dans mon application ?
R : Pour la plupart des applications, non : utilisez l’UTC standard. Gérez‑les seulement pour les systèmes critiques, scientifiques ou distribués.
Q : Que se passe‑t‑il pendant une seconde intercalaire ?
R : L’UTC ajoute une seconde (23:59:60) pour rester synchronisé avec la rotation terrestre. La plupart des systèmes répètent 23:59:59 ou utilisent le smearing.
Q : Comment tester la gestion des secondes intercalaires ?
R : Testez avec des dates historiques comme 2016-12-31T23:59:60Z et vérifiez que l’application ne plante pas et ne produit pas de résultats incorrects.