Cómo mostrar AM/PM o períodos del día específicos según la configuración regional

Usa JavaScript para mostrar períodos de tiempo que coincidan con la forma en que cada cultura divide el día

Introducción

Cuando muestras una hora como las 4:00, los usuarios necesitan contexto para saber si ocurre por la mañana o por la tarde. En inglés, se añade AM o PM para aclarar. Las 4:00 AM ocurren antes del amanecer, mientras que las 4:00 PM ocurren por la tarde.

Otros idiomas no traducen simplemente AM y PM. Muchas culturas dividen el día en más de dos períodos, con términos específicos para la madrugada, la mañana, la tarde, el atardecer y la noche. El español tiene "madrugada" para las horas después de medianoche pero antes del amanecer. El alemán divide el día en seis períodos distintos en lugar de dos. Algunos idiomas llaman a la 1:00 AM "1 de la noche" en lugar de "1 de la mañana".

La función Intl.DateTimeFormat de JavaScript proporciona la opción dayPeriod para mostrar automáticamente estas divisiones de tiempo específicas de cada cultura. Esta lección explica cómo funcionan los períodos del día en diferentes culturas, por qué son importantes para las aplicaciones internacionales y cómo formatear las horas con etiquetas de período del día apropiadas.

Por qué los períodos del día varían según la cultura

Diferentes culturas desarrollaron distintas formas de dividir el día de 24 horas en períodos con nombres específicos. Estas divisiones reflejan cómo las personas en cada cultura piensan y hablan sobre el tiempo.

Los hablantes de inglés dividen el día en cuatro períodos. La mañana (morning) va desde la medianoche hasta el mediodía, la tarde (afternoon) desde el mediodía hasta el atardecer, el atardecer (evening) desde el final de la tarde hasta que oscurece, y la noche (night) desde que oscurece hasta la medianoche. Los términos AM y PM proporcionan un sistema más simple de dos períodos para el reloj de 12 horas.

Los hablantes de español reconocen la "madrugada" como un período distinto que cubre las horas después de la medianoche pero antes de que la gente típicamente se despierte. Esto crea un sistema de cinco períodos que distingue entre las horas tardías de la noche y las horas tempranas de la mañana.

Los hablantes de ruso usan "ночь" (noche) para referirse a cualquier hora cuando las personas normalmente están dormidas. La 1:00 AM es "1 de la noche" en lugar de "1 de la mañana" porque la gente normalmente está durmiendo a esa hora.

El alemán divide el día en seis períodos. "Morgen" (mañana), "Vormittag" (media mañana), "Mittag" (mediodía), "Nachmittag" (tarde), "Abend" (atardecer) y "Nacht" (noche), cada uno cubriendo rangos específicos de horas.

El indonesio usa "pagi" (amanecer hasta las 10 AM), "siang" (10 AM hasta las 2 PM), "sore" (2 PM hasta la puesta del sol) y "malam" (noche) para dividir el día en cuatro períodos basados en la posición del sol.

El bengalí divide el día en seis períodos. "ভোর" (amanecer), "সকাল" (mañana), "দুপুর" (primera parte de la tarde), "বিকাল" (última parte de la tarde), "সন্ধ্যা" (atardecer) y "রাত" (noche), cada uno con rangos de tiempo específicos.

Cuando muestras horas en una aplicación internacional, necesitas usar términos que coincidan con la forma en que los usuarios de cada cultura hablan naturalmente sobre el tiempo. Mostrar "4 AM" a todos los usuarios ignora cómo otros idiomas describen esa hora.

Entendiendo la opción dayPeriod

La opción dayPeriod en Intl.DateTimeFormat indica al formateador que incluya el período del día específico del idioma al formatear una hora. En lugar de mostrar solo la hora y los minutos, el formateador añade el término apropiado para ese momento del día en el idioma de destino.

Esta opción funciona solo con formatos de 12 horas. En formatos de 24 horas, el número de la hora por sí mismo proporciona suficiente contexto. 04:00 es claramente mañana y 16:00 es claramente tarde sin etiquetas adicionales. Los períodos del día existen para desambiguar las horas repetidas en el formato de 12 horas.

La opción dayPeriod acepta tres valores. narrow produce la forma más corta posible, a menudo una sola letra o abreviatura. short produce una forma abreviada. long produce la palabra o frase completa.

Para muchos idiomas, estos tres valores producen resultados idénticos. Los datos de configuración regional de Unicode no definen formas distintas para cada combinación de idioma y longitud de formato. Cuando no existen formas distintas, el formateador utiliza la misma salida independientemente del valor que especifiques.

Formateando horas con períodos del día

