Cómo formatear horas en la configuración regional del usuario
Usa JavaScript para mostrar horas según las convenciones regionales de cada usuario
Introducción
Las horas se muestran de forma diferente en todo el mundo. Los estadounidenses suelen ver las 3:30 PM mostradas como 3:30 PM, mientras que la mayoría de los europeos esperan 15:30. Cuando codificas un formato de hora de forma fija, asumes que todos los usuarios siguen la misma convención.
Mostrar horas en un formato desconocido crea confusión. Un usuario acostumbrado al formato de 24 horas que ve 3:30 PM debe convertirlo mentalmente para entender si representa la mañana o la tarde. Esta carga cognitiva se multiplica en cada hora de tu aplicación.
JavaScript proporciona la API Intl.DateTimeFormat para gestionar el formateo de horas automáticamente. Esta lección explica por qué los formatos de hora varían entre culturas, cómo funciona la API y cómo formatear horas correctamente para cualquier configuración regional.
Por qué los formatos de hora varían según la configuración regional
Diferentes regiones desarrollaron distintas convenciones para mostrar horas. Estas convenciones reflejan prácticas históricas, sistemas educativos y preferencias culturales. Ningún formato único es universal.
En Estados Unidos, Canadá, Australia y Filipinas, las horas usan formato de 12 horas con indicadores AM y PM. Las 3:30 de la tarde aparecen como 3:30 PM.
En la mayoría de los países europeos, América Latina y Asia, las horas usan formato de 24 horas sin indicadores AM o PM. La misma hora aparece como 15:30.
El carácter separador entre horas y minutos también varía. Los países de habla inglesa usan dos puntos, mientras que algunas configuraciones regionales usan puntos u otra puntuación.
La forma en que aparecen AM y PM también difiere. El inglés usa AM y PM, el español usa a.m. y p.m., y algunas configuraciones regionales colocan estos indicadores antes de la hora en lugar de después.
Cuando muestra horas, necesita coincidir con las expectativas del usuario tanto para el formato de hora como para las convenciones de formato específicas.
Uso de Intl.DateTimeFormat para formatear horas
El constructor Intl.DateTimeFormat crea un formateador que aplica convenciones específicas de la configuración regional. Para formatear horas, pase un identificador de configuración regional como primer argumento y especifique opciones relacionadas con la hora en el segundo argumento.
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
const date = new Date('2025-03-15T15:30:00');
console.log(formatter.format(date));
// Output: "3:30 PM"
Esto crea un formateador para inglés estadounidense que muestra horas y minutos. Las opciones hour y minute indican al formateador que incluya estos componentes. El método format() convierte el objeto Date en una cadena con el formato apropiado.
El constructor Date acepta una cadena de fecha y hora ISO 8601 como 2025-03-15T15:30:00. Esto crea un objeto Date que representa las 3:30 PM del 15 de marzo de 2025. El formateador luego convierte esto en una cadena de hora específica de la configuración regional.
Formateo de la misma hora para diferentes configuraciones regionales
Puede formatear la misma hora para diferentes configuraciones regionales cambiando el identificador de configuración regional pasado al constructor.
const date = new Date('2025-03-15T15:30:00');
const usFormatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
console.log(usFormatter.format(date));
// Output: "3:30 PM"
const gbFormatter = new Intl.DateTimeFormat('en-GB', {
hour: 'numeric',
minute: 'numeric'
});
console.log(gbFormatter.format(date));
// Output: "15:30"
const deFormatter = new Intl.DateTimeFormat('de-DE', {
hour: 'numeric',
minute: 'numeric'
});
console.log(deFormatter.format(date));
// Output: "15:30"
const frFormatter = new Intl.DateTimeFormat('fr-FR', {
hour: 'numeric',
minute: 'numeric'
});
console.log(frFormatter.format(date));
// Output: "15:30"
Cada formateador aplica diferentes convenciones. El formateador estadounidense usa formato de 12 horas con AM/PM. Los formateadores británico, alemán y francés usan formato de 24 horas sin indicadores AM/PM.
No necesita saber qué formato usa cada configuración regional. La API maneja estos detalles automáticamente según el identificador de configuración regional.
Inclusión de segundos en la visualización de hora
Puede agregar la opción second para mostrar segundos junto con horas y minutos.
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
});
const date = new Date('2025-03-15T15:30:45');
console.log(formatter.format(date));
// Output: "3:30:45 PM"
La opción second funciona de la misma manera que hour y minute. Establézcala en 'numeric' para incluir segundos en la salida.
Control del relleno de dígitos con 2-digit
Las opciones hour, minute y second aceptan dos valores: 'numeric' y '2-digit'. El valor 'numeric' muestra dígitos sin relleno, mientras que '2-digit' siempre muestra dos dígitos con ceros a la izquierda.
const date = new Date('2025-03-15T09:05:03');
const numericFormatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
});
console.log(numericFormatter.format(date));
// Output: "9:05:03 AM"
const twoDigitFormatter = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
console.log(twoDigitFormatter.format(date));
// Output: "09:05:03 AM"
El formateador numérico muestra 9:05:03 AM con un solo dígito para la hora. El formateador de dos dígitos muestra 09:05:03 AM con un cero inicial para la hora. Ambos muestran dos dígitos para minutos y segundos porque estos valores suelen rellenarse independientemente de la configuración.
Forzar formato de 12 o 24 horas
Por defecto, la API utiliza el formato de hora preferido por la configuración regional. Puede anular esto con la opción hour12.
const date = new Date('2025-03-15T15:30:00');
const hour12Formatter = new Intl.DateTimeFormat('en-GB', {
hour: 'numeric',
minute: 'numeric',
hour12: true
});
console.log(hour12Formatter.format(date));
// Output: "3:30 pm"
const hour24Formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: false
});
console.log(hour24Formatter.format(date));
// Output: "15:30"
Establecer hour12: true fuerza el formato de 12 horas incluso para configuraciones regionales que normalmente usan formato de 24 horas. Establecer hour12: false fuerza el formato de 24 horas incluso para configuraciones regionales que normalmente usan formato de 12 horas.
La configuración regional aún determina otros detalles de formato como puntuación y espaciado. El formateador del Reino Unido con hour12: true muestra 3:30 pm con pm en minúsculas, mientras que un formateador de EE. UU. mostraría 3:30 PM con PM en mayúsculas.
Formatear horas para la configuración regional del usuario
En lugar de codificar una configuración regional específica, puede usar el idioma preferido del usuario desde el navegador. La propiedad navigator.language devuelve la preferencia de idioma principal del usuario.
const userLocale = navigator.language;
const formatter = new Intl.DateTimeFormat(userLocale, {
hour: 'numeric',
minute: 'numeric'
});
const date = new Date('2025-03-15T15:30:00');
console.log(formatter.format(date));
// Output varies by user's locale
// For en-US: "3:30 PM"
// For en-GB: "15:30"
// For de-DE: "15:30"
// For fr-FR: "15:30"
Este enfoque muestra las horas según las expectativas de cada usuario sin requerir que seleccionen manualmente una configuración regional. El navegador proporciona la preferencia de idioma y la API Intl aplica las convenciones de formato apropiadas.
También puede pasar el array completo de idiomas preferidos para habilitar el comportamiento de respaldo.
const formatter = new Intl.DateTimeFormat(navigator.languages, {
hour: 'numeric',
minute: 'numeric'
});
const date = new Date('2025-03-15T15:30:00');
console.log(formatter.format(date));
La API utiliza la primera configuración regional que admite del array. Esto proporciona un mejor manejo de respaldo cuando la preferencia principal del usuario no está disponible.
Crear horas para formatear
Puede crear objetos Date con información de hora de varias maneras. El enfoque más confiable es usar cadenas de fecha y hora ISO 8601.
const time1 = new Date('2025-03-15T09:00:00');
const time2 = new Date('2025-03-15T15:30:00');
const time3 = new Date('2025-03-15T23:45:30');
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
console.log(formatter.format(time1));
// Output: "9:00 AM"
console.log(formatter.format(time2));
// Output: "3:30 PM"
console.log(formatter.format(time3));
// Output: "11:45 PM"
Las cadenas de fecha y hora ISO 8601 utilizan el formato YYYY-MM-DDTHH:MM:SS. La T separa la fecha de la hora. Este formato no es ambiguo y funciona de manera consistente en todas las configuraciones regionales y zonas horarias.
Formateo de horas desde marcas de tiempo
También puedes crear objetos Date desde marcas de tiempo Unix. Una marca de tiempo Unix representa el número de milisegundos desde el 1 de enero de 1970 UTC.
const timestamp = 1710515400000; // March 15, 2025 at 3:30 PM
const date = new Date(timestamp);
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
console.log(formatter.format(date));
// Output: "3:30 PM"
Este enfoque funciona cuando recibes marcas de tiempo desde APIs, bases de datos u otros sistemas que representan las horas como números.
También puedes pasar la marca de tiempo directamente al método format() sin crear primero un objeto Date.
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
const timestamp = 1710515400000;
console.log(formatter.format(timestamp));
// Output: "3:30 PM"
La API acepta tanto objetos Date como marcas de tiempo. Utiliza el enfoque que mejor se adapte a tu código.
Formateo de la hora actual
Para formatear la hora actual, crea un objeto Date sin argumentos. Esto crea un objeto Date que representa el momento actual.
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
});
const now = new Date();
console.log(formatter.format(now));
// Output: "3:45:12 PM" (or current time when run)
También puedes pasar Date.now() directamente, que devuelve la marca de tiempo actual como un número.
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
});
console.log(formatter.format(Date.now()));
// Output: "3:45:12 PM" (or current time when run)
Ambos enfoques producen resultados idénticos.
Reutilización de formateadores para mejorar el rendimiento
Crear una nueva instancia de Intl.DateTimeFormat implica cargar datos de configuración regional y procesar opciones. Cuando necesites formatear múltiples horas con la misma configuración regional y ajustes, crea el formateador una vez y reutilízalo.
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
const times = [
new Date('2025-03-15T09:00:00'),
new Date('2025-03-15T12:30:00'),
new Date('2025-03-15T18:45:00')
];
times.forEach(time => {
console.log(formatter.format(time));
});
// Output:
// "9:00 AM"
// "12:30 PM"
// "6:45 PM"
Este enfoque es más eficiente que crear un nuevo formateador para cada hora. La diferencia de rendimiento se vuelve significativa al formatear arrays con cientos o miles de valores de hora.
Formateo de horas en plantillas
Puedes usar Intl.DateTimeFormat en cualquier lugar donde muestres horas a los usuarios. Esto incluye insertar horas formateadas en plantillas HTML, mostrar horas en tablas o mostrar marcas de tiempo en interfaces de usuario.
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric'
});
const eventStart = new Date('2025-03-15T14:00:00');
const eventEnd = new Date('2025-03-15T16:30:00');
document.getElementById('start-time').textContent = formatter.format(eventStart);
document.getElementById('end-time').textContent = formatter.format(eventEnd);
Las cadenas formateadas funcionan como cualquier otro valor de cadena. Puedes insertarlas en contenido de texto, atributos o cualquier otro contexto donde muestres información a los usuarios.