Luxon: una nueva biblioteca para trabajar con fechas del equipo de Moment.js



Parecería, ¿por qué necesitamos otra biblioteca para trabajar con fechas y horas cuando hay una biblioteca Moment bien conocida? Lo más interesante es que la alternativa fue propuesta por el equipo de Moment.

La biblioteca Luxon se declara como una herramienta poderosa, moderna y conveniente para trabajar con fechas y horas en JavaScript. La biblioteca fue creada por Isaac Cambron, miembro del equipo de desarrollo de Moment desde 2013.

El autor tenía muchas ideas para desarrollar Moment, que no pudo hacer en el marco del código existente. Estos son los puntos principales que quería implementar:

  • pruebe algunas ideas sobre cómo hacer que la API sea más lógica (pero estas ideas no eran compatibles con el enfoque adoptado por Moment),
  • implemente el trabajo "listo para usar" con zonas horarias sin extensiones adicionales,
  • repensar completamente el trabajo con internacionalización, teniendo en cuenta el advenimiento de la API Intl,
  • cambiar a un conjunto moderno de herramientas y enfoques en la formación de código JS.

Por lo tanto, decidió escribir todo desde cero, lo que tomó alrededor de dos años.
El resultado es una especie de versión modernizada de Moment.
La versión resultante parecía interesante para todo el equipo de desarrollo de Moment, por lo que se decidió promover la nueva biblioteca bajo los auspicios del equipo.

Principios de Luxon


  1. Cadenas de llamadas como en Momento.
  2. Todos los tipos son inmutables.
  3. API más clara y obvia: para diferentes objetos: diferentes métodos con parámetros claramente definidos.
  4. API Intl para la internacionalización (retroceder a la versión en inglés si el navegador no es compatible con la API Intl).
  5. API internacional para trabajar con zonas horarias.
  6. Soporte más completo para calcular la duración.
  7. Soporte de intervalo nativo.
  8. Documentación de código en línea.

Estos principios han llevado a las siguientes mejoras:

  • El código de Luxon es mucho más fácil de entender y depurar.
  • El uso de las capacidades integradas del navegador para la internacionalización mejora el comportamiento de la biblioteca y, nuevamente, facilita la depuración.
  • El soporte de zona horaria se implementa mejor que en cualquier otra biblioteca JS.
  • Luxon proporciona una herramienta simple y muy poderosa para trabajar con duración.
  • La biblioteca tiene buena documentación.

Pero Luxon tiene sus inconvenientes:

  • El énfasis en el uso de las capacidades integradas del navegador genera dificultades para admitir navegadores más antiguos.
  • Algunas funciones de internacionalización que aún no son compatibles con los navegadores tampoco se implementan en la biblioteca (es de esperar que este soporte aparezca en los navegadores).
  • La implementación de la API Intl en diferentes navegadores puede variar, respectivamente, el comportamiento de Luxon también variará.

Instalación


Luxon proporciona módulos para todas las plataformas JavaScript modernas.

La documentación tiene una lista completa de navegadores compatibles con restricciones de aplicación. Para los navegadores que no tienen o tienen soporte internacional limitado, se recomienda utilizar un archivo polifiliar (en particular, esto se aplica a IE 10 u 11).

Cuando trabaje con Node.js (6+), si necesita trabajar con configuraciones regionales, deberá instalar adicionalmente el paquete full-icu y establecer la variable de entorno para permitir el uso de este paquete.

El método de instalación estándar de npm:
npm install --save luxon

Luxon tiene soporte para TypeScript y Flow, también hay un módulo en formato ES6.

Revisión rápida


La biblioteca Luxon consta de cinco clases principales:

DateTime : fecha y hora con zona horaria y configuraciones de visualización, así como métodos relacionados.
Duración : un período de tiempo (duración), por ejemplo, "2 meses" o "1 día, 3 horas".
Información : métodos estáticos para obtener datos generales sobre hora y fecha.
Intervalo : intervalo de tiempo y métodos para trabajar con él.
Las configuraciones son métodos estáticos que definen el comportamiento general de Luxon.

