12 horas vs 24 horas - Convenciones regionales
La elección de formato más básica es entre reloj de 12 horas (AM/PM) y reloj de 24 horas. El reloj de 12 horas domina el uso cotidiano en EE. UU., Canadá, Australia y Filipinas. El reloj de 24 horas es la norma en Europa continental, Japón, Corea y China. El Reino Unido ocupa una posición intermedia: el inglés hablado usa las 12 horas, pero los horarios de trenes y documentos oficiales usan las 24 horas.
El diseño de software correcto delega en la configuración regional del usuario en lugar de elegir un valor predeterminado global. Un servidor que codifica «14:30» se verá extraño para usuarios estadounidenses; «2:30 PM» parecerá pedante para quienes están acostumbrados al reloj de 24 horas. Respeta la configuración del sistema operativo o del navegador y deja que la capa de formato elija, en lugar de incrustar una decisión en la lógica de negocio.
ISO 8601 - Legible por máquinas, no por humanos
ISO 8601 (por ejemplo, 2026-05-15T16:30:00+09:00) es excelente para el intercambio de datos entre máquinas, pero no debería presentarse directamente a los usuarios finales. Úsalo para payloads de API, almacenamiento en base de datos y salida de logs, y luego convierte a un formato localizado legible por humanos en la capa de presentación. Mezclar roles entre formatos de máquina y humanos es la causa más común de quejas de usuarios sobre marcas de tiempo.
Hay una excepción: los paneles técnicos y las pantallas de depuración para ingenieros. El desfase de zona horaria explícito en ISO 8601 elimina la ambigüedad al comparar eventos entre regiones. Si tu audiencia es técnica o general determina si ISO 8601 es aceptable en la interfaz orientada al usuario.
La API Intl.DateTimeFormat de JavaScript proporciona formateo consciente de la configuración regional usando los datos de internacionalización del sistema operativo. new Intl.DateTimeFormat('ja-JP', { hour: '2-digit', minute: '2-digit' }).format(date) devuelve «16:30», mientras que cambiar la configuración regional a 'en-US' produce «4:30 PM». No se necesita ninguna biblioteca externa, y los datos se mantienen actualizados con las actualizaciones del sistema operativo.
Atención a dos trampas. Primero, dateStyle/timeStyle y opciones individuales (year/month/day/hour/minute) no pueden mezclarse en la misma llamada. Segundo, los navegadores varían ligeramente en detalles de salida como si aparecen espacios alrededor de AM/PM, por lo que las pruebas de snapshot pueden ser inestables. Usa aserciones de inclusión de cadena o normaliza la salida si necesitas fixtures de prueba estables.
Tiempo relativo - El patrón «hace 3 minutos»
Las aplicaciones sociales y de chat comúnmente muestran «hace 3 minutos» o «ayer» en lugar de horas absolutas. La intuición es simple, pero siguen varias decisiones de diseño. ¿Qué tan granular debe ser la visualización por debajo de un minuto (la mayoría de servicios colapsan a «justo ahora» por debajo de un minuto)? ¿Cuántos días hacia atrás antes de cambiar a fechas absolutas (Twitter cambia a las 24 horas, Facebook a los 7 días)? ¿Cómo se calcula «ayer» cuando el usuario cruza una zona horaria?
Intl.RelativeTimeFormat maneja la localización de la cadena resultante pero no elige la unidad apropiada (segundo, minuto, hora, día, semana, mes, año). Todavía necesitas una pequeña lógica para seleccionar la unidad correcta basándote en la magnitud de la diferencia. Varias bibliotecas (date-fns, plugin relativeTime de Day.js) envuelven esto por ti, pero las decisiones subyacentes siguen siendo tuyas.
Casos límite - 12:00 AM y 12:00 PM
El reloj de 12 horas tiene una famosa ambigüedad al mediodía y la medianoche. Por convención, 12:00 PM es mediodía y 12:00 AM es medianoche, pero esto es lógicamente inconsistente (PM significa post meridiem, después del mediodía, pero el mediodía mismo se etiqueta como PM). La industria de la aviación evita el problema usando la notación de 24 horas (00:00 para medianoche, 12:00 para mediodía), y los documentos legales en EE. UU. típicamente escriben «12:00 noon» o «12:00 midnight» explícitamente.
El enfoque defensivo en software es almacenar las horas internamente como enteros de 24 horas (0-23) y convertir solo al mostrar. Al aceptar entrada del usuario en formato de 12 horas, valida la interpretación AM/PM explícitamente e incluye 12:00 AM y 12:00 PM en los casos de prueba. Los errores en el límite mediodía/medianoche son fáciles de introducir y fáciles de pasar por alto en pruebas casuales.