Artículos de Tecnología

¿Cómo formatear fechas, horas y monedas en JavaScript?

Camila Pessoa
Camila Pessoa
IMG1-portada alt="Imagen de portada del artículo, con fondo azul y código binario dispuesto de forma aleatoria, con los siguientes escritos: "Internacionalización. Fechas, horas y monedas".

Presentación

World Wide Web es fascinante porque puede conectar personas en diferentes lugares del mundo. Alguien en Japón puede acceder a una página brasileña o viceversa, ¡y eso es maravilloso! Esto, es lo que llamamos Internacionalización, ya que los recursos de aplicaciones, sistemas web y sitios están disponibles en todo el mundo.

Sin embargo, diferentes lugares tienen normas y estándares culturales distintos, que no se limitan al idioma, como las convenciones de formatos de fecha, hora, unidades de medida, temperatura, peso, entre otros.

[TOC]

Un ejemplo clásico es el formato de fecha en Estados Unidos, donde típicamente las fechas tienen la estructura "mes/día/año" (por ejemplo, 08/21/1988), mientras que en Brasil y en varios países de Latinoamérica las fechas comienzan con el día, con la estructura "día/mes/año" (por ejemplo, 21/08/1988, ¡mi cumpleaños, anótalo!).

Imagina el escenario de una tienda en línea estadounidense en la que necesitas completar un formulario con tu fecha de nacimiento y usas el formato brasileño. Probablemente el formulario mostrará un error si la aplicación no tiene configuraciones de conversión de acuerdo con la ubicación del navegador del cliente.

O imagina que trabajas en Japón y quieres seguir los partidos del campeonato brasileño de fútbol en streaming, pero la plataforma que muestra los partidos no ha configurado los horarios y fechas para convertirlos según la ubicación del navegador del cliente. Probablemente te perderás tus partidos favoritos porque no tienes la orientación correcta del huso horario.

GIF1 Alt: El gif en repetición muestra un fragmento de video que se hizo viral en la Copa Mundial de 2014. Aparece un hombre de aparentemente 55 años, caucásico y con bigote. Está viendo un partido de Brasil en un estadio y lleva una camiseta de la selección brasileña en color amarillo y verde, al igual que otros aficionados que aparecen en el fondo. Está abrazado a una réplica de la Copa del Mundo con una expresión de profunda tristeza.

Fuente: tenor

Además de estas cuestiones, pueden surgir otras situaciones con un impacto aún mayor en tus proyectos, por lo que es importante comprender algunos aspectos relevantes sobre estas normas.

¿Y cómo tratamos estas convenciones en nuestros proyectos con JavaScript? ¡Una solución es convertir la información!

En este artículo utilizaremos el lenguaje JavaScript para trabajar con estas soluciones, y para eso, necesitamos recordar brevemente algunos puntos sobre el objeto Date. Luego estableceremos las conversiones para garantizar la internacionalización de la información mediante el método toLocale() y entenderemos cómo se puede utilizar la API de internacionalización Intl para este propósito, ambas soluciones nativas de JavaScript.

¿Vamos?

Internacionalización con los objetos Intl y Date

El objeto global Date funciona como un constructor para fechas en JavaScript. Cada vez que creas un new Date(), se generará una nueva instancia con la fecha, la hora, la zona horaria y el desplazamiento horario. Puedes trabajar de forma independiente con meses, horas, minutos, etc. Puedes profundizar en el tema con dos artículos: "Trabajando con fechas en JavaScript" y "Objeto Date y formato de fechas en JavaScript".

En este momento, es importante comprender que JavaScript proporciona varios métodos nativos para manipular fechas, así como las localidades asociadas con el objeto global Date. Pero, ¿cómo funciona esto en la práctica?

En el siguiente código, puedes ver un ejemplo que crea una nueva fecha utilizando new Date():

const nuevaFecha = new Date(Date.UTC(2023, 09, 20, 10, 11, 08));
console.log(nuevaFecha);

Observa que ya utilizamos un método para crear la fecha en el formato UTC, y su sintaxis es la siguiente: Date.UTC(año, mes[, día[, hora[, minuto[, segundo[, milisegundo]]]]]). Sin embargo, la salida no es muy legible, como se muestra a continuación:

2023-10-20T10:11:08.000Z
¿Cómo podemos resolver este problema?

Podemos utilizar el método toLocaleString() para formatear la fecha y hora de acuerdo con las especificaciones de localización, como se muestra en el siguiente código:

const nuevaFecha = new Date(Date.UTC(2023, 09, 20, 10, 11, 08));
console.log(nuevaFecha.toLocaleString('es-PY', { timeZone: 'UTC' }));