import {DateTime, Duration, Info, Interval, Settings} from 'luxon'; 

Tu primera fecha y hora


La clase más importante en Luxon es DateTime. DateTime representa fecha + hora junto con la zona horaria y la configuración regional. Así es como puede configurar el 15 de mayo de 2017 a las 08:30 en la zona horaria local:

 var dt = DateTime.local(2017, 5, 15, 8, 30); 

Aquí está la llamada para determinar la hora actual:

 var now = DateTime.local(); 

Crear desde objeto


 DateTime.fromObject({ month:12, day: 22, hour: 12, minutes: 20, zone: 'Europe/Kaliningrad' }); //=> 2018-12-22T12:20:00.000+02:00 

Crear desde una cadena en formato ISO 8601


 DateTime.fromISO("2017-05-15"); //=> May 15, 2017 at 0:00 DateTime.fromISO("2017-05-15T08:30:00"); //=> May 15, 2017 at 8:30 

Al convertir a una cadena, Luxon también devuelve una cadena en formato ISO 8601:

 DateTime.local().toString(); //=> "2018-12-18T20:58:29.995+03:00" 

Obtención de componentes individuales:


 var dt = DateTime.local(); dt.year; //=> 2018 dt.month; //=> 12 dt.day; //=> 18 dt.second; //=> 27 dt.weekday; //=> 2 dt.zoneName; //=> "Europe/Moscow" dt.offset; //=> 180 dt.daysInMonth; //=> 31 

Salida formateada


Luxon tiene muchos métodos para convertir DateTime en una cadena, dos de ellos son los más importantes paraLocaleString y toISO, el primero se convierte a un formato teniendo en cuenta la laca del navegador y el segundo prepara el texto para el procesamiento programático (por ejemplo, para transferir a un servidor):

 dt.toLocaleString(); //=> "18.12.2018" dt.toLocaleString(DateTime.DATETIME_MED); //=> "18 . 2018 ., 21:46" dt.toISO(); //=> "2018-12-18T21:46:55.013+03:00" 

Luxon tiene dos docenas de "ajustes preestablecidos" listos para la salida formateada (como DATETIME_MED y TIME_WITH_LONG_OFFSET).

También puede crear su propia opción de formato basada en tokens:

 dt.setLocale('ru').toFormat('d MMMM tt - ZZZZZ'); //=> "18  21:46:55 - ,  " 

Conversiones de fecha y hora


Nota importante: los objetos Luxon son inmutables, es decir cualquier método de modificación que se les aplique devolverá la copia modificada sin cambiar el objeto original. Por lo tanto, todos los términos en este artículo (como en la documentación de Luxon) como "cambiar", "instalar", "redefinir" deben entenderse como "crear una nueva instancia con otras propiedades".

Transformaciones matematicas


 var dt = DateTime.local(2018, 12, 18, 20, 30); //=> "18.12.2018, 20:30" dt.plus({hours: 3, minutes: 2}); //=> "18.12.2018, 23:32" dt.minus({days: 7}); //=> "11.12.2018, 20:30" dt.startOf('day'); //=> "18.12.2018, 0:00" dt.endOf('hour'); //=> "18.12.2018, 20:00" 

Anulación de parámetros individuales


 var dt = DateTime.local(); dt.set({hour: 3}).hour //=> 3 

Conversiones Intl


Luxon admite varias transformaciones Intl diferentes, una de las más importantes es el formateo para diferentes configuraciones regionales:

 var dt = DateTime.local(); var f = {month: 'long', day: 'numeric'}; dt.setLocale('fr').toLocaleString(f); //=> "18 décembre" dt.setLocale('en-GB').toLocaleString(f); //=> "18 December" dt.setLocale('en-US').toLocaleString(f); //=> "December 18" 

La clase Info puede devolver listas de meses y días de la semana en una localidad determinada:

 Info.months('long', {locale: 'it'}); //=> ["gennaio", "febbraio", "marzo", ...] Info.weekdays ('short', {locale: 'de'}); //=> ["Mo", "Di", "Mi", ...] 

