Luxon - uma nova biblioteca para trabalhar com datas da equipe Moment.js



Parece, por que precisamos de outra biblioteca para trabalhar com datas e horários em que existe uma biblioteca Moment conhecida ?! O mais interessante é que a alternativa foi proposta pela própria equipe do Moment.

A biblioteca Luxon é declarada como uma ferramenta poderosa, moderna e conveniente para trabalhar com datas e horas em JavaScript. A biblioteca foi criada por Isaac Cambron, membro da equipe de desenvolvimento do Moment desde 2013.

O autor tinha muitas idéias para o desenvolvimento do Moment, que ele não pôde criar dentro da estrutura do código existente. Aqui estão os principais pontos que eu queria implementar:

  • experimente algumas idéias sobre como tornar a API mais lógica (mas essas idéias não são compatíveis com a abordagem adotada pelo Moment),
  • implementar o trabalho "pronto para uso" com fusos horários sem extensões adicionais,
  • repensar completamente o trabalho com a internacionalização, levando em consideração o advento da API Intl,
  • mude para um conjunto moderno de ferramentas e abordagens na formação do código JS.

Portanto, ele decidiu escrever tudo do zero, o que levou cerca de dois anos.
O resultado é uma espécie de versão modernizada do Moment.
A versão resultante parecia interessante para toda a equipe de desenvolvimento do Moment, por isso foi decidido promover a nova biblioteca sob os auspícios da equipe.

Princípios de Luxon


  1. Cadeias de chamadas como no momento.
  2. Todos os tipos são imutáveis.
  3. API mais clara e óbvia: para objetos diferentes - métodos diferentes com parâmetros claramente definidos.
  4. API internacional para internacionalização (reversão para a versão em inglês se o navegador não suportar a API internacional).
  5. API internacional para trabalhar com fusos horários.
  6. Suporte mais completo para calcular a duração.
  7. Suporte de intervalo nativo.
  8. Documentação de código embutido.

Esses princípios levaram às seguintes melhorias:

  • O código Luxon é muito mais fácil de entender e depurar.
  • O uso dos recursos internos do navegador para internacionalização melhora o comportamento da biblioteca e, novamente, facilita a depuração.
  • O suporte ao fuso horário é melhor implementado do que em qualquer outra biblioteca JS.
  • O Luxon fornece uma ferramenta simples e muito poderosa para trabalhar com duração.
  • A biblioteca possui boa documentação.

Mas Luxon tem suas desvantagens:

  • A ênfase no uso dos recursos internos do navegador leva a dificuldades no suporte a navegadores antigos.
  • Alguns recursos de internacionalização que ainda não são suportados por navegadores não são implementados na biblioteca (você deve esperar que esse suporte apareça nos navegadores).
  • A implementação da API Intl em diferentes navegadores pode variar, respectivamente, o comportamento do Luxon também varia.

Instalação


Luxon fornece módulos para todas as plataformas JavaScript modernas.

A documentação possui uma lista completa de navegadores suportados com restrições de aplicativo. Para navegadores que não possuem ou têm suporte internacional limitado, é recomendável usar um polyfile (em particular, isso se aplica ao IE 10 ou 11).

Ao trabalhar com Node.js (6+), se você precisar trabalhar com localidades, precisará instalar adicionalmente o pacote full-icu e definir a variável de ambiente para permitir o uso deste pacote.

O método de instalação padrão do npm:
npm install --save luxon

Luxon tem suporte para TypeScript e Flow, também há um módulo no formato ES6.

Revisão rápida


A biblioteca Luxon consiste em cinco classes principais:

DateTime - data e hora com fuso horário e configurações de exibição, bem como métodos relacionados.
Duração - um período de tempo (duração), por exemplo, "2 meses" ou "1 dia, 3 horas".
Métodos informativos para obter dados gerais sobre hora e data.
Intervalo - intervalo de tempo e métodos para trabalhar com ele.
As configurações são métodos estáticos que definem o comportamento geral do Luxon.

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

Sua primeira data e hora


A classe mais importante em Luxon é o DateTime. DateTime representa data + hora, juntamente com fuso horário e localidade. É assim que você pode definir 15 de maio de 2017 às 08:30 no fuso horário local:

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

Aqui está a chamada para determinar a hora atual:

 var now = DateTime.local(); 

Criar do Objeto


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

Criar a partir de uma string no 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 

Ao converter para uma sequência, o Luxon também retorna uma sequência no formato ISO 8601:

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

Obtenção de componentes individuais:


 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 

Saída formatada