La salida será presentada de la siguiente manera:

20/10/2023, 10:11:08

¡Mucho más legible, ¿verdad? Ahora podemos entender que tenemos una fecha y hora en nuestro formato brasileño.

También existe otra forma similar de utilizar los objetos Intl. Veamos un ejemplo:

const nuevaFecha = new Date(Date.UTC(2023, 09, 20, 10, 11, 08));
const fechaConIntl = new Intl.DateTimeFormat('es-CL', {
    dateStyle: 'short',
    timeStyle: 'long',
    timeZone: 'America/Santiago',
});
console.log(fechaConIntl.format(nuevaFecha));

El código anterior formatea la fecha creada y produce la siguiente salida:

20-10-23, 07:11:08 CLST

Bastante similar a lo realizado en el código con el método toLocaleString(), ¿verdad?

Sin embargo, el objeto Intl es un namespace para la API de Internacionalización y sus métodos de formateo. Incluso su nombre proviene de la abreviatura de "Internationalization" (Internacionalización en español).

Esta API de internacionalización formatea y manipula números, fechas y textos (tipos de datos string) de acuerdo con el estándar de una región determinada. Una de sus propiedades, por ejemplo, es Intl.DateTimeFormat, que formatea y presenta horas y fechas según las convenciones de una localidad específica.

Para manipular fechas, horas o monedas, debes llamar al namespace Intl, aplicar la notación de punto y luego el método deseado para el formateo.

A continuación, se utilizan varios argumentos para especificar el parámetro locales (el argumento que identifica la localidad), basados en las Etiquetas de Idioma (BCP 47, que en términos simples son es-CL o en-US para definir el idioma y la ubicación), y también hay un parámetro options, que son opciones designadas por un objeto que contiene las especificaciones del tipo de número, moneda, fecha o cualquier otra información que se vaya a formatear.

Como se puede observar en el fragmento de código que formatea nuestra fecha const fechaConIntl, para formatear una fecha y hora con Intl.DateTimeFormat, creamos una nueva fecha con el constructor new Date() y luego indicamos las especificaciones con el método DateTimeFormat() y sus argumentos locales y options. Luego, se utiliza el método format(), que se llama para realizar la acción en la fecha creada.

De esta manera, es posible aplicar el mismo formato a diferentes fechas. ¿Muy interesante, verdad? Vamos a profundizar con más ejemplos de formateo. Sigue el siguiente tema.

Fecha y hora

Hay numerosas formas de formatear fecha y hora en JavaScript, algunas más complejas y otras más simples. La idea es presentar estrategias nativas de JavaScript para que no tengas que formatear el día, año y mes de forma aislada.

Objeto Date y formateo

Es posible utilizar numerosos métodos con el objeto Date para manipular fechas y tiempos de acuerdo con la localidad. Un método muy común es toLocaleDateString() y su sintaxis se define con el objeto date, el método y los argumentos locales y options que ya estudiamos en el tema anterior:

 dateObj.toLocaleDateString([locales [, options]])
// Formateo de la fecha actual con locales
const nuevaFecha = new Date();
console.log(nuevaFecha); // Fecha sin formato
console.log(nuevaFecha.toLocaleDateString('pt-BR')); // Fecha en portugués día/mes/año
console.log(nuevaFecha.toLocaleDateString('ko-KR')); // Fecha en coreano año.mes.día.

También podemos personalizar los resultados con el parámetro options:

// Formateo de la fecha actual con options
const opciones = {
  weekday: 'long',
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  timezone: 'UTC',
};
console.log(nuevaFecha.toLocaleDateString('pt-BR', opciones));
console.log(nuevaFecha.toLocaleDateString('ko-KR', opciones));

La salida muestra el día de la semana, el día en números, el mes escrito de forma completa (por ejemplo: enero, en lugar de ene) y el año en números. El primer console.log() está en portugués y el segundo en coreano.

Pero, ¿qué sucede si tengo una fecha fija? Como la fecha de un cumpleaños o la fecha de entrega de un paquete. A continuación, se muestra el formato de una fecha fija:

// Formateo de una fecha
const miCumpleanios = '1988-08-21';
const fechaCreada = new Date(miCumpleanios);
const fechaFormateada = fechaCreada.toLocaleDateString('es-BO', {
  timeZone: 'UTC',
});
console.log(`Mi cumpleaños es ${fechaFormateada}`); // Mi cumpleaños es 21/08/1988

