为什么在JavaScript的Date构造函数中month参数的范围是0到11?

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

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

为什么月份参数从0开始? 另一方面,月份的date参数(最后一个)是从1到31的数字。这是否有很好的理由?

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

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

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

第一个推特

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

第二个推文

这发生在1995年,JDK 1.0正在testing。 它于1996年推出。1997年,出现了JDK 1.1,它弃用了java.util.Date上绝大多数的函数,将它们移到了java.util.Calendar ,但即使这样,它仍然有零个月。 受此影响的开发人员创build了Joda-Time库,最终形成了Java 8(2014)的java.time包。

简而言之,Java需要18年时间才能获得内置的正确devise的date/时间API,但是JavaScript在黑暗时代依然停滞不前。 我们确实拥有像Moment.js , date -fns和js-joda等优秀的图书馆。 但是到目前为止,没有什么比Date内置的语言。 希望这将在不久的将来改变。

除了一个月的一天是0基于, 这里看到一个完整的列表,包括范围 🙂

实际上,这里是一个古怪的日子,奇怪的是。 为什么这样做呢? 我不知道,但可能发生在同一个会议上,他们得到了贴,决定分号是可选的。

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

它也是这样的java太.. 可能将int转换为string(0 – jan,1-feb),他们编码这种方式..因为他们可能有一个string数组(从0索引)月份名称和这个月数字,如果他们从0开始,这将是更容易映射到月份的string..

这可能是一个缺陷,但它也是非常方便的,当你想以一个string来表示星期几或星期几时,你可以像['jan,'feb'… etc] [new Date() .getMonth()]代替['','jan',feb … etc] [new Date()。getMonth()]或['jan','feb'… etc] [new Date ).getMonth() – 1]

这个月的日子通常不会被命名,所以你不会为这些名称创build数组。 在这种情况下1-31更容易处理,所以你想每次减去1 …

他们可能已经考虑过几个月是一个枚举(第一个索引是0),而不是几天,因为它们没有与它们相关联的名称。

或者说,他们认为当天的数字是当天的实际表示(与12/31这样的date中的月份表示方式相同),就好像您可以用数字作为variables进行枚举一样,但实际上0为主。

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

也许下意识地想到了一个月的{1月,2月,…}和几天的{1,2,3,…},除了你将天作为一个数字而不是名字来访问,像1等1,所以不可能从0开始…

我知道这不是真正的原始问题的答案,但我只是想告诉你我的首选解决scheme,这个问题,我似乎永远不会记得,因为它不时popup。

小函数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,当我阅读Brendan Eich的Twitter时,我笑了。