Introducción
Los segundos intercalares son ajustes ocasionales de un segundo a la Hora Universal Coordinada (UTC) para mantenerla sincronizada con la rotación de la Tierra. Representan uno de los aspectos más complejos del manejo del tiempo en el desarrollo de software.
Resumen rápido: UTC añade segundos intercalares para mantenerse dentro de 0,9 segundos de UT1 (tiempo solar). A enero de 2026, se han añadido 37 segundos intercalares desde 1972, haciendo que UTC esté 37 segundos por detrás del Tiempo Atómico Internacional (TAI).
¿Qué son los segundos intercalares?
Definición
Un segundo intercalar es un ajuste de un segundo aplicado a UTC para considerar:
- La desaceleración de la rotación de la Tierra: la rotación se ralentiza gradualmente
- Variaciones irregulares: la velocidad de rotación varía de forma impredecible
- Diferencia UT1-UTC: mantener UTC dentro de ±0,9 segundos del tiempo solar (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
Cómo funcionan los segundos intercalares
Cuando se añade un segundo intercalar, el último minuto de un día UTC tiene 61 segundos en lugar 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)
Nota: los segundos intercalares negativos nunca han ocurrido en la práctica, aunque son teóricamente posibles si la rotación de la Tierra se acelerara de forma repentina.
Historia de los segundos intercalares
Línea de tiempo
| Año | Evento | Desfase UTC-TAI |
|---|---|---|
| 1972 | Se añade el primer segundo intercalar | +10 segundos |
| 1972-1984 | Se añaden 12 segundos intercalares | +22 segundos |
| 1985-1995 | Se añaden 8 segundos intercalares | +29 segundos |
| 1996-2005 | Se añaden 3 segundos intercalares | +32 segundos |
| 2008-2016 | Se añaden 3 segundos intercalares | +35 segundos |
| 2017 | Último segundo intercalar | +36 segundos |
| 2025 | Segundo intercalar futuro | +37 segundos |
Segundos intercalares recientes
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)
Futuro de los segundos intercalares
La Unión Internacional de Telecomunicaciones (ITU) está considerando abolir los segundos intercalares antes de 2035, lo que simplificaría el manejo del tiempo en todo el mundo.
Importante: si se eliminan los segundos intercalares, UTC se iría separando lentamente del tiempo solar. Es un tema controvertido entre astrónomos, desarrolladores y organizaciones de metrología.
TAI vs UTC
Tiempo Atómico Internacional (TAI)
TAI es una escala de tiempo basada en el promedio ponderado de relojes atómicos en todo el mundo. Nunca incluye segundos intercalares, lo que lo convierte en una escala perfectamente 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)
Conversión entre TAI y 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}')
Manejo de segundos intercalares en programación
JavaScript
El objeto Date de JavaScript no soporta segundos intercalares directamente. Repite el timestamp 23:59:60 como 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
El módulo datetime de Python tiene soporte limitado para segundos intercalares. La librería estándar no representa 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 en Java 8+ soporta segundos intercalares en la clase 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
El paquete time de Go no tiene soporte nativo para segundos intercalares.
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}
Time smearing
¿Qué es el time smearing?
Time smearing es una técnica para distribuir el ajuste del segundo intercalar de forma gradual (normalmente 12-24 horas) en lugar de aplicarlo de forma instantánea.
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
Implementaciones de smearing
| Sistema | Método de smearing | Duración |
|---|---|---|
| Google TrueTime | Smearing lineal | 24 horas |
| Amazon Time Sync Service | Smearing lineal | 24 horas |
| Pools NTP | Smearing opcional | 1-24 horas |
| Linux | Paso de kernel (sin smear) | Instantáneo |
Nota: el time smearing se usa en grandes sistemas distribuidos para evitar problemas de sincronización. Sin embargo, crea sus propios problemas: el tiempo “smeared” no es UTC estándar y no se puede convertir de forma fiable a otros sistemas.
Recomendaciones de IETF RFC 8536
RFC 8536 proporciona guías para manejar segundos intercalares en sistemas de software:
Recomendaciones clave
- Usa TAI internamente: guarda timestamps TAI para mayor precisión
- Convierte a UTC solo para mostrar: aplica el offset solo al mostrar al usuario
- Usa NTP para sincronización: obtiene tiempo preciso desde servidores NTP
- Documenta el manejo de segundos intercalares: describe claramente la política
- Prueba eventos de segundos intercalares: simula transiciones en tests
Buenas prácticas
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
Problemas comunes y soluciones
Problema 1: Saltos de tiempo durante el segundo intercalar
Problema: los sistemas experimentan un salto de 1 segundo durante la transición.
Solución: usar time smearing o implementar conciencia de segundo intercalar.
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}
Problema 2: Fallos en consultas de base de datos
Problema: las consultas fallan durante el segundo intercalar porque 23:59:60 no es válido en la mayoría de bases de datos.
Solución: guarda timestamps sin segundos intercalares y documenta el comportamiento.
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';
Problema 3: Errores de logging durante el segundo intercalar
Problema: los logs muestran timestamps duplicados o desordenados.
Solución: usa timestamps de alta resolución e identificadores únicos.
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}')
Ejemplos de código por escenario
Escenario 1: Convertir timestamps con offset de segundo intercalar
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"
Escenario 2: Verificar si una fecha tiene segundo intercalar
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
Pruebas de manejo de segundos intercalares
Casos de prueba
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
Resumen de mejores prácticas
Para la mayoría de aplicaciones
- Ignora segundos intercalares al almacenar (usa UTC estándar)
- Documenta tu política de segundos intercalares
- Prueba con fechas históricas de segundos intercalares
- Usa UTC como estándar principal
Para aplicaciones de alta precisión
- Guarda timestamps TAI para cálculos internos
- Mantén una tabla de segundos intercalares para conversiones
- Usa NTP para sincronización
- Implementa conciencia de segundo intercalar en rutas críticas
Herramientas relacionadas
- TAI Time Converter - Convierte entre TAI, UTC y tiempo GPS
- Current Timestamp - Obtén la hora UTC actual con precisión
- Unix Timestamp Converter - Maneja distintas precisiones de timestamp
- GPS Time Converter - Tiempo GPS con manejo de segundos intercalares
Preguntas frecuentes
P: ¿Con qué frecuencia ocurren los segundos intercalares?
R: Han ocurrido 27 veces desde 1972 (aprox. cada 1-2 años), pero su frecuencia ha disminuido recientemente por la desaceleración de la rotación terrestre.
P: ¿Los segundos intercalares seguirán existiendo?
R: La ITU está discutiendo abolirlos antes de 2035, lo que detendría su adición pero haría que UTC se aleje gradualmente del tiempo solar.
P: ¿Necesito manejar segundos intercalares en mi aplicación?
R: Para la mayoría de aplicaciones, no: usa UTC estándar. Solo manéjalos si construyes sistemas críticos de tiempo, aplicaciones científicas o bases de datos distribuidas.
P: ¿Qué ocurre durante un segundo intercalar?
R: UTC añade un segundo extra (23:59:60) para mantener la sincronización con la rotación de la Tierra. La mayoría de sistemas repiten 23:59:59 o usan smearing para evitar saltos.
P: ¿Cómo pruebo el manejo de segundos intercalares?
R: Prueba con fechas históricas como 2016-12-31T23:59:60Z y verifica que la aplicación no falle ni genere resultados incorrectos.