Nota: Es importante destacar que esto no es una traducción al español, ya que la frase en el template string seguirá igual si se escribe en otro idioma.

Hasta ahora hemos analizado solo un método que se puede utilizar con el objeto Date para formatear fecha y hora. Sin embargo, hay una variedad de métodos para el formateo y puedes realizar pruebas e implementaciones siguiendo la documentación: Referencia del objeto global Date en MDN.

Los métodos de Date son muy eficientes, pero hay otra forma de internacionalización que veremos en el próximo tema.

Objeto Intl y formateo

Además de los métodos del objeto Date, la API de internacionalización también puede formatear fecha y hora según la localidad. Veamos en el siguiente código:

const fechaActual = new Date();
console.log(fechaActual); // La salida será la fecha actual sin formato
const fechaFormateada = new Intl.DateTimeFormat('es-BO', {
    dateStyle: 'full',
    timeStyle: 'long',
    timeZone: 'America/La_Paz',
});
console.log(fechaFormateada.format(fechaActual)); // La salida será la fecha actual formateada con la hora

El parámetro locales define el idioma y la región para el español de Bolívia (es-BO). A continuación, tenemos un objeto con las especificaciones de dateStyle y timeStyle, que definen el estilo de presentación de la información.

En el ejemplo, hemos elegido dateStyle: 'full', que mostrará la fecha completa en texto con el día de la semana, día, mes y año. Del mismo modo, timeStyle: 'long' mostrará la hora completa con horas : minutos : segundos y la especificación de la zona horaria, que en el código, se ha especificado timeZone: 'America/La_Paz', por lo que mostrará la zona horaria de Bolivia. Si no especificas una timeZone, JavaScript tomará el horario del runtime.

El método Intl.DateTimeFormat tiene un objeto options como parámetro, en el cual debes especificar las configuraciones de localización, {locale: 'es-BO'}, para que las convenciones de cada localidad se ajusten a lo deseado.

También puedes formatear la fecha para mostrar solo una opción, como el año con 'year', el día de la semana con weekday' o la hora con 'hour'.

Pero esta salida de información se parece mucho a la proporcionada por JavaScript a través del método toLocaleString(), ¿verdad? Entonces, ¿cuáles son las diferencias?

La API Intl devuelve un objeto DateTimeFormat basado en las directivas definidas en options y formateado con el método format(). Aunque es muy similar a toLocaleString(), la diferencia principal radica en que en Intl.DateTimeFormat se pasa la fecha como argumento en el método format(), mientras que toLocaleString se aplica a un objeto que contiene la información de una fecha.

Un punto a tener en cuenta es que no necesitas conocer las configuraciones de todas las localidades o regiones. Con Intl.Locale() puedes establecer el ciclo de horas y ver las timeZones aceptadas, revisa a continuación:

const portugues = new Intl.Locale('pt-BR', { hourCycle: 'h12' });
console.log(
  portugues.language,
  portugues.hourCycle,
  portugues.region,
  portugues.timeZones
);

La salida muestra la información de la región y la zona horaria:

pt h12 BR [
  'America/Araguaina',
  'America/Bahia',
  'America/Belem',
  'America/Boa_Vista',
  'America/Campo_Grande',
  'America/Rio_Branco',
  'America/Santarem',
  'America/Sao_Paulo'
]

También existe la posibilidad de asignar un formato de tiempo relativo, en caso de que desees crear un cronómetro o una notificación de programación, por ejemplo:

// Formatear tiempo relativo con el idioma del lugar
const tiempoRelativo = new Intl.RelativeTimeFormat('es-BO', { numeric: 'auto' });
console.log(tiempoRelativo.format(2, 'month'));// dentro de 2 meses

La salida muestra la información "dentro de 2 meses", es decir, es un conteo de tiempo relativo. ¿Ya puedes imaginar los posibles usos? ¡Vamos a reflexionar más sobre esto a continuación!

¿Cuando debemos usar Intl o Date?

Una pregunta que puede surgir es: ¿Cuál es el objeto más adecuado si ambos funcionan de manera similar?

En algunas ocasiones, los métodos del objeto Date, como toLocaleString(), tienen la ventaja de ser más simples de usar. Sin embargo, según la documentación, cuando tenemos una gran cantidad de números que manipular o problemas relacionados con la visualización en el navegador, se recomienda utilizar la API Intl. Además, existen algunos problemas de versiones, como se puede ver en este Issue en GitHub.

Al igual que con fechas y horas, las unidades de medida numéricas y las propias monedas no están estandarizadas. ¿Cómo podemos formatear también los números? ¡Descubre cómo hacerlo a continuación!

