
Cuando trabajamos en una aplicación, en particular de lado de la UI, el cómo mostramos la información es un punto importante para que nuestra interfaz sea entendible, estética y, por supuesto, funcional. En muchos casos esta información es texto plano que basta con mostrar tal como lo tenemos, pero en otros casos trabajamos con valores númericos, booleanos o cadenas de texto (strings) que necesitamos mostrar con formatos específicos.
En esta ocasión quiero centrarme en 2 de los más comunes, fechas
y valores que querramos mostrar como moneda
(e.j. $10.00).
Para estos casos seguramente has pensado que lo mejor sea utilizar una librería tipo date-fns
o momentJS
para el formato de fechas y dinero.js
para el formato de moneda, pero puede no ser la mejor idea, ¿a qué me refiero? en muchos casos simplemente necesitamos cambiar Thu Aug 04 2022 16:42:27 GMT-0500 (hora de verano central)
por 04/08/2022
o agregar un $
al valor númerico 10.00
, e instalar una librería para solo hacer esto parece excesivo, ¿no crees?.
Las alternativas
Clase Date
Date.toLocaleDateString
Lo más simple es utilizar el método toLocaleDateString
que nos proporciona la clase Date
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Si buscas utilizar el formato de diferentes regiones del mundo (locale
):
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Y también puedes cambiar el formato en que se muestra el día
o mes
por ejemplo:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Las keys
más utilizadas que podemos agregar al objeto de options
son:
weekday
, valores posibles => "narrow", "short", "long"era
, valores posibles => "narrow", "short", "long"year
, valores posibles => "numeric", "2-digit"month
, valores posibles => "narrow", "short", "long", "numeric", "2-digit"day
, valores posibles => "numeric", "2-digit"hour
, valores posibles => "numeric", "2-digit"minute
, valores posibles => "numeric", "2-digit"second
, valores posibles => "numeric", "2-digit"timeZoneName
, valores posibles => "narrow", "short", "long"hour12
, selecciona si usar horario de 12 horas o 24 horas y depende dellocale
, valores posibles => "true", "false"
Hay otras opciones que podemos agregar que son menos comunes, si quieres explorarlas te comparto este artículo donde las puedes explorar.
Por último, este método nos permite añadir un locale
de respaldo en caso de que el que hayamos solicitado no esté soportado:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Muy útil, ¿no te parece?. Esta alternativa es perfecta para cuando las operaciones que necesitamos hacer con las fechas no son complicadas. Sin embargo, te quiero compartir otra alternativa, perfecta para casos donde necesitas un poco más de opciones para formatear las fechas y (aquí va la sorpresa) que también nos permite dar formato a listas de valores (arrays) y números (además de formato a fechas, claro), ¡Una verdadera maravilla de JavaScript!
Objeto Intl
El objeto Intl
nos permite acceder a la API de internacionalización
de ECMAScript
, que proporciona comparación de cadenas sensible al idioma, formato de números y formato de fecha y hora. El objeto Intl
proporciona acceso a varios métodos útiles para internacionalización y a otras funciones sensibles al lenguaje.
Intl.DateTimeFormat
Siguiendo la línea de formato de fechas, veamos cómo es que haríamos lo mismo que hicimos con Date
, pero ahora con Intl
:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Al igual que con el método toLocaleDateString
, podemos pasar un objeto de opciones para modificar el formato con que se muestran algunas secciones de la fecha:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Las keys
que vimos previamente también aplican para DateTimeFormat
. Sin embargo, tenemos la posibilidad de añadir algunas otras para configurar aún más cómo es que queremos mostrar nuestras fechas, te dejo la referencia para que las puedas revisar por aquí.
A este punto no hay mucha diferencia o una razón en particular para usar una forma o la otra, más allá de tu preferencia personal, si la implementación que buscas es tan simple como lo anterior, pero ahora te voy a mostrar un método de Intl
que me parece increible.
Intl.RelativeTimeFormat
Si lo que necesitas es mostrar una fecha en formato relativo
, es decir, algo como "dentro de 3 días" o "el año pasado", entonces este método es perfecto.
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Nota: Para expresar fechas pasadas, el valor que colocamos es negativo
Si lo que quieres es cambiar el formato del mensaje, puedes pasar un objeto de options
.
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Puedes revisar el resto de las opciones posibles aquí.
Importante: Observa que este método no recibe un objeto de fecha, solo recibe un valor númerico y un identificador temporal (day o month) que sirve para el formato internacionalizado. El cálculo para sacar el valor númerico lo tenemos que hacer nosotros, pero no te preocupes, más adelante de digo cómo.
¡Basta de fechas!
Como te mencioné al principio de este artículo, el formato de moneda es otro de los que posiblemente ocupes más y que también veremos aquí y sí, Intl
también nos cubre con esto.
Intl.NumberFormat
Este método permite formatear los números en función del idioma, siendo el formato de moneda al que le daremos prioridad, pero igual te comentaré un poco los demás, ya sabes, por no dejar.
El uso es simple y muy similar a lo que hemos visto hasta el momento.
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Genial, ¿no?, vamos a mejorarlo.
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Importante: En los ejemplos anteriores el primer valor (es-ES o en-US) corresponde al locale y es el que determina realmente cómo es que se mostrará nuestro valor por lo que aunque estemos mostrando pesos mexicanos (MXN) el formato en que se muestra puede variar segun el locale, veamos un ejemplo:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
A pesar de que en los 2 casos estamos mostrando pesos mexicanos (MXN) indicado en la llave currency
de las options, la forma en la que se muestra el valor es distinto debido a que los locales, son distintos, uno es formato europeo (es-ES o español de españa) y el otro es formato mexicano (es-MX).
Por último, hay otra propiedad de las options
que podemos pasar que me parece interesante y que me gustaría compartirte, currencyDisplay
.
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Puedes revisar el resto de las opciones posibles aquí.
Finalmente, quiero mencionar otras opciones que tiene NumberFormat
, las unidades y los porcentajes
Unidades
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Puedes revisar el resto de las unidades posibles aquí.
Porcentaje
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Bonus
Adicional a lo que hemos visto quiero platicarte de otros métodos que tiene Intl
que también son interesantes:
Intl.ListFormat
Este método es en realidad muy simple, nos permite mostrar una lista legible de valores para cada idioma partiendo de una array de valores
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Puedes cambiar la forma en la que se muestra la lista agregando la llave type
al objeto de options:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Los valores posibles son:
conjunction
, para listas de tipo "y"disjunction
para listas de tipo "o"unit
si la lista es de unidades de medida, que se suelen poner en forma de lista de modo diferente.
Intl.PluralRules
Este método lo podemos describir como algo más avanzado y está pensado para ser una ayuda cuando necesitamos pluralizar valores o palabras, pero ojo, no funciona pasando una cadena y que nos devuelva el valor pluralizado, el funcionamiento es de más bajo nivel.
Por ejemplo, en español, inglés u otros idiomas occidentales una viga mide 1 metro (singular), 3 metros (plural) o, curiosamente, 0 metros (plural aunque sea cero). Sin embargo, en árabe tiene otras acepciones para ciertos números.
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Como puedes observar, para los idiomas occidentales generalmente hay dos posibilidades: 'one' (singular) o 'other' (plural), y con eso podemos decidir si se le pone una "s" al final o no, por ejemplo:
Si hablamos de pez (singular)
y peces (plural)
, no es simplemente agregar una s
. Sin embargo, para casos más simples puede ser de mucha ayuda.
Ahora sí, para terminar...
Si llegaste hasta aquí, agradezco que te hayas tomado el tiempo de leer este post y quiero cerrar con lo que prometí antes: un par de algoritmos que nos ayuden a completementar y sacar el mayor provecho de lo que acabamos de ver.
Cambiar el estilo de cómo mostramos la fecha
Si queremos cambiar el caracter con el que mostramos la fecha, directamente con estos métodos no es posible, pero si hacemos un poco de algoritmia podemos lograrlo:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Sacar los días entre 2 fechas para usarlos con RelativeTimeFormat
En realidad es muy simple ya que con JavaScript podes operar fechas de forma que podamos sacar como entero los días, años o meses entre 2 fechas.
Ejemplo con días:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Efectos secundarios con useEffect
Checa este otro Post