Para mostrar un período del día, crea una instancia de Intl.DateTimeFormat con la opción dayPeriod establecida en narrow, short o long. También debes incluir una opción de componente de tiempo como hour y especificar un formato de 12 horas usando hourCycle.

const date = new Date('2025-01-15T04:30:00');

const formatter = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});

console.log(formatter.format(date));
// Output: "4:30 in the morning"

Esto crea un formateador que muestra la hora, los minutos y el período del día. La opción hourCycle: 'h12' especifica el formato de 12 horas, que es necesario para que aparezcan los períodos del día. La opción dayPeriod: 'long' solicita la frase completa del período del día.

Sin la opción dayPeriod, el formateador mostraría "4:30 AM" en su lugar. La opción de período del día reemplaza el indicador simple de AM/PM con una frase más descriptiva.

Mostrando períodos del día en diferentes horas

Los períodos del día cambian según la hora que se está formateando. El formateador selecciona automáticamente el período apropiado para cada hora de acuerdo con las convenciones del idioma.

const options = {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
};

const formatter = new Intl.DateTimeFormat('en-US', options);

const morning = new Date('2025-01-15T04:30:00');
console.log(formatter.format(morning));
// Output: "4:30 in the morning"

const afternoon = new Date('2025-01-15T14:30:00');
console.log(formatter.format(afternoon));
// Output: "2:30 in the afternoon"

const evening = new Date('2025-01-15T20:30:00');
console.log(formatter.format(evening));
// Output: "8:30 in the evening"

const night = new Date('2025-01-15T23:30:00');
console.log(formatter.format(night));
// Output: "11:30 at night"

El inglés distingue entre mañana, tarde, noche y madrugada. Cada hora recibe la frase apropiada según la hora. No es necesario determinar qué período aplica. El formateador maneja esto automáticamente basándose en los datos de configuración regional de Unicode.

Comparando formatos estrecho, corto y largo

Los tres formatos de longitud producen diferentes resultados en algunos idiomas. Las diferencias varían según el idioma y pueden ser sutiles o inexistentes.

const date = new Date('2025-01-15T04:30:00');

const narrow = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'narrow'
});
console.log(narrow.format(date));
// Output: "4 in the morning"

const short = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'short'
});
console.log(short.format(date));
// Output: "4 in the morning"

const long = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});
console.log(long.format(date));
// Output: "4 in the morning"

Para el inglés estadounidense, las tres longitudes producen resultados idénticos. Los datos de configuración regional no definen formas diferentes para esta combinación de idioma y hora.

Algunos idiomas sí distinguen entre longitudes. El francés produce diferentes resultados para los formatos estrecho y largo.

const date = new Date('2025-01-15T04:30:00');

const frNarrow = new Intl.DateTimeFormat('fr-FR', {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'narrow'
});
console.log(frNarrow.format(date));
// Output: "4 mat."

const frLong = new Intl.DateTimeFormat('fr-FR', {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});
console.log(frLong.format(date));
// Output: "4 du matin"

El francés usa "mat." como forma abreviada y "du matin" como forma larga. Ambas significan mañana, pero la forma larga es más explícita.

A menos que tengas restricciones específicas de espacio que requieran la salida más corta posible, usa long para mayor claridad. Las formas más largas son más fáciles de entender para los usuarios, y muchos idiomas no proporcionan alternativas más cortas de todos modos.

Cómo funcionan los períodos del día en diferentes locales

Diferentes locales utilizan diferentes términos para los períodos del día y dividen el día con límites distintos. El formateador aplica automáticamente las convenciones para cada locale.

const date = new Date('2025-01-15T04:30:00');
const options = {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
};

const enUS = new Intl.DateTimeFormat('en-US', options);
console.log(enUS.format(date));
// Output: "4 in the morning"

const enGB = new Intl.DateTimeFormat('en-GB', options);
console.log(enGB.format(date));
// Output: "4 at night"

const deDK = new Intl.DateTimeFormat('de-DE', options);
console.log(deDK.format(date));
// Output: "4 morgens"

const fr = new Intl.DateTimeFormat('fr-FR', options);
console.log(fr.format(date));
// Output: "4 du matin"

El inglés británico considera que las 4:30 AM es "at night" (de noche) en lugar de "in the morning" (por la mañana), reflejando diferentes límites culturales para los períodos del día. El alemán usa "morgens" para las horas de la mañana. El francés usa "du matin" para el mismo período.

Estas diferencias no son errores ni inconsistencias. Reflejan diferencias culturales genuinas en cómo las personas conceptualizan y hablan sobre el tiempo. El formateador respeta estas diferencias automáticamente según el locale.

