datetime - Por que o argumento month varia de 0 a 11 no construtor Date do JavaScript?
Ao inicializar um novo objeto Date em JavaScript usando a chamada abaixo, descobri que o argumento do mês é contado a partir do zero.
new Date(2010, 3, 1); // that's the 1st April 2010!
Por que o argumento do mês começa em 0? Por outro lado, o argumento do dia do mês (o último) é um número de 1 a 31. Existem boas razões para isso?
Resposta #1
A resposta real para esta pergunta é que ela foi copiada de java.util.Date, que também tinha essa peculiaridade. A prova pode ser encontrada no Twitter de Brendan Eich - o cara que originalmente implementou o JavaScript:
https://twitter.com/BrendanEich/status/481939099138654209
https://twitter.com/BrendanEich/status/771006397886533632
Brendan também indica que foi Ken Smith da Netscape quem fez a portabilidade do Java.
https://twitter.com/BrendanEich/status/771006208949891072
Isso aconteceu em 1995, e o JDK 1.0 estava em versão beta. Ele foi lançado em 1996. Em 1997, o JDK 1.1 foi lançado, que depreciou a grande maioria das funções em java.util.Date, movendo-as para java.util.Calendar, mas mesmo assim ainda tinha meses baseados em zero. Desenvolvedores cansados disso criaram a biblioteca Joda-Time, que eventualmente levou ao pacote java.time, que vem incorporado no Java 8 (2014).
Em resumo, levaram 18 anos para o Java ter uma API de data/hora corretamente projetada incorporada, mas o JavaScript ainda está preso na Idade das Trevas. De fato, temos bibliotecas excelentes como Luxon, Moment.js, date-fns, js-joda e outras. Mas, até agora, não há nada mais do que Date incorporado na linguagem. Esperançosamente, isso mudará em um futuro próximo com a proposta Temporal do TC39.
Resposta #2
É uma tradição antiga (provavelmente infeliz, provavelmente moribunda) no mundo da programação, veja a antiga função padrão (POSIX) localtime em C http://linux.die.net/man/3/localtime
Resposta #3
Tudo, exceto o dia do mês, é baseado em 0, veja aqui uma lista completa incluindo intervalos :)
Na verdade, são os dias baseados em 1 que são os estranhos aqui... curiosamente. Por que isso foi feito? Não sei... mas provavelmente aconteceu na mesma reunião em que eles ficaram bêbados e decidiram que os ponto e vírgulas eram opcionais.
Resposta #4
Em 2024, a verdadeira pergunta é:
Se
Dateestava quebrado desde o primeiro dia do JS, por que depois de 29 anos (28 se contar a partir do zero) ele ainda está aqui?
JS tem muitas partes/peculiaridades ruins e a pior coisa é que algumas delas não foram corrigidas em décadas (curiosidade: estamos falando sobre Date datas).
Mas temos sorte, parece que o fim de Date está próximo.
Spoiler
new Temporal.PlainDate(2020, 11, 26); // => 2020-11-26
Temporal (proposta)
Da introdução da proposta:
Datetem sido um ponto problemático de longa data no ECMAScript. Esta é uma proposta paraTemporal, umObjectglobal que atua como um namespace de nível superior (comoMath), que traz uma API moderna de data/hora para a linguagem ECMAScript.
É baseado, conforme relatado nos documentos, "em casos de uso comuns que examinamos" e possui múltiplos tipos para diferentes tipos de dados:
- Tipos
Plainnão têm fuso horário - Tipos
ZonedDateTimepossuem um fuso horário - a maioria dos tipos tem um calendário
- muitos tipos úteis:
Absolute,DateTime,Date,Time,TimeZone, ...
Este é um esquema que descreve vários tipos Temporal e suas relações
Você pode ler mais sobre eles na documentação disponível e no bom livro de receitas. Ou explorar os problemas atuais para os que estão abertos.
Quando o Temporal estará disponível
Desde março de '21, está no Estágio 3/Rascunho (veja a referência de estágios do TC39). Veja os slides do TC39 de março de '21.
Agora isso pode ser incluído no TypeScript em breve, já que a política deles é:
Quando novos recursos atingem o estágio 3, então eles estão prontos para inclusão no TypeScript.
Provavelmente para Node e os principais navegadores teremos que esperar mais.
Comece a experimentar hoje
Enquanto isso, você pode experimentá-lo usando o polyfill do Temporal.
npm install --save proposal-temporal
// temporal-test.js
const { Temporal } = require('proposal-temporal');
// or as an ES module
// import { Temporal } from 'proposal-temporal/lib/index.mjs';
// 11 means November now!
const date = new Temporal.PlainDate(2020, 11, 26); // => 2020-11-26
const sameDate = Temporal.PlainDate.from(
{year: 2020, month: 11, day: 26}); // => 2020-11-26



