为什么 JavaScript 的 Date 构造函数中的月份参数范围从 0 到 11?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2552483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:52:00  来源:igfitidea点击:

Why does the month argument range from 0 to 11 in JavaScript's Date constructor?

javascriptdatetimedate

提问by Agnel Kurian

When initializing a new Dateobject in JavaScript using the below call, I found out that the month argument counts starting from zero.

Date使用下面的调用在 JavaScript 中初始化一个新对象时,我发现月份参数从零开始计数。

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

Why does the month argument start from 0? On the other hand, the day of the month argument (last one) is a number from 1 to 31. Are there good reasons for this?

为什么月份参数从 0 开始?另一方面,月份参数(最后一个)是从 1 到 31 的数字。这样做有充分的理由吗?

采纳答案by leonbloy

It's an old (probably unfortunate, probably dying) tradition in the programming world, see the old standard (POSIX) localtimeC function http://linux.die.net/man/3/localtime

这是编程世界中一个古老的(可能是不幸的,可能正在消亡)传统,请参阅旧标准(POSIX)localtimeC 函数http://linux.die.net/man/3/localtime

回答by Matt Johnson-Pint

The real answer to this question, is that it was copied from java.util.Date, which also had this quirk. Proof can be found on Twitter from Brendan Eich - the guy who originally implemented JavaScript (including the Dateobject):

这个问题的真正答案是它是从 复制的java.util.Date,它也有这个怪癖。可以在 Twitter 上找到 Brendan Eich 的证明,他是最初实现 JavaScript(包括Date对象)的人:

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

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

first tweet

第一条推文

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

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

second tweet

第二条推文

This happened in 1995, and JDK 1.0 was in beta. It launched in 1996. In 1997, JDK 1.1 came out which deprecated the vast majority of functions on java.util.Date, moving them over to java.util.Calendar, but even that still had zero-based months. Developers fed-up with this created the Joda-Timelibrary, which ultimately led to java.timepackage that's baked in to Java 8 (2014).

这发生在 1995 年,当时 JDK 1.0 处于测试阶段。它于 1996 年推出。 1997 年,JDK 1.1 出现,弃用了 上的绝大多数功能java.util.Date,将它们移至java.util.Calendar,但即便如此,仍然有从零开始的月份。对此感到厌烦的开发人员创建了Joda-Time库,最终导致java.time包被嵌入到 Java 8 (2014) 中。

In short, it took 18 years for Java to get a correctly designed date/time API built-in, but JavaScript is still stuck back in the dark ages. We do indeed have excellent libraries like Moment.js, date-fns, and js-joda. But as of now, there is nothing more than Datebuilt-in to the language. Hopefully this will change in the near future.

简而言之,Java 花了 18 年的时间才获得正确设计的内置日期/时间 API,但 JavaScript 仍然停留在黑暗时代。我们确实有像Moment.jsdate -fnsjs-joda这样的优秀库。但截至目前,除了Date内置于该语言之外,别无他物。希望这会在不久的将来改变。

回答by Nick Craver

Everything but the day of the month is 0 based, see here for a full list including ranges:)

除了一个月中的某一天之外的所有内容都是基于 0 的,请参阅此处以获取包括范围的完整列表:)

It's actually the 1 based days that are the oddballs here...oddly enough. Why was this was done? I don't know...but probably happened the same meeting they got plastered and decided semicolons were optional.

它实际上是基于 1 天的天数是这里的怪胎......奇怪了。为什么这样做?我不知道......但可能发生在他们被贴上石膏并决定分号是可选的同一次会议上。

回答by Jonathan Julian

There are always 12 months in a year, so early C implementations might have used a static fixed-width array with indexes 0..11.

一年总有 12 个月,因此早期的 C 实现可能使用索引为 0..11 的静态固定宽度数组。

回答by raj

Its like this in java too.. Probablyto convert int to string (0 - jan,, 1-feb), they coded this way.. because they might have an array of string (indexed from 0) of month names and these month numbers if they start from 0, it'll be lot easier to map to the month strings..

它在java中也是这样..可能将int转换为字符串(0 - jan,, 1-feb),他们以这种方式编码..因为他们可能有一个字符串数组(从0开始索引)的月份名称和这些月份如果数字从 0 开始,则映射到月份字符串会容易得多。

回答by Christof K?lin

I know it's not really an answer to the original question, but I just wanted to show you my preferred solution to this problem, which I never seem to memorize as it pops up from time to time.

我知道这并不是对原始问题的真正答案,但我只是想向您展示我对这个问题的首选解决方案,我似乎从未记住它,因为它不时出现。

The small function zerofill does the trick filling the zeroes where needed, and the month is just +1added:

小函数 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;
}

But yes, Date has a pretty unintuitive API, I was laughing when I read Brendan Eich's Twitter.

但是是的,Date 有一个非常不直观的 API,当我阅读 Brendan Eich 的 Twitter 时我笑了。

回答by Pat-Laugh

They might've considered months to be an enumeration (first index being 0) and days not since they don't have a name associated with them.

他们可能认为月份是枚举(第一个索引为 0)而天不是,因为它们没有与之关联的名称。

Or rather, they thought the number of the day was the actual representation of the day (the same way months are represented as numbers in a date like 12/31), as if you could make a enumeration with numbers as the variables, but actually 0-based.

或者更确切地说,他们认为天数是当天的实际表示(就像在 12/31 之类的日期中将月份表示为数字一样),好像您可以使用数字作为变量进行枚举,但实际上0 为基础。

So actually, for the months, perhaps they thought the proper enumeration representation would be to use the month's name, instead of numbers, and they would've done the same if days had a name representation. Imagine if we'd say January Five, January Sixth, instead of January 5, January 6, etc., then perhaps they'd have made a 0-based enumeration for days too...

所以实际上,对于几个月,也许他们认为正确的枚举表示是使用月份的名称,而不是数字,如果天有名称表示,他们也会这样做。想象一下,如果我们说 1 月 5 日、1 月 6 日,而不是 1 月 5 日、1 月 6 日等,那么也许他们也会对几天进行基于 0 的枚举......

Perhaps subconsciously they thought about an enumeration for months as {January, February, ...} and for days as {One, Two, Three, ...}, except for days you access the day as a number rather than the name, like 1 for One, etc., so impossible to start at 0...

也许在潜意识中,他们认为月份的枚举为 {January, February, ...},而几天为 {One, Two, Three, ...},除了您以数字而不是名称访问日期的天数,像 1 代表 1 等等,所以不可能从 0 开始......

回答by Rogier

It might be a flaw, but it's also very handy when you want to represent the months or day of the week as a string you can just create an array like ['jan,'feb' ...etc][new Date().getMonth()] in stead of ['','jan',feb ...etc][new Date().getMonth()] or ['jan','feb' ...etc][new Date().getMonth()-1]

这可能是一个缺陷,但是当您想将月份或星期几表示为字符串时,它也非常方便,您只需创建一个数组,例如 ['jan,'feb' ...etc][new Date() .getMonth()] 而不是 ['','jan',feb ...etc][new Date().getMonth()] 或 ['jan','feb' ...etc][new Date( ).getMonth()-1]

days of the month are normaly not named so you won't be making arrays with names for those. In this case 1-31 is easier to handle, so you want have to subtract 1 every time...

一个月中的几天通常没有命名,因此您不会为这些天制作带有名称的数组。在这种情况下 1-31 更容易处理,因此您希望每次都减去 1...