Números y monedas

Imagina que al acceder a una plataforma de compras en línea de otro país te encuentras con un superdescuento y, emocionado por comprar todas las prendas, compras 4 camisas por 40,00. Pero lo que no te diste cuenta es que el valor estaba en dólares y en tu tarjeta de crédito te llegó la cuenta en soles (en ealtl día de tu compra, 1.0 dólar equivalía aproximadamente a 3.62 soles).

GIF2 alt="Muestra al personaje del dibujo animado japonés Naruto Uzumaki, tiene el pelo amarillo puntiagudo, piel clara, usa una banda en la frente con el símbolo en espiral que representa su aldea de la hoja. Tiene los ojos entrecerrados, las cejas tensas y lágrimas caen repetidamente por su rostro."

Un pequeño error por parte del equipo de desarrollo de la plataforma generó un problema serio para varios clientes. ¿Cómo resolver esta cuestión?

¡Conversión de números! Sin embargo, esta respuesta puede generar otra pregunta: ¿los números son equivalentes a las monedas?

Sí y no, un dato del tipo Number por sí solo no es una moneda, ya que los valores monetarios son diferentes según la ubicación. En este caso, utilizamos los números en programación de la misma manera que en el mundo real, es decir, necesitamos realizar la conversión de los valores. Esto significa que le indicamos a nuestro programa, a través del lenguaje de programación, que realice la conversión. Por ejemplo: "¡Toma este número 3 y conviértelo en 3,00 reales!"

¿Vamos a entenderlo en la práctica?

Objeto Intl y formateo de monedas

El siguiente código formatea un valor del tipo Number a monedas, es decir, convierte un número a su equivalente en moneda:

const numero = 50.0;
console.log(
  new Intl.NumberFormat('es-PE', { style: 'currency', currency: 'PEN' }).format(
    numero
  )
);// salida S/ 50.00

console.log(
  new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(
    numero
  )
);// salida 50,00 €

En ambos ejemplos se realiza el formateo del valor inicial, que es un dato del tipo Number, a su equivalente en Sol Peruano y Euro. Este formateo se realiza de acuerdo con lo que deseamos mostrar en pantalla, ya que insertamos las propiedades en el objeto como argumento del parámetro options, de la misma forma en que trabajamos con fechas y horas.

Observamos que no se trata de una conversión directa de un valor de Sol a Euro, ya que esa conversión podría requerir el uso de APIs, bibliotecas o incluso un manejo más complejo de la información en el código. Sin embargo, ya tenemos las herramientas necesarias para mostrar la información deseada en nuestros proyectos.

También es posible trabajar con el método toLocaleString(), como veremos en el próximo tema.

toLocaleString() y formateo de monedas

El formateo con el método toLocaleString() sigue la misma lógica. El siguiente código muestra el valor de la const numero = 50.0 formateado según las localidades de Estados Unidos y Japón:

const numero = 50.0;

const formatoEua = numero.toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
});
console.log(formatoEua);// salida $50.00

const formatoJp = numero.toLocaleString('jp-JP', {
  style: 'currency',
  currency: 'JPY',
});
console.log(formatoJp); // salida JP¥ 50

Observamos que la salida ya incluye la identificación de la moneda local y el estilo de visualización. La forma de mostrar la moneda puede establecerse en el objeto, en nuestro código utilizamos la propiedad style, que define el estilo de presentación y se establece con el valor 'currency', que significa moneda. A su vez, la moneda se representa con el código ISO 4217 de cada localidad, que en este ejemplo son USD y JPY.

También podemos definir cómo se muestra la moneda utilizando la propiedad currencyDisplay, donde podemos elegir mostrar la información en formato extenso o utilizando el símbolo de la moneda, como se muestra a continuación:

const formatoBr = numero.toLocaleString('pt-BR', {
  style: 'currency',
  currency: 'BRL',
  currencyDisplay: 'name',
});
console.log(formatoBr);

Y la salida será "50,00 Reales brasileños". Muy útil, ¿verdad?

Probablemente, en este punto pueda surgir la duda sobre qué método utilizar para formatear monedas. La respuesta está relacionada con tus necesidades, ya que la recomendación es la siguiente: si tienes una gran cantidad de números, lo ideal es crear un objeto con Intl.NumberFormat y formatearlos utilizando el método Intl.NumberFormat.prototype.format().

Recordemos que el método toLocaleString() se puede asociar al objeto global Number, es decir, se utiliza para formatear números y no solo monedas. Por eso es importante definir la propiedad style con el valor 'currency', de esta manera el dato se formateará como moneda.

