Por que o argumento do mês varia de 0 a 11 no construtor Date do JavaScript?


128

Ao inicializar um novo Dateobjeto em JavaScript usando a chamada abaixo, descobri que o argumento do mês conta 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 (último) é um número de 1 a 31. Existem boas razões para isso?


96
É apenas para mantê-lo alerta.
SeanJA

4
Um que também é zero indexado é the Day of the week (integer)0-6 #
593 SeanJA

Porque foi codificado para máquinas e não para humanos. Mas ainda é uma enorme fonte de erros, porque um monte de código (ainda) é escrito por seres humanos :)
Christophe Roussy

4
@Christophe o mesmo argumento deve se aplicar também ao dia e ao ano.
precisa saber é o seguinte

2
@ChristopheRoussy sim, se foi codificado para máquinas, por que indexar dias a partir de 1 então?
user151496

Respostas:


55

É uma tradição antiga (provavelmente lamentável, provavelmente moribunda) no mundo da programação; veja a função C localtime do padrão antigo (POSIX) http://linux.die.net/man/3/localtime


14
O Dateobjeto JS foi portado do Java 1.0, é por isso. Herdando todas as suas falhas ... stackoverflow.com/questions/344380/…
c69

1
Você está certo, as tradições são geralmente totalmente inconsistentes e muitas vezes irracional e eu realmente espero que essas tradições "maus" são realmente morrendo ...
Henon

1
é 2019 e estou corrigindo um problema relacionado a esse comportamento, desde que estruturas como angulares e linguagens como javascript não depreciem isso ainda acontecerá - sinta-se à vontade para comentar no ano de 2025 em diante ;-)
Mauricio Gracia Gutierrez

Essa é uma tradição que sempre me faz gastar tempo em problemas de depuração com datas ... Pensando em quantas horas de trabalho desperdiçadas essa tradição causou.
Vedmant 03/07

102

A verdadeira resposta para essa pergunta é que ela foi copiada java.util.Date, que também tinha essa peculiaridade. A prova pode ser encontrada no Twitter em Brendan Eich - o cara que implementou o JavaScript originalmente (incluindo o Dateobjeto):

https://twitter.com/BrendanEich/status/481939099138654209

primeiro tweet

https://twitter.com/BrendanEich/status/771006397886533632

segundo tweet

Isso aconteceu em 1995 e o JDK 1.0 estava na versão beta. Foi lançado em 1996. Em 1997, foi lançado o JDK 1.1, que depreciava a grande maioria das funções java.util.Date, passando-as para java.util.Calendar, mas mesmo isso ainda tinha meses com base zero. Os desenvolvedores fartos disso criaram a biblioteca Joda-Time , que finalmente levou ao java.timepacote que foi incorporado ao Java 8 (2014).

Em resumo, demorou 18 anos para o Java obter uma API de data / hora projetada corretamente, mas o JavaScript ainda está preso na idade das trevas. De fato, temos excelentes bibliotecas como Moment.js , date-fns e js-joda . Mas, a partir de agora, não há nada além de Dateembutido no idioma. Espero que isso mude no futuro próximo.


24
Ah ... Boa e antiga metodologia de Desenvolvimento Orientado a Demonstrações.
Álvaro González

@ ÁlvaroGonzález Eu culparia o desenvolvedor original do JDK 1.0 que o introduziu em primeiro lugar.
#

30

Tudo, exceto o dia do mês, é 0, veja aqui uma lista completa, incluindo os intervalos :)

Na verdade, são os dias 1 que são os excêntricos aqui ... curiosamente. Por que isso foi feito? Eu não sei ... mas provavelmente aconteceu na mesma reunião em que eles foram colados e decidiram que o ponto e vírgula era opcional.


1
A coisa dos dias "baseados em um" é provavelmente porque ninguém em sã consciência jamais criaria uma matriz de nomes de strings por dias (por exemplo, { "first", "second", "third", ..., "twenty-seventh", ... }) e tentaria indexá-lo tm_mday. Por outro lado, talvez eles tenham visto a utilidade absoluta em fazer com que um erro ocorresse regularmente.
D.Shawley

Eles por que os anos não são baseados em zero?
Vedmant 03/07


4

É assim também em java. Provavelmente para converter int em string (0 - jan ,, 1-feb), eles codificaram desta maneira .. porque eles podem ter uma matriz de string (indexada de 0) de nomes de meses e este mês números se eles começarem a partir de 0, será muito mais fácil mapear para as sequências de meses.


3

Sei que não é realmente uma resposta para a pergunta original, mas só queria mostrar a minha solução preferida para esse problema, que eu nunca memorizo, pois aparece de vez em quando.

A pequena função zerofill faz o truque preenchendo os zeros quando necessário, e o mês é apenas +1adicionado:

function zerofill(i) {
    return (i < 10 ? '0' : '') + i;
}

function getDateString() {
    const date = new Date();
    const year = date.getFullYear();
    const month = zerofill(date.getMonth()+1);
    const day = zerofill(date.getDate());
    return year + '-' + month + '-' + day;
}

Mas sim, o Date tem uma API pouco intuitiva, eu estava rindo quando li o Twitter de Brendan Eich.


2

Eles podem ter considerado meses uma enumeração (o primeiro índice é 0) e dias desde que não têm um nome associado a eles.

Ou melhor, eles pensavam que o número do dia era a representação real do dia (da mesma forma que os meses são representados como números em uma data como 31/12), como se você pudesse fazer uma enumeração com números como variáveis, mas na verdade Baseado em 0.

Então, na verdade, durante os meses, talvez eles pensassem que a representação de enumeração adequada seria usar o nome do mês, em vez de números, e teriam feito o mesmo se os dias tivessem uma representação de nome. Imagine se disséssemos 5 de janeiro, 6 de janeiro, em vez de 5 de janeiro, 6 de janeiro, etc., então talvez eles tivessem feito uma enumeração baseada em 0 por dias também ...

Talvez subconscientemente pensassem em uma enumeração por meses como {janeiro, fevereiro, ...} e por dias como {um, dois, três, ...}, exceto nos dias em que você acessa o dia como um número, e não como o nome, como 1 para um, etc., é impossível iniciar em 0 ...


Você deve ter aula dupla para psicólogo. Ainda é um erro que eles cometeram, mas pelo menos agora entendemos por que eles cometeram.
Zesty

0

Pode ser uma falha, mas também é muito útil quando você deseja representar os meses ou o dia da semana como uma string, basta criar uma matriz como ['jan,' feb '... etc] [new Date () .getMonth ()] em vez de ['', 'jan', fev ... etc] [nova Data (). getMonth ()] ou ['jan', 'feb' ... etc] [nova Data ( ) .getMonth () - 1]

os dias do mês normalmente não são nomeados, portanto você não criará matrizes com nomes para eles. Nesse caso, 1-31 é mais fácil de manusear, portanto, você precisa subtrair 1 toda vez ...


Na verdade não. Você pode facilmente subtrair um. Isso cria mais problemas do que resolve, porque agora, quando você faz contas com datas, precisa manipular especificamente o mês com bastante frequência.
Rey
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.