Zonas horarias


Luxon admite zonas horarias. Si crea un DateTime sin especificar explícitamente una zona horaria, la zona local se seleccionará de manera predeterminada. Si cambia la zona para un DateTime existente, la hora y la fecha se volverán a calcular teniendo en cuenta la diferencia entre las zonas horarias.

 var dt = DateTime.local(2018, 12, 18, 20, 00); //=> 2018-12-18T20:00:00.000+03:00 dt.zone.name; //=> "Europe/Moscow" dt.setZone('Asia/Vladivostok'); //=> 2018-12-19T03:00:00.000+10:00 

Luxon también admite trabajar con fecha y hora en formato UTC:

 DateTime.utc(2018, 5, 15); //=> 2018-05-15T00:00:00.000Z DateTime.utc(); //=> 2018-12-18T17:58:29.995Z DateTime.local().toUTC(); //=> 2018-12-18T17:58:29.995Z DateTime.utc().toLocal(); //=> 2018-12-18T20:58:29.995+03:00 

Duración


La clase Duración proporciona la capacidad de trabajar con una duración de, por ejemplo, "2 horas y 7 minutos". Puede crear una duración como esta:

 var dur = Duration.fromObject({hours: 2, minutes: 7}); 

Las duraciones se pueden sumar y restar. La duración puede tener un valor negativo.

 dur.minus(dur).minus(dur); //=> {hours: -2, minutes: -7} 

Del mismo modo, la duración se puede agregar o restar de DateTime.

 DateTime.local().plus(dur); 

La duración tiene captadores (similar a los captadores DateTime):

 dur.hours; //=> 2 dur.minutes; //=> 7 dur.seconds; //=> 0 dur.zone; //=> undefined 

La duración también tiene otros métodos útiles:

 dur.as('seconds'); //=> 7620 dur.toObject(); //=> { hours: 2, minutes: 7 } dur.toISO(); //=> 'PT2H7M' 

Intervalos


Los intervalos se definen como el período entre dos puntos de tiempo; la clase Intervalo se utiliza para trabajar con ellos. El tiempo de inicio se incluye en el intervalo, pero el tiempo de finalización no: en consecuencia, el comienzo al convertir a una cadena se marca con un corchete y el final con un corchete.

 var today = DateTime.local(2018, 12, 18); var later = DateTime.local(2020, 10, 12); var interval = Interval.fromDateTimes(today, later); interval.toString(); //=> "[2018-12-18T00:00:00.000+03:00 – 2020-10-12T00:00:00.000+03:00)" interval.toISO(); //=> "2018-12-18T00:00:00.000+03:00/2020-10-12T00:00:00.000+03:00" interval.length(); //=> 57369600000 interval.length('years', true); //=> 1.8169398907103824 interval.contains(DateTime.local(2019)); //=> true 

Los intervalos se pueden comparar entre sí y combinarse entre sí:

 var nextYear = Interval.after(DateTime.local(), {year: 1}); var prevYear = Interval.before(DateTime.local(), {year: 1}); prevYear.overlaps(nextYear); //false prevYear.abutsStart(nextYear); //true nextYear.union(prevYear).length('years'); //=> 2 

Luxon y Momento


La biblioteca de Luxon "vive" en el proyecto "Momento", pero no es un reemplazo completo de la biblioteca Momento. Luxon no proporciona la funcionalidad completa de Moment, por ejemplo, el formato de fecha relativa se implementó recientemente en el navegador Chrome versión 71, aún no funciona en otros navegadores y el soporte para este aún no se implementó en Luxon (aunque se espera). Pero incluso si los navegadores admiten la funcionalidad requerida, debe comprender que solo estará disponible en estos nuevos entornos. En los navegadores más antiguos, Luxon funcionará con problemas, mientras que Moment funciona en cualquier momento y en cualquier lugar.

Además, la API de Luxon ha sido completamente rediseñada y es completamente diferente de la API de Moment.

Tenga en cuenta las principales diferencias entre Moment y Luxon.

