Saltar al contenido

Los bugs de fecha y hora más comunes en software

Guía práctica de errores que rompen software: datetimes sin zona, confusión con UTC, horario de verano, fechas puras, timestamps Unix y semanas.

· 13 min de lectura · Gabriel

Pantalla de desarrollo con errores de fecha y hora en software
Índice de contenidos

El bug suele empezar con una frase que parece inofensiva

La mayoría de los bugs de fecha y hora no empiezan con astronomía rara. Empiezan con una frase de producto que suena obvia: “manda el recordatorio mañana por la mañana”, “caduca esta prueba después de 30 días”, “muestra los pedidos de hoy”, “ejecuta este proceso a las 2:30”, “guarda el timestamp”. Cada frase esconde una regla. ¿Mañana por la mañana dónde? ¿Treinta días naturales o 30 veces 24 horas? ¿Hoy en la ciudad del cliente, en el almacén o en el servidor de base de datos? ¿Qué pasa cuando las 2:30 no existen?

El software cuenta muy bien. Los calendarios no son solo conteo. Son una pila de convenciones humanas: zonas horarias, cambios de horario de verano, días hábiles, formatos locales, años bisiestos, semanas ISO, tipos de base de datos y horas legales de corte. Los bugs aparecen cuando el código trata una capa como si fuera otra.

Esta guía es un manual de campo para los errores que rompen sistemas en producción una y otra vez. Está escrita para desarrolladores, product managers, analistas y cualquiera que haya mirado un panel y se haya preguntado por qué los números de ayer cambiaron después del desayuno.

1. Datetimes sin zona: el timestamp sin pasaporte

Un datetime sin zona es una fecha y una hora de reloj sin zona horaria. 2026-03-08 02:15 parece preciso, pero no dice dónde ocurrió. En Nueva York, durante el cambio de primavera de 2026, la hora de 02:00 a 02:59 no existe. En otra ciudad puede ser perfectamente válida. En UTC significa otra cosa.

El fallo común es guardar hora local como si fuera un instante absoluto. Una reunión creada para “9:00 Europe/Madrid” debe seguir siendo a las 9:00 en Madrid cuando España cambie de hora. Un evento de pago que ya ocurrió debe guardarse como un instante. Son modelos distintos.

Caso de usoGuardaPor qué
Log de auditoría, clic, pago, evento APIInstante, normalmente UTCEl evento ya ocurrió en un momento exacto.
Reunión futura en una ciudadFecha local, hora local, zona IANALa hora de reloj debe sobrevivir a cambios de DST.
Cumpleaños, festivo, día de facturaciónSolo fechaPuede no haber una hora útil.
Horario de aperturaHora local más lugar o reglaLa regla se repite en tiempo civil local.

Si necesitas comparar momentos exactos, convierte a instantes. Si necesitas conservar una cita humana donde fue pensada, conserva también el lugar. Un offset como UTC+01:00 no basta para planificación futura porque el offset puede cambiar.

2. Confusión con UTC: buen almacenamiento, mala experiencia

“Guarda todo en UTC” es una regla útil para eventos que ya ocurrieron. No es un diseño de producto completo. Las personas no piensan en UTC al programar una cita médica, publicar un webinar o elegir una fecha de entrada a un hotel. Piensan en tiempo civil local.

El bug aparece cuando un sistema guarda UTC correctamente pero pierde la zona que el usuario quería. Una invitación creada en Los Ángeles para las 9:00 puede verse internamente como 17:00 UTC. Eso está bien. Pero si la aplicación reconstruye luego el evento usando la zona del servidor, o solo guarda un offset fijo, la reunión puede moverse tras un cambio de horario.

Los buenos sistemas separan tres preguntas: qué instante es, qué hora local quería el usuario y qué reglas de zona horaria explican esa hora local. Nuestro conversor de zonas horarias es útil precisamente porque la fecha, el lugar y el offset importan juntos.

3. Huecos y pliegues de DST: horas que desaparecen o pasan dos veces

