1. Por qué suponer que «el tiempo siempre avanza» falla con el segundo bisiesto
El segundo bisiesto es una corrección ocasional para alinear la hora de los relojes atómicos con la rotación de la Tierra. Entre 1972 y finales de 2016, se añadió un segundo en 27 ocasiones. [7] Para las personas, añadir un segundo no es difícil, pero para los ordenadores sí lo es.
Muchos sistemas usan la «Hora UNIX», que cuenta los segundos desde el 1 de enero de 1970 sin contar los bisiestos. La norma POSIX define que un día tiene exactamente 86.400 segundos. [5] Por lo tanto, no existe un número de segundo específico para el «segundo bisiesto». Cuando ocurre, el sistema debe retroceder el reloj o contar el mismo segundo dos veces para que todo encaje.
Este retroceso es la causa de muchos fallos. Imagina un programa que calcula cuánto duró algo restando la hora de inicio a la de fin. Si el reloj retrocede 1 segundo mientras se hace la cuenta, el resultado será incorrectamente corto. Si lo que se mide dura menos de un segundo, el resultado puede ser negativo, algo que los ordenadores no suelen esperar.
2. Cómo un tiempo negativo causó el fallo de Cloudflare en 2017
Cloudflare es una empresa que ayuda a mostrar y proteger sitios web. Su sistema DNS (que traduce nombres a direcciones) mide cuánto tarda en recibir respuestas de otros ordenadores para elegir el más rápido. Normalmente, esto toma unos pocos milisegundos.
El 1 de enero de 2017 a las 00:00 UTC (las 9:00 de la mañana en Japón), durante el segundo bisiesto, el reloj retrocedió mientras Cloudflare medía tiempos. Esto hizo que el tiempo de respuesta fuera negativo. [1] El programa promediaba varias mediciones; si varias mediciones negativas se sucedían, el promedio podía volverse negativo.
Ese valor negativo se envió a una función que genera números aleatorios para elegir servidores. Esta función estaba diseñada para detenerse si recibía un número negativo, lo que causó el error. Solo afectó a clientes que usaban registros DNS de tipo CNAME. Cloudflare informó que los errores fueron menos del 1% de las peticiones HTTP y el 0,2% de las consultas DNS en su peor momento. [1] Los ingenieros señalaron que el error se debió a la suposición falsa de que «el tiempo nunca retrocede». Además, el lenguaje Go que usaban no tenía un reloj monotónico (que solo avanza) disponible en ese momento.
3. Cómo el segundo bisiesto de 2012 afectó a los temporizadores de Linux
Otro ejemplo ocurrió en 2012, cuando se añadió un segundo bisiesto el 30 de junio. Ordenadores que usaban el sistema operativo Linux fallaron en varias partes del mundo. Los sistemas de reserva «Amadeus Altea» de las aerolíneas Qantas y Virgin Australia en Australia se detuvieron durante casi una hora, obligando al personal a hacer los embarques a mano. [2] También se reportaron problemas en Mozilla, Reddit, LinkedIn y Yelp.
Amadeus culpó a un error del «kernel» de Linux (el núcleo del sistema). [2] El desarrollador John Stultz explicó que el kernel retrocedió el reloj real (CLOCK_REALTIME), pero olvidó avisar al sistema que gestiona los temporizadores (hrtimer) de este cambio. [3]
Es como si un empleado que debía avisar a las 9:00 en punto siguiera mirando el reloj antiguo antes del retroceso. Como resultado, los temporizadores basados en hora sonaron un segundo antes de lo debido. Si la espera era muy corta, el sistema pensaba que ya había pasado el tiempo y devolvía una respuesta inmediata. Esto causó que muchos programas entraran en un bucle de «esperar y responder» repetitivo, sobrecargando los procesadores. [3] La solución fue añadir la notificación del retroceso al código del segundo bisiesto.
4. Dos formas de evitar estos errores: relojes monotónicos y suavizado del segundo
La primera forma de evitar problemas es usar un «reloj monotónico». Este reloj, como un cronómetro, solo cuenta el tiempo transcurrido y nunca retrocede, aunque se cambie la hora del sistema. En Python, por ejemplo, la función time.monotonic() está diseñada para no verse afectada por cambios en el reloj del sistema. [6] En cambio, time.time() sí puede devolver valores más pequeños si el reloj retrocede.
La segunda forma es la estrategia de «suavizado» (smear) usada por Google desde 2008. En lugar de añadir un segundo entero de golpe, Google distribuye ese segundo entre el mediodía UTC y el del día siguiente. Durante este periodo, cada segundo dura aproximadamente 11,6 microsegundos más de lo normal. [4] Así, el reloj nunca retrocede ni muestra «60 segundos», aunque puede tener una diferencia máxima de unos 0,5 segundos respecto a la hora oficial UTC.
5. Por qué se decidió eliminar el segundo bisiesto a partir de 2027
En octubre de 2026, en Versalles (Francia), se adoptó una resolución para dejar de usar el segundo bisiesto a partir del 20 de mayo de 2027. [7] A partir de esa fecha, la hora UTC será continua y no hará ajustes bruscos.
La norma permite que la diferencia entre la hora atómica (UTC) y la rotación de la Tierra (UT1) crezca hasta un máximo de 3.600 segundos (una hora). [8] La resolución menciona que existe una probabilidad estimada del 30% de necesitar un «segundo bisiesto negativo» (restar un segundo) antes de 2035. [8] Nunca se ha hecho esto y se considera muy riesgoso para la infraestructura global.
Un retroceso de un segundo puede causar fallos, como muestran estos casos. El impacto de «saltar» o borrar un segundo entero no ha sido probado todavía. [8] Para campos que necesitan precisión astronómica, como la observación de estrellas, se gestionará esa diferencia acumulada por separado. [7]
Nota de seguridad: El hecho de que nunca se haya probado «borrar» un segundo es una de las razones para abolir esta práctica.
6. Cómo simular con papel y lápiz el problema de restar horas
Puedes simular el problema en papel. Escribe una hora de inicio, por ejemplo 10:00:05, y una de fin, 10:00:08. La diferencia es de 3 segundos.
Ahora imagina que el reloj retrocede 1 segundo mientras se hace la medición. Cambia la hora de fin a 10:00:07. Al restar, obtendrás 2 segundos en lugar de 3. Si hubieras medido algo muy rápido, podrías obtener un número negativo.
Si usas un cronómetro real (que empieza desde cero), no importa si el reloj de la pared cambia; el cronómetro sigue contando hacia adelante. Si sabes programar en Python, puedes leer la documentación oficial para comparar cómo funcionan time.time() y time.monotonic(). [6]
No intentes realmente poner el reloj 1 segundo atrás, ya que esto afecta a otros programas.