Inmunidad


Los objetos de Luxon son inmutables, pero Moment no.
En el siguiente ejemplo, m1 y m2 son el mismo objeto modificado por el método add.

 var m1 = moment(); var m2 = m1.add(1, 'hours'); m1 === m2; //=> true 

En el caso de Luxon, el método plus devuelve un nuevo objeto d2 sin cambiar el d1 original.

 var d1 = DateTime.local(); var d2 = d1.plus({ hours: 1 }); d1 === d2; //=> false d1.valueOf() === d2.valueOf(); //=> false 

Por esta razón, Luxon no requiere constructores de copias especiales o métodos de clonación que Moment use para obtener copias sin cambiar el valor original.

Diferencias funcionales clave


  1. La cuenta regresiva de meses en Luxon comienza desde 1, y no desde cero, como en Momento (y de forma nativa en el objeto Date js).
  2. La localización y las zonas horarias se implementan utilizando la API Intl nativa (o polífilos), y no están integradas en la biblioteca.
  3. Luxon tiene tipos incorporados Duración e Intervalo.
  4. Luxon aún no admite el formato de fecha relativa.
  5. Luxon tampoco tiene un método humanizado para representar la duración en un estilo "humanizado" (por ejemplo, "unos segundos").

Diferencias de estilo API


  • En los métodos de la API de Luxon, los parámetros opcionales generalmente se ubican en último lugar.
  • Luxon tiene muchos métodos separados para crear objetos (por ejemplo, desde ISO), a diferencia de Moment, que tiene una función para esto, y el tipo de objeto se establece mediante parámetros.
  • Luxon tiene analizadores muy estrictos, mientras que Moment tiene otros más liberales, es decir. Si el formato de la cadena de entrada es diferente del estándar, Luxon inmediatamente dará un error, y Moment intentará corregir algunos errores en el formato.
  • Luxon usa getters (dt.year, dt.isValid) para obtener el valor de los campos internos, y no métodos como Moment (m.year (), m.isValid ()).
  • Luxon permite que un método establezca inmediatamente todos los parámetros necesarios dt.set ({año: 2016, mes: 4}), en Momento se configuran solo uno a la vez: una cadena de llamadas m.year (2016) .month (4).
  • La duración en Luxon es una clase separada de duración de nivel superior.

De lo contrario, Luxon tomó prestadas muchas ideas de Moment, la documentación incluso contiene tablas de equivalencia de los métodos Moment y Luxon.

Tamaños de archivo de biblioteca


Luxon (v. 1.8.2)
luxon.min.js - 61 KB

Momento (v. 2.23.0)
moment.min.js - 51 KB
moment.min.js + locale / ru.js - 59 KB
moment-with-locales.min.js - 323 KB

Como puede ver, sin configuraciones regionales Moment, el tamaño es 10 KB más pequeño que Luxon, pero con la adición de varias configuraciones regionales, el tamaño se vuelve aproximadamente igual.

Si se requiere soporte inmediato para todas las configuraciones regionales, entonces Luxon obtiene una ganancia significativa.

Resumen


La biblioteca está completamente lista para su uso y el autor promete su apoyo. La biblioteca ya tiene más de 7k estrellas en el github y su popularidad solo está creciendo. No solo el propio autor realiza los commits en su código, sino al menos 6 desarrolladores más.

Asumiré que la biblioteca Luxon es una respuesta a la aparición del soporte de API Intl en los navegadores. Los desarrolladores de Moment entienden que trabajar con fechas en la web puede cambiar significativamente y están tratando de prepararse para estos cambios. Pero no pueden predecir con precisión el desarrollo de la web, y con él el nuevo proyecto (que ellos mismos llaman el proyecto Moment labs). ¿Se trasladarán las ideas de Luxon a Moment 3? ¿La mayoría de los usuarios irán de Moment a Luxon en algún momento? ¿Tal vez Luxon pasará a llamarse Momento? Los propios desarrolladores admiten que ahora no pueden responder estas preguntas.

Source: https://habr.com/ru/post/es433850/


All Articles