O Luxon tem muitos métodos para converter DateTime em uma string, dois deles são mais importantes para LocalString e toISO, o primeiro converte para um formato levando em consideração o verniz do navegador e o segundo prepara o texto para processamento programático (por exemplo, para transferir para um 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" 

O Luxon possui duas dúzias de "predefinições" prontas para saída formatada (como DATETIME_MED e TIME_WITH_LONG_OFFSET).

Você também pode criar sua própria opção de formatação com base em tokens:

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

Conversões DateTime


Nota importante: os objetos Luxon são imutáveis, ou seja, quaisquer métodos de modificação aplicados a eles retornarão a cópia modificada sem alterar o objeto original. Portanto, todos os termos deste artigo (como na documentação do Luxon) como "alterar", "instalar", "redefinir" devem ser entendidos como "criar uma nova instância com outras propriedades".

Transformações matemáticas


 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" 

Substituindo Parâmetros Individuais


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

Conversões internacionais


O Luxon suporta várias transformações Intl diferentes, uma das mais importantes é a formatação para diferentes localidades:

 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" 

A classe Info pode retornar listas de meses e dias da semana em um determinado local:

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

Fusos horários


Luxon suporta fusos horários. Se você criar um DateTime sem especificar explicitamente um fuso horário, o fuso local será selecionado por padrão. Se você alterar o fuso horário para um DateTime existente, a hora e a data serão recalculadas levando em consideração a diferença entre os fusos horários.

 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 também suporta trabalhar com data e hora no 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 

Duração


A classe Duration oferece a capacidade de trabalhar com uma duração de, por exemplo, "2 horas e 7 minutos". Você pode criar uma duração como esta:

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

Durações podem ser adicionadas e subtraídas. A duração pode ter um valor negativo.

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

Da mesma forma, a duração pode ser adicionada ou subtraída do DateTime.

 DateTime.local().plus(dur); 

A duração possui getters (semelhante aos get DateTime):

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

A duração também possui outros métodos úteis:

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

Intervalos


Intervalos são definidos como o período entre dois pontos no tempo; a classe Interval é usada para trabalhar com eles. O horário de início está incluído no intervalo, mas o horário de término não é: consequentemente, o início da conversão para uma sequência de caracteres é marcado com um colchete e o final com um colchete.

 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 

Os intervalos podem ser comparados entre si e combinados entre si:

 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 and Moment


A biblioteca Luxon "vive" no projeto "Moment", mas não é um substituto completo para a biblioteca Moment. O Luxon não fornece a funcionalidade completa do Moment, por exemplo, a formatação de data relativa foi implementada apenas recentemente na versão 71 do navegador Chrome, ainda não funciona em outros navegadores e o suporte ainda não foi implementado no Luxon (embora seja esperado). Mas mesmo que os navegadores suportem a funcionalidade necessária, você deve entender que ele estará disponível apenas nesses novos ambientes. Nos navegadores mais antigos, o Luxon trabalha com problemas, enquanto o Moment funciona a qualquer hora, em qualquer lugar.

Além disso, a API do Luxon foi completamente redesenhada e é completamente diferente da API do momento.

Observe as principais diferenças entre Moment e Luxon.

Imunidade


Objetos Luxon são imutáveis, mas Moment não.
No exemplo abaixo, m1 e m2 são o mesmo objeto que foi modificado pelo método add.

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

No caso de Luxon, o método plus retorna um novo objeto d2 sem alterar o d1 original.

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

Por esse motivo, o Luxon não requer construtores de cópia ou métodos de clonagem especiais que o Moment usa para obter cópias sem alterar o valor original.

Principais diferenças funcionais


  1. A contagem regressiva dos meses em Luxon começa em 1, e não do zero, como em Moment (e nativamente no objeto Date js).
  2. A localização e os fusos horários são implementados usando a API Intl nativa (ou polyphile) e não são incorporados à biblioteca.
  3. Luxon possui tipos internos Duration e Interval.
  4. O Luxon ainda não suporta a formatação de data relativa.
  5. Luxon também não possui um método humanizado para representar a duração em um estilo "humanizado" (por exemplo, "alguns segundos").

Diferenças de estilo da API


  • Nos métodos da API Luxon, os parâmetros opcionais geralmente estão localizados por último.
  • O Luxon possui muitos métodos separados para criar objetos (por exemplo, do ISO), diferentemente do Moment, que possui uma função para isso, e o tipo do objeto é definido por parâmetros.
  • Luxon tem analisadores muito rigorosos, enquanto Moment tem mais liberais, ou seja, se o formato da sequência de entrada for diferente do padrão, o Luxon imediatamente emitirá um erro e o Moment tentará corrigir alguns erros no formato.
  • O Luxon usa getters (dt.year, dt.isValid) para obter o valor dos campos internos, e não métodos como Moment (m.year (), m.isValid ()).
  • O Luxon permite que um método defina imediatamente todos os parâmetros necessários dt.set ({ano: 2016, mês: 4}); no momento, eles são definidos apenas um de cada vez - uma cadeia de chamadas m.ano (2016) .mês (4).
  • A duração em Luxon é uma classe de duração de nível superior separada.

Caso contrário, Luxon emprestou muitas idéias do Moment, a documentação ainda contém tabelas de equivalência dos métodos Moment e Luxon.

Tamanhos de arquivo da 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 você pode ver, sem as localidades do Moment, o tamanho é 10 KB menor que o Luxon, mas com a adição de várias localidades, o tamanho se torna aproximadamente igual.

Se o suporte for necessário imediatamente para todas as localidades, haverá um ganho significativo da Luxon.

Sumário


A biblioteca está completamente pronta para uso e o autor promete seu apoio. A biblioteca já tem mais de 7k estrelas no github e sua popularidade está crescendo apenas. Não apenas o próprio autor faz as confirmações em seu código, mas pelo menos mais 6 desenvolvedores.

Assumirei que a biblioteca Luxon é uma resposta à aparência do suporte à API Intl nos navegadores. No momento, os desenvolvedores entendem que trabalhar com datas na Web pode mudar significativamente e está tentando se preparar para essas alterações. Mas eles não podem prever com precisão o desenvolvimento da Web e, com ela, o novo projeto (que eles mesmos chamam de projeto Moment labs). As idéias de Luxon serão portadas para o Momento 3? A maioria dos usuários passará de Moment para Luxon em algum momento? Talvez Luxon seja renomeado como Momento? Os próprios desenvolvedores admitem que agora não podem responder a essas perguntas.

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


All Articles