Cómo formatear intervalos de tiempo como 2 horas 30 minutos
Muestra duraciones en el idioma del usuario con localización automática
Introducción
Cuando muestras cuánto tiempo dura algo, necesitas mostrar esa duración de una manera que los usuarios entiendan. Un video muestra un tiempo de reproducción de 2 horas 30 minutos, una aplicación de entrenamiento registra la duración del ejercicio, una herramienta de gestión de proyectos muestra el tiempo de finalización de tareas. Sin localización, podrías escribir código como este:
const hours = 2;
const minutes = 30;
const timeSpan = `${hours}h ${minutes}m`;
Esto produce "2h 30m" para todos los usuarios independientemente del idioma. Los usuarios franceses ven "2h 30m" cuando esperan "2 h 30 min". Los usuarios alemanes ven abreviaturas en inglés en lugar de "2 Std. 30 Min". Los usuarios españoles no obtienen la conjunción "y" entre unidades.
JavaScript proporciona la API Intl.DurationFormat para formatear intervalos de tiempo según el idioma y las convenciones culturales del usuario. Esta lección explica cómo crear formateadores de duración, construir objetos de duración y mostrar intervalos de tiempo correctamente para cualquier configuración regional.
Qué son los intervalos de tiempo
Un intervalo de tiempo representa una duración, no un momento específico. El número 150 minutos es una duración. El 15 de marzo de 2025 a las 2:30 PM es una fecha y hora.
Esta distinción es importante porque las fechas involucran calendarios, zonas horarias y reglas históricas. Los intervalos de tiempo miden el tiempo transcurrido sin contexto de calendario. No puedes añadir una zona horaria a una duración porque las duraciones existen independientemente de cualquier momento específico.
Utiliza Intl.DurationFormat para intervalos de tiempo. Utiliza Intl.DateTimeFormat para fechas y horas. Utiliza Intl.RelativeTimeFormat para expresiones relativas como "hace 2 horas".
Crear un formateador de duración
El constructor Intl.DurationFormat toma una configuración regional y un objeto de opciones. La configuración regional determina el idioma de salida. Las opciones controlan el estilo de formato y la visualización de unidades.
const formatter = new Intl.DurationFormat('en', { style: 'long' });
Llama a format() con un objeto de duración para producir una cadena formateada. El objeto de duración contiene propiedades numéricas para unidades de tiempo.
const duration = { hours: 2, minutes: 30 };
formatter.format(duration);
// "2 hours and 30 minutes"
La API maneja automáticamente abreviaturas, conjunciones, orden de palabras y espaciado según la configuración regional.
Construir objetos de duración
Un objeto de duración es un objeto JavaScript simple con propiedades para unidades de tiempo. Incluye solo las unidades que quieres mostrar.
const duration1 = { hours: 2, minutes: 30 };
const duration2 = { minutes: 5, seconds: 45 };
const duration3 = { hours: 1, minutes: 15, seconds: 30 };
La API admite estas unidades de tiempo: years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds.
No necesitas incluir todas las unidades. Omite cualquier unidad que no quieras mostrar.
const formatter = new Intl.DurationFormat('en', { style: 'long' });
formatter.format({ hours: 2, minutes: 30 });
// "2 hours and 30 minutes"
formatter.format({ minutes: 30 });
// "30 minutes"
formatter.format({ hours: 2 });
// "2 hours"
Elegir un estilo de formato
La opción style controla la densidad de la salida. Hay cuatro estilos disponibles: long, short, narrow y digital.
El estilo largo utiliza palabras completas. Úsalo para prosa y áreas de contenido principal.
const duration = { hours: 2, minutes: 30 };
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "2 hours and 30 minutes"
El estilo corto utiliza abreviaturas comunes. Úsalo cuando el espacio es limitado pero la legibilidad importa.
new Intl.DurationFormat('en', { style: 'short' }).format(duration);
// "2 hr and 30 min"
El estilo estrecho utiliza caracteres mínimos. Úsalo para visualizaciones compactas como interfaces móviles o tablas de datos.
new Intl.DurationFormat('en', { style: 'narrow' }).format(duration);
// "2h 30m"
El estilo digital produce una salida similar a un temporizador con dos puntos. Úsalo para reproductores multimedia y visualizaciones de cuenta regresiva.
new Intl.DurationFormat('en', { style: 'digital' }).format(duration);
// "2:30:00"
El estilo digital requiere que incluyas todas las unidades desde la más grande hasta la más pequeña. Si formateas horas y minutos, también debes incluir segundos.
Formatear intervalos de tiempo en diferentes idiomas
El mismo intervalo de tiempo se formatea de manera diferente en cada idioma. La API maneja toda la localización automáticamente.
const duration = { hours: 2, minutes: 30 };
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "2 hours and 30 minutes"
new Intl.DurationFormat('fr', { style: 'long' }).format(duration);
// "2 heures et 30 minutes"
new Intl.DurationFormat('de', { style: 'long' }).format(duration);
// "2 Stunden und 30 Minuten"
new Intl.DurationFormat('es', { style: 'long' }).format(duration);
// "2 horas y 30 minutos"
new Intl.DurationFormat('ja', { style: 'long' }).format(duration);
// "2時間30分"
Observe cómo cada localización utiliza diferentes palabras y conjunciones. El francés usa "et", el alemán usa "und", el español usa "y", el japonés no usa conjunciones. La API conoce estas reglas para cada localización.
Los estilos corto y estrecho también se localizan correctamente.
new Intl.DurationFormat('fr', { style: 'short' }).format(duration);
// "2 h et 30 min"
new Intl.DurationFormat('de', { style: 'narrow' }).format(duration);
// "2 Std. 30 Min."
Formatear intervalos de tiempo para la localización del usuario
En lugar de codificar una localización, utilice 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.DurationFormat(userLocale, { style: 'short' });
const duration = { hours: 2, minutes: 30 };
formatter.format(duration);
// La salida varía según la localización del usuario
// Para en-US: "2 hr and 30 min"
// Para de-DE: "2 Std. und 30 Min."
// Para fr-FR: "2 h et 30 min"
Esto muestra los intervalos de tiempo de acuerdo con las expectativas de cada usuario sin requerir una selección manual de localización.
Convertir milisegundos a objetos de duración
Los cálculos de tiempo a menudo producen milisegundos. Convierte los milisegundos a objetos de duración dividiéndolos por los factores apropiados.
const milliseconds = 9000000; // 2 horas 30 minutos
const hours = Math.floor(milliseconds / 3600000);
const minutes = Math.floor((milliseconds % 3600000) / 60000);
const seconds = Math.floor((milliseconds % 60000) / 1000);
const duration = { hours, minutes, seconds };
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "2 hours, 30 minutes and 0 seconds"
Omite los valores cero a menos que específicamente quieras mostrarlos.
const duration = {};
if (hours > 0) duration.hours = hours;
if (minutes > 0) duration.minutes = minutes;
if (seconds > 0) duration.seconds = seconds;
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "2 hours and 30 minutes"
Calcular intervalos de tiempo entre dos fechas
Calcula la duración entre dos fechas restando las marcas de tiempo, luego convierte el resultado a un objeto de duración.
const startTime = new Date('2025-10-15T10:00:00');
const endTime = new Date('2025-10-15T12:30:00');
const diffMs = endTime - startTime;
const hours = Math.floor(diffMs / 3600000);
const minutes = Math.floor((diffMs % 3600000) / 60000);
const duration = { hours, minutes };
new Intl.DurationFormat('en', { style: 'short' }).format(duration);
// "2 hr and 30 min"
Este enfoque funciona para cualquier cálculo de tiempo que produzca milisegundos.
Formatear duraciones de reproductores de video
Los reproductores de video muestran la duración en los controles. Utiliza el estilo digital o estrecho para una visualización compacta.
function formatVideoDuration(totalSeconds) {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = Math.floor(totalSeconds % 60);
const duration = hours > 0
? { hours, minutes, seconds }
: { minutes, seconds };
const locale = navigator.language;
return new Intl.DurationFormat(locale, { style: 'digital' }).format(duration);
}
formatVideoDuration(9000); // "2:30:00"
formatVideoDuration(330); // "5:30"
Esto incluye condicionalmente las horas solo cuando es necesario, mostrando "5:30" para videos cortos y "2:30:00" para contenido más largo.
Formatear duraciones de entrenamiento
Las aplicaciones de fitness registran la duración del ejercicio. Utiliza el estilo largo para los resúmenes de sesiones y el estilo estrecho para las vistas de lista compactas.
function formatWorkoutDuration(startTime, endTime, locale) {
const diffMs = endTime - startTime;
const hours = Math.floor(diffMs / 3600000);
const minutes = Math.floor((diffMs % 3600000) / 60000);
const duration = hours > 0
? { hours, minutes }
: { minutes };
return new Intl.DurationFormat(locale, { style: 'long' }).format(duration);
}
const workoutStart = new Date('2025-10-15T07:00:00');
const workoutEnd = new Date('2025-10-15T09:30:00');
formatWorkoutDuration(workoutStart, workoutEnd, 'en');
// "2 hours and 30 minutes"
formatWorkoutDuration(workoutStart, workoutEnd, 'es');
// "2 horas y 30 minutos"
Formatear duraciones de tareas de proyectos
Las herramientas de gestión de proyectos muestran cuánto tiempo toman las tareas. Utiliza el estilo corto para las visualizaciones del panel.
function formatTaskDuration(minutes, locale) {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
const duration = {};
if (hours > 0) duration.hours = hours;
if (mins > 0) duration.minutes = mins;
return new Intl.DurationFormat(locale, { style: 'short' }).format(duration);
}
formatTaskDuration(150, 'en');
// "2 hr and 30 min"
formatTaskDuration(45, 'en');
// "45 min"
formatTaskDuration(150, 'de');
// "2 Std. und 30 Min."
Formatear diferentes unidades de tiempo
Los intervalos de tiempo no se limitan a horas y minutos. Formatea cualquier combinación de unidades soportadas.
const formatter = new Intl.DurationFormat('en', { style: 'long' });
formatter.format({ days: 3, hours: 2 });
// "3 days and 2 hours"
formatter.format({ minutes: 45, seconds: 30 });
// "45 minutes and 30 seconds"
formatter.format({ hours: 1, minutes: 30, seconds: 45 });
// "1 hour, 30 minutes and 45 seconds"
La API maneja las conjunciones y separadores apropiados para cualquier combinación de unidades.
Formatear intervalos de tiempo con solo segundos
Cuando tu duración es menor a un minuto, incluye solo segundos.
const formatter = new Intl.DurationFormat('en', { style: 'short' });
formatter.format({ seconds: 45 });
// "45 sec"
formatter.format({ seconds: 5 });
// "5 sec"
Para duraciones muy cortas, puedes incluir milisegundos.
formatter.format({ seconds: 5, milliseconds: 500 });
// "5 sec and 500 ms"
Reutilizar instancias del formateador para mejorar el rendimiento
Crear un nuevo formateador implica cargar datos de localización y procesar opciones. Cuando formateas múltiples intervalos de tiempo con el mismo idioma y estilo, crea el formateador una vez y reutilízalo.
const formatter = new Intl.DurationFormat('en', { style: 'short' });
const durations = [
{ hours: 1, minutes: 30 },
{ hours: 2, minutes: 15 },
{ minutes: 45 }
];
durations.map(d => formatter.format(d));
// ["1 hr and 30 min", "2 hr and 15 min", "45 min"]
Este patrón mejora el rendimiento cuando se formatean muchas duraciones en bucles o renderizados repetidos.
Compatibilidad con navegadores
La API Intl.DurationFormat se convirtió en estándar en marzo de 2025. Funciona en las últimas versiones de Chrome, Edge, Firefox y Safari. Los navegadores más antiguos no soportan esta API.
Verifica la compatibilidad antes de usar la API.
if (typeof Intl.DurationFormat !== 'undefined') {
const formatter = new Intl.DurationFormat('en', { style: 'short' });
return formatter.format(duration);
} else {
return `${duration.hours}h ${duration.minutes}m`;
}
Esto proporciona una alternativa para navegadores antiguos mientras se utiliza la API nativa cuando está disponible.