Los períodos del día requieren formato de 12 horas

La opción dayPeriod solo funciona cuando se especifica un formato de 12 horas usando hourCycle: 'h12' o hourCycle: 'h11'. Sin un formato de 12 horas, los períodos del día no aparecen.

const date = new Date('2025-01-15T04:30:00');

const with12Hour = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});
console.log(with12Hour.format(date));
// Output: "4 in the morning"

const with24Hour = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  hourCycle: 'h23',
  dayPeriod: 'long'
});
console.log(with24Hour.format(date));
// Output: "04"

El formato de 24 horas no muestra el período del día aunque la opción esté especificada. En el formato de 24 horas, el número de hora proporciona suficiente contexto sin etiquetas adicionales.

La diferencia entre h12 y h11 se relaciona con cómo se numeran la medianoche y el mediodía. Use h12 para el reloj estándar de 12 horas donde las horas van de 1 a 12. Use h11 para un sistema de horas de 0 a 11. Ambos funcionan con períodos del día.

Combinando períodos del día con minutos y segundos

Puedes incluir minutos y segundos junto con los períodos del día. El formateador posiciona el período del día apropiadamente según las convenciones del idioma.

const date = new Date('2025-01-15T04:30:45');

const withMinutes = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});
console.log(withMinutes.format(date));
// Output: "4:30 in the morning"

const withSeconds = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});
console.log(withSeconds.format(date));
// Output: "4:30:45 in the morning"

El período del día aparece después de los componentes de tiempo. No necesitas posicionar o formatear manualmente el período del día. El formateador maneja la disposición según las convenciones del idioma.

Formateando horas con períodos del día para el idioma del usuario

En lugar de codificar un idioma específico, utiliza el idioma preferido del usuario desde el navegador. La propiedad navigator.language devuelve la preferencia de idioma principal del usuario.

const date = new Date('2025-01-15T04:30:00');

const formatter = new Intl.DateTimeFormat(navigator.language, {
  hour: 'numeric',
  minute: 'numeric',
  hourCycle: 'h12',
  dayPeriod: 'long'
});

console.log(formatter.format(date));
// El resultado varía según el idioma del usuario
// Para en-US: "4:30 in the morning"
// Para en-GB: "4:30 at night"
// Para de-DE: "4:30 morgens"
// Para fr-FR: "4:30 du matin"

Este enfoque muestra las horas con períodos del día que coinciden con la forma en que cada usuario habla naturalmente sobre el tiempo. El navegador proporciona la preferencia de idioma, y la API Intl aplica los términos y límites apropiados del período del día.

Cuándo usar períodos del día

Los períodos del día funcionan bien cuando quieres proporcionar más contexto que los simples indicadores AM/PM. Hacen que las horas sean más conversacionales y más fáciles de interpretar a primera vista.

Utiliza períodos del día en interfaces de usuario donde las horas aparecen junto con texto descriptivo. Un calendario que muestra "4:30 de la mañana" es más claro que "4:30 AM" porque la frase suena más natural en el texto corrido.

Utiliza períodos del día en notificaciones y mensajes donde el lenguaje conversacional mejora la legibilidad. "Tu reunión comienza a las 8:30 de la noche" se lee mejor que "Tu reunión comienza a las 8:30 PM".

Evita los períodos del día en pantallas compactas donde el espacio es limitado. Las tablas, gráficos y diseños densos funcionan mejor con indicadores estándar AM/PM o formato de 24 horas.

Evita los períodos del día cuando muestres horas en formato de 24 horas. El período del día no añade información útil cuando el número de hora ya indica la hora del día.

Resumen

La opción dayPeriod en Intl.DateTimeFormat muestra términos específicos de cada cultura para los momentos del día. Diferentes culturas dividen el día de manera distinta, usando términos como "madrugada" en español o seis períodos distintos en alemán en lugar de solo AM y PM.

La opción acepta tres valores. narrow produce la forma más corta, short produce una forma abreviada, y long produce la frase completa. Muchas configuraciones regionales producen resultados idénticos para los tres valores.

Los períodos del día solo aparecen cuando se utiliza el formato de 12 horas especificado con hourCycle: 'h12' o hourCycle: 'h11'. No aparecen en el formato de 24 horas porque el número de hora proporciona contexto suficiente.

Diferentes configuraciones regionales utilizan diferentes términos para los períodos del día y establecen límites en diferentes horas. El formateador aplica estas convenciones automáticamente según el identificador de configuración regional. El inglés británico trata las 4:30 AM como "at night" (por la noche) mientras que el inglés americano lo trata como "in the morning" (por la mañana).