2010-03-31 13 views
66

Podczas inicjowania nowego obiektu Date w języku JavaScript za pomocą poniższego wywołania, dowiedziałem się, że argument miesiąca liczy się od zera.Dlaczego argument miesiąca mieści się w przedziale od 0 do 11 w konstruktorze daty JavaScript?

new Date(2010, 3, 1); // that's the 1st April 2010! 

Dlaczego argument miesiąca zaczyna się od 0? Z drugiej strony, argument "dzień miesiąca" (ostatni) to liczba od 1 do 31. Czy istnieją ku temu uzasadnione powody?

+39

To tylko po to, aby trzymać cię na palcach. – SeanJA

+3

Jedną z nich, która jest również zindeksowana, jest "Dzień tygodnia (liczba całkowita)" 0-6 – SeanJA

+0

Ponieważ została zakodowana dla maszyn, a nie dla ludzi. Ale wciąż jest ogromnym źródłem błędów, ponieważ wiele kodu jest (nadal) napisane przez ludzi :) –

Odpowiedz

32

To stary (prawdopodobnie niefortunne, prawdopodobnie umiera) tradycja w świecie programowania zobaczyć starą normę (POSIX) localtime C funkcja http://linux.die.net/man/3/localtime

+9

Obiekt JS 'Date' został przeniesiony z Java 1.0, dlatego. Dziedziczenie wszystkich jej wad ... http://stackoverflow.com/questions/344380/why-is-january-month-0-in-java-calendar – c69

+0

Masz rację, tradycje są zwykle całkowicie niespójne i często nieracjonalne, a ja Naprawdę mam nadzieję, że takie "złe" tradycje naprawdę umierają ... – henon

3

Zawsze są 12 miesięcy w roku, więc implementacje C na wczesnym etapie mogły użyć statycznej tablicy o stałej szerokości z indeksami 0..11.

+2

Implementacja daty/kalendarza Java utrzymuje obsługę dodatkowego miesiąca dla niektórych kalendarzy. http://en.wikipedia.org/wiki/Undecimber – Pointy

23

Wszystko jednak dzień miesiąca jest 0 oparte see here for a full list including ranges :)

To rzeczywiście 1 dzień opartego na które są tutejsi oddballs ... tyle dziwnie. Dlaczego to się stało? Nie wiem ... ale prawdopodobnie zdarzyło się to samo spotkanie, które zostało otynkowane i uznałem, że średniki są opcjonalne.

+1

Dzieje "oparte na tych samych" są prawdopodobnie spowodowane tym, że nikt przy zdrowych zmysłach nigdy nie utworzy tablic nazw łańcuchów przez kilka dni (np. '{" pierwszy ", "second", "third", ..., "twenty-seventh", ...} ') i spróbuj zaindeksować go przez' tm_mday'. Z drugiej strony może po prostu widzieli absolutną użyteczność w popełnianiu _off przez one_ errors. –

2

To jak to w java zbyt .. Prawdopodobnie do konwersji int do string (0 - jan ,, 1-feb), kodowane w ten sposób .. ponieważ mogą mieć tablicę ciągów (indeksowanych od 0) nazw miesięcy i tych numerów miesięcy, jeśli zaczynają się od 0, to będzie dużo łatwiej jest mapować na ciągi miesiąca ..

0

To może być usterka, ale jest również bardzo przydatna, gdy chcesz reprezentować miesiące lub dzień tygodnia jako ciąg, możesz po prostu utworzyć tablicę, taką jak ['jan,' feb '... etc] [new Date(). getMonth()] zamiast [' ',' jan ', feb. ..etc] [new Date(). getMonth()] lub ['jan', 'feb' ... etc] [new Date(). getMonth() - 1]

dni miesiąca są normalne nie nazwie, więc nie będziesz tworzyć tablic z nazwami dla nich. W tym przypadku 1-31 jest łatwiejszy w obsłudze, więc chcesz odjąć 1 za każdym razem ...

+0

niezupełnie. Możesz łatwo odjąć jedną. Stwarza więcej problemów niż rozwiązuje, ponieważ teraz, kiedy robisz matematykę z datami, musisz często wykonywać określoną manipulację w danym miesiącu. – xckpd7

1

Mogły one być miesiącem do wyliczenia (pierwszy indeks to 0), a dni nie, ponieważ nie • mieć nazwę skojarzoną z nimi.

A raczej, uważali, że numer dnia był faktycznym przedstawieniem dnia (w ten sam sposób miesiące są reprezentowane jako liczby w dniu takim jak 12/31), tak jakby można było wyliczyć z liczbami jako zmienne, ale w rzeczywistości oparte na 0.

Rzeczywiście, przez te miesiące, być może uważali, że odpowiednia reprezentacja wyliczeniowa będzie używać nazwy miesiąca, zamiast liczb, i zrobiliby to samo, gdyby dni miały reprezentację imion. Wyobraźmy sobie, że powiemy, że piątego stycznia, szóstego stycznia, zamiast 5 stycznia, 6 stycznia itd., Być może oni też wykonaliby wyliczenia 0 przez wiele dni ...

Być może podświadomie myśleli o wyliczenie na miesiące jako {styczeń, luty, ...} oraz na dni jako {Jeden, Dwa, Trzy, ...}, z wyjątkiem dni, w których uzyskasz dostęp do dnia jako liczby, a nie nazwy, np. 1 dla jednego, itd., więc niemożliwe do rozpoczęcia 0 ...

43

Prawdziwa odpowiedź na to pytanie jest taka, że ​​została skopiowana z java.util.Date, która również miała to dziwactwo.Dowód można znaleźć na Twitterze od Brendan Eich - facet, który pierwotnie realizowane JavaScript (w tym obiekcie Date):

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

first tweet

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

second tweet

Stało się to w 1995, a JDK 1.0 był w wersji beta. Został uruchomiony w 1996 roku. W 1997 roku wyszedł JDK 1.1, który wycofał znaczną większość funkcji na java.util.Date, przenosząc je na java.util.Calendar, ale nawet to nadal miało miesiące zerowe. Deweloperzy dość tego stworzyli bibliotekę Joda-Time, która ostatecznie doprowadziła do pakietu java.time, który został wypalony na Java 8 (2014).

W skrócie, Java zajęła 18 lat, aby uzyskać poprawnie zaprojektowany interfejs API daty i godziny, ale JavaScript nadal tkwi w mrocznych czasach. Rzeczywiście mamy doskonałe biblioteki, takie jak Moment.js, date-fns i js-joda. Ale od tej pory nie ma nic więcej niż tylko wbudowany w język język angielski: Date. Mam nadzieję, że to się zmieni w najbliższej przyszłości.

+5

Ah ... Dobra stara metodologia rozwoju demo. –

1

Wiem, że to nie jest odpowiedź na oryginalne pytanie, ale chciałem pokazać wam moje preferowane rozwiązanie tego problemu, którego nigdy nie zapamiętam, ponieważ pojawia się od czasu do czasu.

Mała funkcja ZEROFILL załatwia sprawę Napełnianie zer w razie potrzeby, a miesiąc ma tylko +1 dodania:

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; 
} 

Ale tak, data ma dość nieintuicyjne API, śmiałam się, gdy czytam Brendan Eich Świergot.

Powiązane problemy