Guías
Cómo manejar los segundos intercalares
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)
Leap Second Formula:
If UT1 - UTC > 0.9 seconds → Add positive leap second
If UT1 - UTC < -0.9 seconds → Add negative leap second
Result: 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:
Normal Day (no leap second):
23:59:58 UTC
23:59:59 UTC
00:00:00 UTC (next day)
Leap Second Day:
23:59:58 UTC
23:59:59 UTC
23:59:60 UTC ← Leap second!
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
All Leap Seconds (1972 - 2025):
- 1972-06-30: +1 second (UTC-TAI = +11s)
- 1972-12-31: +1 second (UTC-TAI = +12s)
- 1973-12-31: +1 second (UTC-TAI = +13s)
- 1974-12-31: +1 second (UTC-TAI = +14s)
- 1975-12-31: +1 second (UTC-TAI = +15s)
- 1976-12-31: +1 second (UTC-TAI = +16s)
- 1977-12-31: +1 second (UTC-TAI = +17s)
- 1978-12-31: +1 second (UTC-TAI = +18s)
- 1979-12-31: +1 second (UTC-TAI = +19s)
- 1981-06-30: +1 second (UTC-TAI = +20s)
- 1982-06-30: +1 second (UTC-TAI = +21s)
- 1983-06-30: +1 second (UTC-TAI = +22s)
- 1985-06-30: +1 second (UTC-TAI = +23s)
- 1987-12-31: +1 second (UTC-TAI = +24s)
- 1988-12-31: +1 second (UTC-TAI = +25s)
- 1989-12-31: +1 second (UTC-TAI = +26s)
- 1990-12-31: +1 second (UTC-TAI = +27s)
- 1992-06-30: +1 second (UTC-TAI = +28s)
- 1993-06-30: +1 second (UTC-TAI = +29s)
- 1994-06-30: +1 second (UTC-TAI = +30s)
- 1995-12-31 +1 second (UTC-TAI = +31s)
- 1997-12-31 +1 second (UTC-TAI = +32s)
- 1998-12-31 +1 second (UTC-TAI = +33s)
- 1999-12-31 +1 second (UTC-TAI = +34s)
- 2000-12-31 +1 second (UTC-TAI = +35s)
- 2005-12-31 +1 second (UTC-TAI = +36s)
- 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.
TAI Characteristics:
- Based on: 400+ atomic clocks worldwide
- Precision: ±0.000000001 seconds (1 nanosecond)
- Leap Seconds: Never
- Usage: Scientific research, precise synchronization
Current TAI-UTC Offset: +37 seconds (as of January 2026)
Conversión entre TAI y UTC
// Convert TAI timestamp to UTC timestamp
const TAI_OFFSET_SECONDS = 37; // As of 2026
function taiToUtc(taiTimestamp) {
return taiTimestamp - TAI_OFFSET_SECONDS;
}
function utcToTai(utcTimestamp) {
return utcTimestamp + TAI_OFFSET_SECONDS;
}
// Example
const taiTs = 1735689637;
const utcTs = taiToUtc(taiTs); // 1735689600
console.log('TAI Timestamp:', taiTs);
console.log('UTC Timestamp:', utcTs);
from datetime import datetime, timezone, timedelta
TAI_OFFSET_SECONDS = 37 # As of 2026
def tai_to_utc(tai_timestamp):
return tai_timestamp - TAI_OFFSET_SECONDS
def utc_to_tai(utc_timestamp):
return utc_timestamp + TAI_OFFSET_SECONDS
# Example
tai_ts = 1735689637
utc_ts = tai_to_utc(tai_ts) # 1735689600
print(f'TAI Timestamp: {tai_ts}')
print(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.
// Leap second handling in JavaScript
const leapSecondDate = new Date('2016-12-31T23:59:60Z');
// JavaScript treats this as 23:59:59Z
console.log(leapSecondDate.toISOString()); // "2016-12-31T23:59:59.000Z"
// Workaround: Use a library that supports leap seconds
import { unix } from 'dayjs';
import utc from 'dayjs/plugin/utc';
import customParseFormat from 'dayjs/plugin/customParseFormat';
// Note: Day.js also doesn't support leap seconds natively
// 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.
# Leap second handling in Python
from datetime import datetime, timezone, timedelta
# Standard datetime doesn't support leap seconds
try:
leap_second = datetime(2016, 12, 31, 23, 59, 60, tzinfo=timezone.utc)
except ValueError as e:
print(f'Error: {e}') # ValueError: second must be in 0..59
# Workaround: Use specialized libraries
# For true leap second support, consider:
# - astropy.time for scientific applications
# - specialized time handling libraries
Java
java.time en Java 8+ soporta segundos intercalares en la clase Instant.
import java.time.Instant;
import java.time.temporal.ChronoUnit;
// Leap second handling in Java
Instant leapSecondInstant = Instant.parse("2016-12-31T23:59:60Z");
// Java correctly handles leap second in Instant
System.out.println("Leap Second: " + leapSecondInstant);
// Check if a timestamp contains a leap second
Instant timestamp = Instant.parse("2016-12-31T23:59:60Z");
boolean isLeapSecond = timestamp.getNano() == 0 &&
timestamp.getEpochSecond() % 60 == 59;
System.out.println("Is Leap Second: " + isLeapSecond);
Go
El paquete time de Go no tiene soporte nativo para segundos intercalares.
package main
import (
"fmt"
"time"
)
func main() {
// Go doesn't support leap seconds natively
leapSecondStr := "2016-12-31T23:59:60Z"
_, err := time.Parse(time.RFC3339, leapSecondStr)
if err != nil {
fmt.Println("Error:", err)
// Go will reject leap second timestamps
}
}
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.
Traditional Leap Second:
23:59:58 UTC
23:59:59 UTC
23:59:60 UTC ← Instant jump
00:00:00 UTC (next day)
Smeared Leap Second (24-hour smear):
Each second is ~1.16ms longer for 24 hours
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
For Most Applications:
✓ Use UTC timestamps (ignore leap seconds in storage)
✓ Apply leap second offset only when needed (rare cases)
✓ Test with historical leap second dates
✓ Document your leap second policy
For High-Precision Applications:
✓ Store TAI timestamps
✓ Maintain leap second table
✓ Convert to UTC for display
✓ 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.
// Time smearing example (simplified)
function smearedTime(timestamp, leapSecondDate) {
const diffHours = (timestamp - leapSecondDate) / (1000 * 60 * 60);
const smearDuration = 24; // 24 hours
const smearFactor = Math.min(Math.max(diffHours / smearDuration, 0), 1);
return timestamp + smearFactor * 1000; // Add up to 1 second over 24 hours
}
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.
-- Store standard UTC timestamps (without leap second)
CREATE TABLE events (
id INT PRIMARY KEY,
event_timestamp TIMESTAMP WITHOUT TIME ZONE, -- Standard UTC
description TEXT
);
-- Handle leap second by using a range
SELECT * FROM events
WHERE 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.
# Logging with leap second awareness
import time
from datetime import datetime
def log_event(message):
# Use millisecond precision to handle leap seconds
timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
sequence_id = time.time_ns() # Nanosecond precision
print(f'[{timestamp}] [{sequence_id}] {message}')
Ejemplos de código por escenario
Escenario 1: Convertir timestamps con offset de segundo intercalar
const LEAP_SECONDS = 37; // As of 2026
// Convert TAI timestamp to human-readable UTC
function taiToUtcString(taiTimestamp) {
const utcTimestamp = taiTimestamp - LEAP_SECONDS;
const date = new Date(utcTimestamp * 1000);
return date.toISOString();
}
// Example
const taiTs = 1735689637;
console.log(taiToUtcString(taiTs)); // "2026-01-01T00:00:00.000Z"
from datetime import datetime, timezone, timedelta
LEAP_SECONDS = 37 # As of 2026
def tai_to_utc_string(tai_timestamp):
utc_timestamp = tai_timestamp - LEAP_SECONDS
utc_time = datetime.fromtimestamp(utc_timestamp, timezone.utc)
return utc_time.isoformat()
# Example
tai_ts = 1735689637
print(tai_to_utc_string(tai_ts)) # "2026-01-01T00:00:00Z"
Escenario 2: Verificar si una fecha tiene segundo intercalar
const LEAP_SECOND_DATES = [
'1972-06-30', '1972-12-31', '1973-12-31', '1974-12-31',
'1975-12-31', '1976-12-31', '1977-12-31', '1978-12-31',
'1979-12-31', '1981-06-30', '1982-06-30', '1983-06-30',
'1985-06-30', '1987-12-31', '1989-12-31', '1990-12-31',
'1992-06-30', '1993-06-30', '1994-06-30', '1995-12-31', '1997-06-30',
'1998-12-31', '1999-12-31', '2000-12-31', '2005-12-31',
'2008-12-31', '2012-06-30', '2015-06-30', '2025-12-31',
'2017-12-31', '2018-06-30', '2019-12-31', '2025-12-31'
];
function isLeapSecondDate(date) {
const dateStr = date.toISOString().split('T')[0];
return LEAP_SECOND_DATES.includes(dateStr);
}
// Example
const date = new Date('2016-12-31T23:59:59Z');
console.log(isLeapSecondDate(date)); // true
from datetime import datetime
LEAP_SECOND_DATES = [
datetime(1972, 6, 30), datetime(1972, 12, 31),
datetime(1973, 12, 31), datetime(1974, 12, 31),
datetime(1975, 12, 31), datetime(1976, 12, 31),
datetime(1977, 12, 31), datetime(1978, 12, 31),
datetime(1979, 12, 31), datetime(1981, 6, 30),
datetime(1982, 6, 30), datetime(1983, 6, 30),
datetime(1985, 6, 30), datetime(1987, 12, 31),
datetime(1989, 12, 31), datetime(1990, 12, 31),
datetime(1992, 6, 30), datetime(1993, 6, 30),
datetime(1994, 6, 30), datetime(1995, 12, 31),
datetime(1997, 12, 31), datetime(1998, 12, 31),
datetime(1999, 12, 31), datetime(2000, 12, 31),
datetime(2001, 6, 30), datetime(2002, 6, 30),
datetime(2003, 6, 30), datetime(2004, 6, 30),
datetime(2005, 12, 31), datetime(2008, 12, 31)
]
def is_leap_second_date(date):
return any(
date.year == leap_date.year and
date.month == leap_date.month and
date.day == leap_date.day
for leap_date in LEAP_SECOND_DATES
)
# Example
date = datetime(2016, 12, 31, 23, 59, 59)
print(is_leap_second_date(date)) # True
Pruebas de manejo de segundos intercalares
Casos de prueba
Test 1: Verify leap second offset
Input: TAI = 1735689637
Expected: UTC = 1735689600 (difference = 37 seconds)
Status: PASS if difference equals current UTC-TAI offset
Test 2: Handle leap second timestamp
Input: "2016-12-31T23:59:60Z"
Expected: System handles gracefully (no crash, no data corruption)
Status: PASS if no errors
Test 3: Convert leap second date range
Input: Range [2016-12-31T23:59:59Z, 2017-01-01T00:00:01Z]
Expected: All events in range, including leap second events
Status: PASS if all events returned
Test 4: Verify time smearing
Input: Timestamp near leap second
Expected: Smooth transition, no instant jump
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.