Почему аргумент месяца находится в диапазоне от 0 до 11 в конструкторе JavaScript в JavaScript? - PullRequest
93 голосов
/ 31 марта 2010

При инициализации нового объекта Date в JavaScript с помощью вызова ниже, я обнаружил, что аргумент month начинается с нуля.

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

Почему аргумент month начинается с 0? С другой стороны, аргумент «день месяца» (последний) - это число от 1 до 31. Есть ли для этого веские причины?

Ответы [ 8 ]

75 голосов
/ 02 февраля 2017

Реальный ответ на этот вопрос заключается в том, что он был скопирован с java.util.Date, который также имел эту причуду. Доказательство можно найти в Twitter от Брендана Эйха - парня, который изначально реализовал JavaScript (включая объект Date):

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

first tweet

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

second tweet

Это произошло в 1995 году, и JDK 1.0 была в бета-версии. Он был запущен в 1996 году. В 1997 году вышла JDK 1.1, которая устарела в подавляющем большинстве функций на java.util.Date, перенеся их на java.util.Calendar, но даже у этого месяца все еще были нулевые месяцы. Разработчики, которым это надоело, создали библиотеку Joda-Time , что в итоге привело к созданию пакета java.time, встроенного в Java 8 (2014).

Короче говоря, Java потребовалось 18 лет, чтобы получить правильно спроектированный встроенный API даты и времени, но JavaScript все еще застрял в темноте. У нас действительно есть отличные библиотеки, такие как Moment.js , date-fns и js-joda . Но на данный момент, нет ничего более, чем Date встроенный в язык. Надеюсь, это изменится в ближайшем будущем.

45 голосов
/ 31 марта 2010

Это старая (вероятно, неудачная, возможно, умирающая) традиция в мире программирования, см. Старый стандарт (POSIX) местное время функция C http://linux.die.net/man/3/localtime

28 голосов
/ 31 марта 2010

Все, кроме дня месяца, основано на 0, смотрите здесь полный список, включающий диапазоны :)

Это на самом деле дни, основанные на 1, это странные шары ... как ни странно. Почему это было сделано? Я не знаю ... но, вероятно, произошло то же самое собрание, которое они обмазали и решили, что точки с запятой необязательны.

4 голосов
/ 31 марта 2010

В году всегда 12 месяцев, поэтому в ранних реализациях C мог использоваться статический массив фиксированной ширины с индексами 0..11.

3 голосов
/ 13 марта 2017

Я знаю, что это не совсем ответ на первоначальный вопрос, но я просто хотел показать вам мое предпочтительное решение этой проблемы, которое я никогда не запоминаю, когда оно всплывает время от времени.

Небольшая функция zerofill выполняет трюк, заполняя нули там, где это необходимо, и месяц просто добавляется +1:

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

Но да, у Date довольно неинтуитивный API, я смеялся, когда читал твиттер Брендана Эйха.

3 голосов
/ 31 марта 2010

Так же и в java .. Возможно для преобразования int в строку (0 - jan ,, 1-feb), они закодированы таким образом ... потому что они могут иметь массив строк (проиндексированный от 0) названий месяцев и номеров этих месяцев, если они начинаются с 0, будет намного проще отобразить строки месяца.

1 голос
/ 26 августа 2016

Возможно, они считали месяцы перечислением (первый индекс равен 0), а дни - нет, поскольку с ними не связано имя.

Или, скорее, они думали, что число дня было фактическим представлением дня (так же, как месяцы представлены в виде чисел в дате, такой как 12/31), как если бы вы могли сделать перечисление с числами в качестве переменных , но на самом деле на основе 0.

Так что на самом деле в течение месяцев, возможно, они думали, что правильное представление перечисления будет использовать имя месяца вместо цифр, и они сделали бы то же самое, если бы дни имели представление имени. Представьте, что если бы мы сказали «5 января», «6 января» вместо 5 января, 6 января и т. Д., То, возможно, они сделали бы перечисление на основе 0 и в течение нескольких дней ...

Возможно, подсознательно они думали о перечислении месяцев {январь, февраль, ...} и дней {Один, Два, Три, ...}, за исключением дней, когда вы обращаетесь к дню в виде числа, а не имя, как 1 для одного и т. д., поэтому невозможно начать с 0 ...

0 голосов
/ 31 июля 2015

Это может быть недостатком, но это также очень удобно, когда вы хотите представить месяцы или день недели в виде строки, вы можете просто создать массив как ['jan,' feb '... etc] [new Date (). GetMonth ()] вместо ['', 'jan', feb ... etc] [new Date (). GetMonth ()] или ['jan', 'feb' ... etc] [ новая дата (). getMonth () - 1]

Дни месяца обычно не называются, поэтому вы не будете создавать массивы с именами для них. В этом случае с 1-31 легче работать, поэтому вам нужно каждый раз вычитать 1 ...

...