Conclusión

En este artículo hemos comprendido que formatear fechas y números en JavaScript no tiene por qué ser una película de terror. Hay varias opciones que puedes utilizar. Existen muchos métodos, objetos y APIs. Pero ahora ya tienes la base para elegir la mejor forma y aplicarla según el contexto de tu proyecto.

Hemos aprendido que el objeto global Date se utiliza como constructor en JavaScript para fechas, y se pueden asociar varios métodos a él para formatear fechas, como toLocaleString().

Por otro lado, Intl.Locale es un conjunto de reglas y convenciones para formatear datos, como formatos de fecha y hora, símbolos de moneda y separadores de números. El objeto Intl proporciona una API de internacionalización en JavaScript que se puede utilizar para formatear y mostrar fechas, horas, números y cadenas de acuerdo con las convenciones de una localidad específica.

Bueno, ahora puedes trabajar con dos formas de formatear fechas, horas y monedas según la localidad, y así integrar tu proyecto con el estándar de internacionalización.

Además, tienes el conocimiento esencial para probar otros métodos. Consulta ejemplos con fragmentos de código, los famosos snippets, en el repositorio Interactive Examples de MDN para realizar nuevas implementaciones en tus proyectos.

Por último, con todo lo que has aprendido, te propongo un desafío: crea tu propio convertidor de monedas y mejora aún más tu portafolio.

¡Felices estudios y nos vemos pronto!

autora

Camila Pessôa

¡Hola, soy Camila! Tengo 33 años, soy madre y me adentré en el área de la tecnología a través de la robótica educativa. Participé en el Bootcamp { Reprograma } con enfoque en Back-End /Node.js y actualmente estoy estudiando Sistemas de Información. Formo parte del equipo Scuba-Team y tengo una gran pasión por la educación y la tecnología, ya que creo que esta combinación tiene un poder transformador.

Adaptado para Alura Latam por Priscila Storck.

Artículos de Tecnología

En Alura encontrarás variados cursos sobre . ¡Comienza ahora!

Precios en:
USD
  • USD
  • BOB
  • CLP
  • COP
  • USD
  • PEN
  • MXN
  • UYU

Semestral

  • 274 cursos

    Cursos de Programación, Front End, Data Science, Innovación y Gestión.

  • Videos y actividades 100% en Español
  • Certificado de participación
  • Estudia las 24 horas, los 7 días de la semana
  • Foro y comunidad exclusiva para resolver tus dudas
  • Luri, la inteligencia artificial de Alura

    Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana

  • Acceso a todo el contenido de la plataforma por 6 meses
US$ 65.90
un solo pago de US$ 65.90
¡QUIERO EMPEZAR A ESTUDIAR!

Paga en moneda local en los siguientes países

Anual

  • 274 cursos

    Cursos de Programación, Front End, Data Science, Innovación y Gestión.

  • Videos y actividades 100% en Español
  • Certificado de participación
  • Estudia las 24 horas, los 7 días de la semana
  • Foro y comunidad exclusiva para resolver tus dudas
  • Luri, la inteligencia artificial de Alura

    Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana

  • Acceso a todo el contenido de la plataforma por 12 meses
US$ 99.90
un solo pago de US$ 99.90
¡QUIERO EMPEZAR A ESTUDIAR!

Paga en moneda local en los siguientes países

Bootcamp Back End

  • 274 cursos

    Cursos de Programación, Front End, Data Science, Innovación y Gestión.

  • Videos y actividades 100% en Español
  • Certificado de participación
  • Estudia las 24 horas, los 7 días de la semana
  • Foro y comunidad exclusiva para resolver tus dudas
  • Luri, la inteligencia artificial de Alura

    Luri es nuestra inteligencia artificial que resuelve dudas, da ejemplos prácticos y ayuda a profundizar aún más durante las clases. Puedes conversar con Luri hasta 100 mensajes por semana

  • Acceso a la Formación - Aprende Java con Orientación a Objetos - Bootcamp Back End Java

    Aprende a programar en uno de los principales lenguajes de programación para el back-end en el mercado: Java. En este módulo, tendrás la oportunidad de conocer las principales bibliotecas de Java y dominar el paradigma de la Orientación a Objetos.

  • Acceso a todo el contenido de la plataforma por 6 meses
US$ 149.90
un solo pago de US$ 149.90
¡QUIERO EMPEZAR A ESTUDIAR!

Paga en moneda local en los siguientes países

Acceso a todos
los cursos

Estudia las 24 horas,
dónde y cuándo quieras

Nuevos cursos
cada semana