El horario de verano crea dos trampas clásicas. En primavera, una hora local puede saltarse. En otoño, una hora local puede ocurrir dos veces. Si tu planificador acepta “2026-03-08 02:30 America/New_York”, ¿qué debe hacer? ¿Rechazarla? ¿Moverla a las 03:00? ¿Interpretarla en otra zona? No hay una respuesta universal. El producto necesita una regla.

Las horas ambiguas de otoño son incluso más sutiles. “2026-11-01 01:30 America/New_York” puede referirse a la primera 01:30 o a la segunda 01:30. Ambas etiquetas locales son reales. Logs, sistemas de transporte, sistemas hospitalarios y programadores de tareas necesitan saber cuál se quiso decir.

Una suite de pruebas útil incluye fechas reales de transición para las zonas que importan a tus usuarios. No pruebes solo el 15 de enero. Prueba un día de salto de primavera, un día de retroceso de otoño y un país cuyas reglas de DST no coincidan con las tuyas.

4. Fechas puras que se convierten accidentalmente en medianoche

Una fecha no siempre es un datetime con medianoche pegada. Una reserva de hotel para el 3 de junio, un cumpleaños, una fecha límite fiscal y un festivo son conceptos de fecha. Cuando el código los convierte en 2026-06-03T00:00:00Z, ha inventado una hora y una zona.

Así es como los cumpleaños aparecen el día anterior para usuarios al oeste de UTC. También es como “el informe de hoy” puede mostrar datos de ayer para un equipo y de mañana para otro. La solución no es complicada: usa tipos de solo fecha para conceptos de solo fecha, y crea un datetime únicamente cuando la regla de negocio necesite una hora.

Para deadlines, haz una pregunta más precisa: ¿caduca al inicio de la fecha, al final de la fecha, al cierre local del negocio o en un instante exacto? “Caduca el 3 de junio” es texto de producto, no una regla completa.

5. Sumar días como segundos

Sumar 86.400 segundos no es lo mismo que sumar un día natural en hora local. La mayoría de los días tienen 24 horas, pero los días de transición DST pueden tener 23 o 25. Si un recordatorio diario debe aparecer a las 8:00 hora local, suma un día de calendario en la zona del usuario. Si una caché debe expirar exactamente después de 24 horas, suma una duración.

FraseNormalmente significaModelo más seguro
Misma hora mañanaSiguiente día natural local a la misma hora de relojFecha/hora en la zona del usuario
Caduca en 24 horasDuración exacta transcurridaInstante más duración
Vence en 3 días hábilesRegla local de días laborablesCalendario laboral
Cada lunes a las 9Horario local recurrenteHora local más zona IANA

Esta distinción es la razón por la que una calculadora de días hábiles no es solo una calculadora de diferencia de fechas con fines de semana eliminados. Festivos, fines de semana locales y cierres observados pueden cambiar el resultado.

6. Unidades de timestamp Unix: segundos, milisegundos, microsegundos, nanosegundos

Unix time es elegante: contar el tiempo desde 1970-01-01T00:00:00Z. El problema es que los ecosistemas de software no siempre usan la misma unidad. Muchas APIs usan segundos. JavaScript usa milisegundos. Algunas bases de datos y sistemas de observabilidad usan microsegundos o nanosegundos. 1717425600 y 1717425600000 representan el mismo momento en unidades distintas; si eliges mal, tu fecha salta siglos.

La comprobación rápida es contar dígitos. Los segundos Unix actuales tienen 10 dígitos. Los milisegundos tienen 13. Los microsegundos, 16. Los nanosegundos, 19. Un buen importador debe identificar la unidad explícitamente o rechazar entradas ambiguas en vez de adivinar en silencio. Nuestro conversor de timestamp Unix muestra la misma idea en forma de herramienta.

7. Ordenar fechas como texto en el formato incorrecto

