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 tarda algo, necesitas mostrar esa duración de una manera que los usuarios comprendan. Un vídeo muestra una duración de 2 horas 30 minutos, una app de ejercicio rastrea 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 longitud de tiempo, no un punto en el tiempo. 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 importa 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.

Usa Intl.DurationFormat para intervalos de tiempo. Usa Intl.DateTimeFormat para fechas y horas. Usa 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 las unidades de tiempo.

const duration = { hours: 2, minutes: 30 };
formatter.format(duration);
// "2 hours and 30 minutes"

La API maneja abreviaturas, conjunciones, orden de palabras y espaciado automáticamente según la localización.

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 deseas 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 desees 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 salida. Hay cuatro estilos disponibles: long, short, narrow y digital.

El estilo largo usa palabras completas. Usa esto 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 usa abreviaturas comunes. Usa esto 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 usa caracteres mínimos. Usa esto para pantallas 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. Usa esto para reproductores multimedia y pantallas de cuenta regresiva.

new Intl.DurationFormat('en', { style: 'digital' }).format(duration);
// "2:30:00"

El estilo digital requiere que incluyas todas las unidades de mayor a menor. 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分"

Observa cómo cada localización usa 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 cortos y estrechos 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 según la configuración regional del usuario

En lugar de codificar una configuración regional, utiliza 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);
// Output varies by user's locale
// For en-US: "2 hr and 30 min"
// For de-DE: "2 Std. und 30 Min."
// For fr-FR: "2 h et 30 min"

Esto muestra los intervalos de tiempo según las expectativas de cada usuario sin requerir selección manual de configuración regional.

Convertir milisegundos a objetos de duración

Los cálculos de tiempo a menudo producen milisegundos. Convierte los milisegundos a objetos de duración dividiendo por los factores apropiados.

const milliseconds = 9000000; // 2 hours 30 minutes

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 que se muestren.

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 y 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 vídeo

Los reproductores de vídeo 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 sea necesario, mostrando "5:30" para vídeos cortos y "2:30:00" para contenido más largo.

Formatear duraciones de entrenamientos

Las aplicaciones de fitness rastrean la duración del ejercicio. Utiliza el estilo largo para resúmenes de sesiones y el estilo estrecho para 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 llevan las tareas. Utiliza el estilo corto para visualizaciones en el panel de control.

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 compatibles.

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 de formateador para mejorar el rendimiento

Crear un nuevo formateador implica cargar datos de configuración regional y procesar opciones. Cuando formateas múltiples intervalos de tiempo con la misma configuración regional 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 al formatear muchas duraciones en bucles o renderizados repetidos.

Compatibilidad con navegadores

La API Intl.DurationFormat se convirtió en Baseline en marzo de 2025. Funciona en las últimas versiones de Chrome, Edge, Firefox y Safari. Los navegadores más antiguos no son compatibles con 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 más antiguos mientras usa la API nativa cuando está disponible.