Cómo cambiar entre formato de 12 horas y 24 horas
Usa JavaScript para mostrar horas con AM/PM o en formato de 24 horas según las preferencias del usuario
Introducción
La hora aparece de manera diferente alrededor del mundo. Los estadounidenses típicamente ven 2:30 PM, mientras que los alemanes ven 14:30, y ambos representan el mismo momento. Cuando muestras horas en un solo formato, asumes que todos los usuarios siguen la misma convención.
Mostrar horas en un formato no familiar crea fricción. Un usuario que espera ver 14:30 pero ve 2:30 PM debe convertir mentalmente la hora. Un usuario que espera 2:30 PM pero ve 14:30 enfrenta el mismo problema. Esta carga cognitiva se repite para cada hora mostrada en tu aplicación.
JavaScript proporciona la API Intl.DateTimeFormat para manejar el formato de hora automáticamente. Esta lección explica por qué los formatos de hora varían, cómo la API controla la visualización de 12 horas versus 24 horas, y cuándo anular los valores predeterminados de la configuración regional.
Por qué los formatos de hora varían según la configuración regional
Diferentes regiones desarrollaron diferentes convenciones para mostrar la hora. Estas convenciones reflejan prácticas culturales, sistemas educativos y precedentes históricos. Ningún formato es universal.
En Estados Unidos, Canadá, Australia y Filipinas, el formato de 12 horas con indicadores AM/PM es estándar. La hora de la tarde aparece como 2:30 PM.
En la mayor parte de Europa, América Latina y Asia, el formato de 24 horas es estándar. La misma hora aparece como 14:30 sin necesidad de indicador AM/PM.
Algunas regiones utilizan ambos formatos dependiendo del contexto. El Reino Unido utiliza el formato de 24 horas para horarios de transporte pero el formato de 12 horas para la conversación cotidiana.
Cuando muestras horas, necesitas coincidir con las expectativas del usuario para su región y contexto.
Qué significan los formatos de 12 y 24 horas
El formato de 12 horas divide el día en dos períodos de 12 horas. Las horas van de 12 a 11, luego comienzan de nuevo. El sistema utiliza AM (ante meridiem) desde medianoche hasta mediodía y PM (post meridiem) desde mediodía hasta medianoche. La medianoche comienza a las 12:00 AM y el mediodía ocurre a las 12:00 PM.
12:00 AM → medianoche
1:00 AM → 1 hora después de medianoche
11:59 AM → 1 minuto antes del mediodía
12:00 PM → mediodía
1:00 PM → 1 hora después del mediodía
11:59 PM → 1 minuto antes de medianoche
El formato de 24 horas cuenta las horas continuamente de 0 a 23. La medianoche comienza a las 00:00 y el día termina a las 23:59. No se necesita indicador AM/PM porque cada hora tiene un número único.
00:00 → medianoche
01:00 → 1 hora después de medianoche
11:59 → 1 minuto antes del mediodía
12:00 → mediodía
13:00 → 1 hora después del mediodía
23:59 → 1 minuto antes de medianoche
Diferentes configuraciones regionales utilizan diferentes formatos por defecto. La API Intl.DateTimeFormat respeta estos valores predeterminados pero permite anularlos cuando sea necesario.
Uso de la opción hour12 para controlar el formato de hora
La opción hour12 controla si se usa el formato de 12 horas. Establécela como true para el formato de 12 horas con AM/PM, o false para el formato de 24 horas.
const date = new Date('2025-03-15T14:30:00');
const format12 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true
});
const format24 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: false
});
console.log(format12.format(date));
// Output: "2:30 PM"
console.log(format24.format(date));
// Output: "14:30"
La opción hour12 anula el comportamiento predeterminado del idioma. Aunque el inglés estadounidense normalmente usa el formato de 12 horas, establecer hour12: false fuerza el formato de 24 horas.
Debes incluir hour en las opciones o usar timeStyle para que la opción hour12 tenga efecto. Sin un componente de tiempo en la salida, la opción no tiene impacto.
Uso de la opción hourCycle para un control más preciso
La opción hourCycle proporciona más control que hour12 al especificar exactamente cómo se deben contar las horas. Acepta cuatro valores: "h11", "h12", "h23" y "h24".
const date = new Date('2025-03-15T00:30:00'); // 12:30 AM
const h11 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h11'
});
const h12 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12'
});
const h23 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h23'
});
const h24 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h24'
});
console.log(h11.format(date));
// Output: "0:30 AM"
console.log(h12.format(date));
// Output: "12:30 AM"
console.log(h23.format(date));
// Output: "00:30"
console.log(h24.format(date));
// Output: "24:30"
Cada valor de ciclo horario produce una salida diferente para la misma hora. Las diferencias se hacen más evidentes a medianoche y al mediodía.
Comprendiendo los cuatro valores de hourCycle
Los cuatro valores de hourCycle definen cómo se numeran las horas dentro de cada período.
El valor "h12" utiliza el formato de 12 horas con horas del 1 al 12. La medianoche aparece como 12:00 AM y el mediodía como 12:00 PM. Este es el formato estándar de 12 horas utilizado en los Estados Unidos.
El valor "h11" utiliza el formato de 12 horas con horas del 0 al 11. La medianoche aparece como 0:00 AM y el mediodía como 0:00 PM. Este formato es menos común pero aparece en algunos contextos.
El valor "h23" utiliza el formato de 24 horas con horas del 0 al 23. La medianoche aparece como 00:00 y el día termina a las 23:59. Este es el formato estándar de 24 horas utilizado en la mayor parte de Europa y Asia.
El valor "h24" utiliza el formato de 24 horas con horas del 1 al 24. La medianoche aparece como 24:00 desde la perspectiva del día anterior. Este formato es raro pero aparece en algunos contextos técnicos.
La mayoría de las aplicaciones utilizan "h12" para el formato de 12 horas o "h23" para el formato de 24 horas.
Comparando las horas a medianoche en diferentes ciclos horarios
La medianoche demuestra las diferencias entre los valores de ciclo horario de manera más clara.
const midnight = new Date('2025-03-15T00:00:00');
const cycles = ['h11', 'h12', 'h23', 'h24'];
cycles.forEach(cycle => {
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hourCycle: cycle
});
console.log(`${cycle}: ${formatter.format(midnight)}`);
});
// Output:
// h11: 0:00:00 AM
// h12: 12:00:00 AM
// h23: 00:00:00
// h24: 24:00:00
Los valores h12 y h23 producen las representaciones más familiares para sus respectivos formatos.
Comparando las horas al mediodía en diferentes ciclos horarios
El mediodía también muestra cómo difieren los ciclos horarios.
const noon = new Date('2025-03-15T12:00:00');
const cycles = ['h11', 'h12', 'h23', 'h24'];
cycles.forEach(cycle => {
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hourCycle: cycle
});
console.log(`${cycle}: ${formatter.format(noon)}`);
});
// Output:
// h11: 0:00:00 PM
// h12: 12:00:00 PM
// h23: 12:00:00
// h24: 12:00:00
De nuevo, h12 y h23 producen representaciones estándar mientras que h11 utiliza 0 para la hora del mediodía.
Cómo interactúan hour12 y hourCycle
Cuando especificas tanto hour12 como hourCycle, la opción hour12 tiene precedencia y la opción hourCycle se ignora.
const date = new Date('2025-03-15T14:30:00');
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true,
hourCycle: 'h23' // Esto se ignora
});
console.log(formatter.format(date));
// Output: "2:30 PM" (formato de 12 horas de hour12: true)
La configuración hour12: true fuerza el formato de 12 horas, anulando la configuración hourCycle: 'h23' que normalmente produciría un formato de 24 horas.
En la práctica, utiliza hour12 para un control simple o hourCycle para un control preciso, pero no ambos juntos.
Respetando los valores predeterminados de la configuración regional
Cuando omites tanto hour12 como hourCycle, el formateador utiliza el formato de hora predeterminado de la configuración regional.
const date = new Date('2025-03-15T14:30:00');
const usFormatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
const deFormatter = new Intl.DateTimeFormat('de-DE', {
hour: 'numeric',
minute: 'numeric'
});
const jpFormatter = new Intl.DateTimeFormat('ja-JP', {
hour: 'numeric',
minute: 'numeric'
});
console.log(usFormatter.format(date));
// Output: "2:30 PM" (predeterminado de EE.UU.: 12 horas)
console.log(deFormatter.format(date));
// Output: "14:30" (predeterminado alemán: 24 horas)
console.log(jpFormatter.format(date));
// Output: "14:30" (predeterminado japonés: 24 horas)
La configuración regional de EE.UU. utiliza por defecto el formato de 12 horas, mientras que las configuraciones regionales alemana y japonesa utilizan por defecto el formato de 24 horas. Respetar estos valores predeterminados proporciona la experiencia más familiar para los usuarios de cada región.
Anulación de los valores predeterminados de configuración regional
Puedes anular el formato de hora predeterminado de una configuración regional estableciendo explícitamente hour12 o hourCycle.
const date = new Date('2025-03-15T14:30:00');
// Forzar la configuración regional alemana para usar formato de 12 horas
const de12 = new Intl.DateTimeFormat('de-DE', {
hour: 'numeric',
minute: 'numeric',
hour12: true
});
// Forzar la configuración regional de EE.UU. para usar formato de 24 horas
const us24 = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: false
});
console.log(de12.format(date));
// Salida: "2:30 PM"
console.log(us24.format(date));
// Salida: "14:30"
Este enfoque funciona cuando necesitas imponer un formato de hora específico independientemente de la configuración regional del usuario.
Cuándo respetar los valores predeterminados de configuración regional
La mayoría de las aplicaciones deberían respetar los valores predeterminados de configuración regional. Los usuarios de cada región esperan que las horas aparezcan en el formato que les resulta familiar. Anular estos valores predeterminados crea confusión.
Permite que el formateador utilice el formato de hora predeterminado de la configuración regional cuando muestre horas a los usuarios en su propia región.
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric'
});
const time = new Date('2025-03-15T14:30:00');
console.log(formatter.format(time));
// La salida varía según la configuración regional del usuario
// Para en-US: "2:30 PM"
// Para de-DE: "14:30"
// Para ja-JP: "14:30"
Este enfoque se adapta automáticamente a las expectativas de cada usuario sin requerir configuración.
Cuándo anular los valores predeterminados de configuración regional
Anula los valores predeterminados de configuración regional cuando tu aplicación requiere consistencia para todos los usuarios. Los sistemas de transporte, aplicaciones militares y herramientas técnicas a menudo necesitan formato de 24 horas independientemente de la configuración regional.
// Usar siempre formato de 24 horas para horarios de vuelos
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric',
hour12: false
});
const departureTime = new Date('2025-03-15T14:30:00');
console.log(`Salida: ${formatter.format(departureTime)}`);
// Salida: "Salida: 14:30" (para todas las configuraciones regionales)
Esto asegura consistencia cuando se muestran horas que los usuarios necesitan referenciar con precisión, como horarios, registros o marcas de tiempo.
También puedes anular los valores predeterminados cuando los usuarios seleccionan explícitamente una preferencia. Si tu aplicación ofrece una configuración para elegir entre formato de 12 horas y 24 horas, usa esa preferencia en lugar del valor predeterminado de la configuración regional.
function formatTime(date, userPrefers24Hour) {
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric',
hour12: !userPrefers24Hour
});
return formatter.format(date);
}
const time = new Date('2025-03-15T14:30:00');
console.log(formatTime(time, false));
// Salida: "2:30 PM"
console.log(formatTime(time, true));
// Salida: "14:30"
Este patrón respeta la elección del usuario mientras sigue localizando otros aspectos de la visualización de la hora como los caracteres separadores y la dirección del texto.
Uso de hour12 con timeStyle
La opción hour12 funciona con los estilos preestablecidos de timeStyle. Esto te permite controlar el formato de hora mientras sigues utilizando estilos preestablecidos convenientes.
const date = new Date('2025-03-15T14:30:45');
const short12 = new Intl.DateTimeFormat('en-US', {
timeStyle: 'short',
hour12: true
});
const short24 = new Intl.DateTimeFormat('en-US', {
timeStyle: 'short',
hour12: false
});
const medium12 = new Intl.DateTimeFormat('en-US', {
timeStyle: 'medium',
hour12: true
});
const medium24 = new Intl.DateTimeFormat('en-US', {
timeStyle: 'medium',
hour12: false
});
console.log(short12.format(date));
// Output: "2:30 PM"
console.log(short24.format(date));
// Output: "14:30"
console.log(medium12.format(date));
// Output: "2:30:45 PM"
console.log(medium24.format(date));
// Output: "14:30:45"
Este enfoque simplifica el formateo al combinar estilos preestablecidos con control explícito del formato de hora.
Formateo de horas para múltiples locales
Cuando tu aplicación atiende a usuarios en múltiples regiones, formatea las horas según las convenciones de cada locale.
const date = new Date('2025-03-15T14:30:00');
const locales = [
{ code: 'en-US', name: 'United States' },
{ code: 'en-GB', name: 'United Kingdom' },
{ code: 'de-DE', name: 'Germany' },
{ code: 'ja-JP', name: 'Japan' }
];
locales.forEach(locale => {
const formatter = new Intl.DateTimeFormat(locale.code, {
hour: 'numeric',
minute: 'numeric'
});
console.log(`${locale.name}: ${formatter.format(date)}`);
});
// Output:
// United States: 2:30 PM
// United Kingdom: 14:30
// Germany: 14:30
// Japan: 14:30
Cada locale utiliza automáticamente su formato preferido. No necesitas saber qué regiones utilizan qué formato.
Verificación del ciclo horario resuelto
Puedes verificar qué ciclo horario utiliza realmente el formateador llamando a resolvedOptions().
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric'
});
const options = formatter.resolvedOptions();
console.log(options.hourCycle);
// Output: "h12"
console.log(options.hour12);
// Output: true
Este método devuelve la configuración real que utiliza el formateador después de resolver todos los valores predeterminados del locale y las opciones explícitas. El objeto devuelto incluye tanto las propiedades hourCycle como hour12 cuando hay componentes de tiempo presentes.
Formateo de horas en plantillas
Puedes usar horas formateadas en cualquier lugar donde muestres información temporal a los usuarios. Esto incluye insertar horas en HTML, mostrar marcas de tiempo en registros o visualizar horarios.
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric'
});
const meetingTime = new Date('2025-03-15T14:30:00');
const deadlineTime = new Date('2025-03-15T17:00:00');
document.getElementById('meeting').textContent = formatter.format(meetingTime);
document.getElementById('deadline').textContent = formatter.format(deadlineTime);
Las cadenas formateadas funcionan como cualquier otro valor de cadena. Puedes insertarlas en contenido de texto, atributos o cualquier contexto donde muestres información a los usuarios.
Qué recordar
Usa la opción hour12 para cambiar entre el formato de 12 horas y el de 24 horas. Establécela como true para el formato de 12 horas con AM/PM o false para el formato de 24 horas.
Utiliza la opción hourCycle para un control preciso sobre la numeración de horas. El valor "h12" proporciona el formato estándar de 12 horas y "h23" proporciona el formato estándar de 24 horas.
Respeta los valores predeterminados de la configuración regional en la mayoría de las aplicaciones. Los usuarios esperan que las horas aparezcan en el formato familiar de su región. Anula los valores predeterminados solo cuando la consistencia entre todos los usuarios es más importante que respetar las convenciones regionales.
Combina hour12 con los preajustes de timeStyle para controlar el formato de hora mientras utilizas estilos preestablecidos convenientes para otros componentes de tiempo.