Las fechas estilo ISO se ordenan bien como texto: 2026-06-03 viene antes de 2026-12-01. Muchos formatos locales no. Una lista de cadenas MM/DD/YYYY o DD/MM/YYYY puede parecer correcta en una muestra pequeña y fallar cuando cambian los meses o los países.

Usa ISO 8601 o tipos reales de fecha para intercambio y almacenamiento. Usa formatos localizados solo en el borde de visualización. Si un CSV es para humanos, explica el formato esperado en la cabecera o en la documentación de exportación. Si es para máquinas, prefiere un estándar inequívoco como RFC 3339 para timestamps.

8. Bugs de número de semana alrededor de Año Nuevo

Los números de semana no son universales. Las semanas ISO empiezan el lunes y hacen que la Semana 1 sea la semana que contiene el primer jueves. Algunos sistemas de estilo estadounidense empiezan el domingo y cuentan como Semana 1 la semana que contiene el 1 de enero. Alrededor de Año Nuevo, esas reglas pueden diferir una semana completa.

Si un informe dice “ingresos de Semana 1”, una exportación de nómina dice “2026-W01” y una hoja de cálculo usa su función por defecto, confirma la regla antes de reconciliar números. En equipos internacionales, la etiqueta más segura es el sistema de semana más el rango de fechas, por ejemplo: “ISO 2026-W01, 29 dic 2025-4 ene 2026”.

La misma lógica está en nuestra herramienta de número de semana, que muestra el rango de fechas en vez de tratar el número como autoexplicativo.

9. Filtraciones de zona horaria del servidor

Uno de los bugs de producción más frustrantes es el código que pasa todas las pruebas en local y falla al desplegar porque el servidor usa otra zona horaria. El portátil del desarrollador, el runner de CI, la imagen Docker, la base de datos, el worker de cola y el warehouse de analítica pueden tener defaults distintos.

Configura zonas horarias explícitas en tests. Ejecuta al menos un job de pruebas con una zona no local. Evita depender de defaults del proceso al parsear o formatear. Si una función recibe una cadena de fecha, haz que el formato esperado y la zona formen parte del contrato.

10. “Final del día” sin lugar

Final del día suena claro hasta que los clientes viven en más de un sitio. Una promoción que termina “el viernes a medianoche” puede significar medianoche local del cliente, medianoche de la sede de la empresa, medianoche UTC o el corte del procesador de pagos. Cada regla crea una experiencia distinta.

Un buen texto de producto nombra el lugar o usa una cuenta atrás vinculada al deadline real. Un buen backend guarda el deadline como un instante preciso después de aplicar la regla de negocio. Una buena documentación de soporte dice qué regla se utilizó.

Checklist práctica antes de publicar código de fecha/hora

  • ¿Este valor es un instante, una fecha/hora local, una fecha pura, una duración o una regla recurrente?
  • Si es local, ¿qué zona IANA posee la regla?
  • Si es una fecha pura, ¿hemos evitado inventar medianoche UTC?
  • ¿Los huecos y pliegues de DST tienen comportamiento explícito?
  • ¿Las unidades de timestamp están nombradas, validadas y probadas?
  • ¿Los informes definen el sistema de número de semana y el rango de fechas?
  • ¿Las pruebas se ejecutan fuera de la zona horaria del desarrollador?
  • ¿El texto visible dice lo suficiente para que una persona actúe correctamente?

La regla más profunda

Los bugs de fecha y hora rara vez se deben a falta de código ingenioso. Se deben a que falta un sustantivo. “Mañana” necesita un lugar. “Treinta días” necesita decir calendario o duración. “Semana 1” necesita un sistema. “Timestamp” necesita una unidad. “Final del día” necesita una jurisdicción o zona horaria.

Cuando el sustantivo es explícito, el código suele volverse más simple. La columna de base de datos recibe el tipo correcto. El contrato de la API sorprende menos. La interfaz puede explicar el resultado. Y la siguiente persona que lea el código no tendrá que reconstruir qué se suponía que significaba “ahora más un día”.

Lecturas relacionadas

← Volver a todos los artículos