As datas do JavaScript finalmente serão corrigidas
(docs.timetime.in)- Entre as mudanças recentes do ECMAScript, a mais notável é a proposta Temporal
- Essa API já pode ser usada por meio do polyfill fornecido pela equipe do FullCalendar
- Uma das principais vantagens dessa API é que finalmente passamos a ter um objeto nativo para representar "Zoned Date Time"
O que é Zoned Date Time?
- Ao lidar com datas humanas, normalmente omitimos o fuso horário e falamos apenas da data e da hora
- Porém, o objeto
Datedo JavaScript lida apenas com números, então o significado original da data se perde - Por exemplo, ao registrar o momento de um pagamento com cartão, muita gente pode usar um código como este
const paymentDate = new Date('2024-07-20T10:30:00'); - Nesse caso, o navegador calcula os milissegundos com base no fuso horário do usuário (CET). Mas a informação armazenada pode ser interpretada de forma diferente dependendo do fuso
- Além do fato muito importante de que, em JavaScript, datas não usam UTC e sim POSIX, onde segundos bissextos são completamente ignorados, há também o problema de que, quando só restam números, o significado original da data desaparece
- Muita gente acha que trabalhar em UTC ou transmitir datas em formato ISO é suficiente, mas isso não está correto, porque ainda pode haver perda de informação
UTC não é suficiente
- Mesmo trabalhando com o formato ISO, ainda falta a informação de fuso horário na hora de exibir a data
- A função que converte um timestamp em uma data legível por humanos não é injective (injetiva)
- Por exemplo, se você viajar de Madri para Sydney e depois voltar, pode acabar confuso com questões de fuso horário no extrato bancário
Introdução à API Temporal
- A API Temporal introduz o objeto
Temporal.ZonedDateTime, que representa data e hora junto com o fuso horário - Ela propõe uma extensão do RFC 3339, apresentando um padrão para serializar e desserializar datas em formato de string
1996-12-19T16:39:57-08:00[America/Los_Angeles]- Essa string representa 19 de dezembro de 1996 às 16:39:57
- O offset é de -08:00 em relação ao UTC (o Horário Padrão do Pacífico, PST, ao qual Los Angeles pertence)
- E ainda especifica o fuso horário correspondente ("Horário Padrão do Pacífico") para que aplicações com reconhecimento de fuso horário possam levá-lo em conta
- Suporta vários sistemas de calendário (por exemplo: budista, chinês, Dangi, gregoriano, islâmico, persa, japonês etc.)
Operações básicas
Criação de datas
- A API Temporal fornece ferramentas poderosas para lidar com fusos horários
- Por exemplo, ao criar um objeto
Temporal.ZonedDateTime, ela garante que o fuso horário seja refletido corretamente:const zonedDateTime = Temporal.ZonedDateTime.from({ year: 2024, month: 8, day: 16, hour: 12, minute: 30, second: 0, timeZone: 'Europe/Madrid'}); - Isso permite manter a hora correta mesmo com mudanças de fuso horário ou ajustes locais de horário, como DST
Comparação de datas
- Objetos
ZonedDateTimeoferecem o métodocompare, que permite comparar doisZonedDateTime:const one = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]'); const two = Temporal.ZonedDateTime.from('2020-11-01T01:15-08:00[America/Los_Angeles]'); Temporal.ZonedDateTime.compare(one, two); // => -1
Recursos embutidos úteis
- A propriedade
hoursInDayretorna o número real de horas daquele dia:Temporal.ZonedDateTime.from('2020-03-08T12:00-07:00[America/Los_Angeles]').hoursInDay; // => 23 (dia de início do DST)
Conversão de fuso horário
- Você pode alterar o fuso horário de um
ZonedDateTimeusando o métodowithTimeZone:zdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30+09:00[Asia/Tokyo]'); zdt.withTimeZone('Africa/Accra').toString(); // => '1995-12-06T18:24:30+00:00[Africa/Accra]'
Operações aritméticas básicas
- Você pode usar o método
.addpara somar ou subtrair datas de acordo com as regras de DST:zdt = Temporal.ZonedDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]'); laterDay = zdt.add({ days: 1 }); // => 2020-03-09T00:00:00-07:00[America/Los_Angeles]
Cálculo da diferença entre datas
- O método
.untilcalcula a diferença entre dois horários e a retorna como um objetoTemporal.Duration- Por exemplo, ele pode ser usado como
zdt.until(other)
- Por exemplo, ele pode ser usado como
Conclusão
- A API Temporal transforma de forma profunda a maneira como o JavaScript lida com tempo
- Este artigo abordou a diferença entre datas legíveis por humanos e datas em UTC, além de como representá-las com precisão usando o objeto
Temporal.ZonedDateTime - No próximo artigo, serão explorados outros objetos interessantes, como Instant, PlainDate e Duration
Opinião do GN⁺
- O problema de lidar com datas e horários, que há muito tempo dificulta a vida de desenvolvedores JavaScript, deve ser resolvido com a API Temporal
- Como ela consegue tratar automaticamente questões de fuso horário e DST, é muito útil no desenvolvimento de aplicações globais
- Compatibilidade com o objeto
Dateexistente e questões de migração ainda são pontos a considerar - A API
Temporalfoi projetada de forma clara e intuitiva e também se destaca no suporte à internacionalização, inclusive com suporte a vários sistemas de calendário - Espera-se que essa mudança aumente bastante a produtividade de desenvolvedores JavaScript
5 comentários
Finalmente!
Só para constar, o Deno já incorpora a API Temporal.
Nossa, ao projetar serviços globais gigantes eu sempre sofria com datas
Quero muito testar isso uma vez
Sério, finalmente não vai mais precisar usar moment ou dayjs?
Opiniões no Hacker News
Lidar com data e hora em Javascript é muito difícil
Datedo JS e Moment são difíceis de usarHá expectativa de que a nova API resolva os problemas de fuso horário no JS
Uma função que converte um timestamp em uma data legível por humanos não é injetiva
Piada sobre a curva de dificuldade no tratamento de tempo
Se o artigo usasse mais exemplos de datas futuras, seria mais convincente
Usuário se sente inseguro por não entender o tratamento de tempo
Ter um bom padrão de datetime já é metade da batalha
Strings de data ISO devem capturar a informação correta
Dateresolvem problemas simples de forma complicadaPergunta sobre como lidar com esse problema no Postgres
Faltam evidências de que Temporal realmente será adotado