Javascriptdate01/01/0001

我想在javascript中创build一个Date对象,它代表了0001,2014年前的年份。

我试过了

d = new Date(); d.setYear(1); console.log(d); 

但它给出了1901年

 d = new Date(1,1,1) console.log(d); 

没门。

我怎样才能创build这个date?

首先,这不是千年虫问题! (更新:在某些情况下 – 这与千年虫问题有关,但这不是问题)

正确的答案是你不能可靠地做到这一点 。 夏令时是否适用于第1年? 那里有几个闰年? 有没有? 等等,但@Daniel的回答将会使用它!

更新:更不用说@MattJohnson关于DST的post。 DST在第一年,实际上JS(ES5无论如何)将谎言,并使用当前DST规则的所有年份

所以,请不要自欺欺人地认为自己可以在1970年以前的date工作。(即使在这个时间范围内,你也会遇到很多问题和惊喜)。

但是如果真的,真的需要你可以使用new Date('0001-01-01') (ISO 8601格式)或@ Daniel的方法:

 var d = new Date(); d.setFullYear(1); 

但是在使用之前请阅读这个…


JS中有4种创builddate的方法:

 new Date() new Date(milliseconds) new Date(dateString) new Date(year, month, day, hours, minutes, seconds, milliseconds) 

1) 新的date()创build当前date(在您当地的时区),所以我们现在不感兴趣。


2) 新的date(数字)创build一个新的date对象作为零时间加数字。 零时间是1970年1月1日00:00:00 UTC。

所以在这个案例中,JS从1970年开始计算时间。

 (new Date(0)).toUTCString() "Thu, 01 Jan 1970 00:00:00 GMT 

如果你使用负数,你可以在1970年之前“回”它的时间

 (new Date(-62167219200000)).toUTCString() "Sat, 01 Jan 0 00:00:00 GMT" -62167219200000 <- milliseconds -62167219200000 / 1000 -62167219200 <- seconds -62167219200 / 60 -1036120320 <- minutes -1036120320 / 60 -17268672 <- hours -17268672 / 24 -719528 <- days -719528 / 365 -1971.309589041096 <- years ( this is roughly calculated value ) 

问题是它不可靠。 那里有几个闰年? 有没有? 夏令时? 等我不喜欢它,因为这个神奇的数字-62167219200000


3) 新date(dateString)这是最“可靠”的方式。 DateString – 表示RFC2822或ISO 8601date的string。

RFC2822 / IETFdate语法(RFC2822第3.3节),例如“星期一,1995年12月25日13:30:00 GMT”

它的问题是,如果你使用负数,你会得到一个不正确的dateNaN在所有方法的结果

 (new Date('01 January -1 00:00:00 UTC')).getFullYear() NaN 

如果你使用年份大于或等于0且小于50,那么2000会自动添加。

 (new Date('01 January 0 00:00:00 UTC')).getFullYear() 2000 (new Date('01 January 1 00:00:00 UTC')).getFullYear() 2001 (new Date('01 January 10 00:00:00 UTC')).getFullYear() 2010 (new Date('01 January 01 00:00:00 UTC')).getFullYear() 2001 (new Date('01 January 30 00:00:00 UTC')).getFullYear() 2030 (new Date('01 January 49 00:00:00 UTC')).getFullYear() 2049 

如果你使用年份高于或等于50且低于100,则1900将被添加。

 (new Date('01 January 50 00:00:00 UTC')).getFullYear() 1950 (new Date('01 January 51 00:00:00 UTC')).getFullYear() 1951 (new Date('01 January 90 00:00:00 UTC')).getFullYear() 1990 (new Date('01 January 99 00:00:00 UTC')).getFullYear() 1999 

等于100或更高的年份将获得正确的年份编号

 (new Date('01 January 100 00:00:00 UTC')).getFullYear() 100 (new Date('01 January 101 00:00:00 UTC')).getFullYear() 101 (new Date('01 January 999 00:00:00 UTC')).getFullYear() 999 (new Date('01 January 9999 00:00:00 UTC')).getFullYear() 9999 

所以我们不能使用RFC2822 / IETFdate语法来创build第一年

关于ISO 8601:

http://www.w3.org/TR/NOTE-datetime

实际的格式是

 Year: YYYY (eg 1997) Year and month: YYYY-MM (eg 1997-07) Complete date: YYYY-MM-DD (eg 1997-07-16) Complete date plus hours and minutes: YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00) Complete date plus hours, minutes and seconds: YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) Complete date plus hours, minutes, seconds and a decimal fraction of a second YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00) 

我们最感兴趣的是“完成date”

 (new Date('0001-01-01')).toUTCString() "Mon, 01 Jan 1 00:00:00 GMT" 

雅虎! (或者说Google!:)),我们可以使用ISO 8601创build第一年的date

但要小心,不要试图使用负数或短年数,因为parsing这些可能会有所不同本地化或只是疯狂:)

 (new Date('-0001-01-01')).toUTCString() "Sun, 31 Dec 2000 21:00:00 GMT" (new Date('01-01-01')).toUTCString() "Sun, 31 Dec 2000 21:00:00 GMT" (new Date('02-01-01')).toUTCString() "Wed, 31 Jan 2001 21:00:00 GMT" (new Date('02-01-05')).toUTCString() "Mon, 31 Jan 2005 21:00:00 GMT" 

4) 新的date(年,月,日,时,分,秒,毫秒)

要使用这一个,你必须传递两个参数(年和月),其他的都是可选的。 要小心,因为这个月将从0到11开始,而不是像其他地方一样。 WAT? O_O

警告! 这个date将在您当前的时区创build! 所以要小心使用它!

UPD: @ matt-johnson的澄清

实际上Date对象总是反映当地时区。 您不能将它放在另一个时区,即使您使用UTC时间戳初始化它,它仍将reflection大部分函数中的本地时区。 在内部,它通过数字时间戳来跟踪UTC,并且有一些函数显式公开UTC值,但其他一切都是局部的。

负数将被解释为负数年份

 (new Date(-1, 0)).toString() "Fri Jan 01 -1 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(-234, 0)).toString() "Wed Jan 01 -234 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 

从0到99的数字将自动增加1900

 (new Date(0, 0)).toString() "Mon Jan 01 1900 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(1, 0)).toString() "Tue Jan 01 1901 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(11, 0)).toString() "Sun Jan 01 1911 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(50, 0)).toString() "Sun Jan 01 1950 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(99, 0)).toString() "Fri Jan 01 1999 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 

从100到275760的数字将被解释为年份数字

 (new Date(100, 0)).toString() "Fri Jan 01 100 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(102, 0)).toString() "Sun Jan 01 102 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(2002, 0)).toString() "Tue Jan 01 2002 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 

而数字高于275760将是无效的date

 (new Date(275760, 0)).toString() "Tue Jan 01 275760 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" (new Date(275761, 0)).toString() "Invalid Date" 

UPD:

新date(Date.UTC(1,1,1))将从与新date(年,月,日,小时,分钟,秒,毫秒)相同的症状中更安全。 由于Date.UTCfunction。

使用setFullYear – 这是JavaScript的Y2K问题。

 var d = new Date(); d.setFullYear(1); document.write(d); 

在处理JavaScriptdate对象时,你必须指定1950年的全年,而不是50年。这是在文档中提到的。 所以代码应该像丹尼尔所说的那样,

 d = new Date(); d.setFullYear(1); console.log(d); 

(不build议使用) Date.setYear方法设置指定date的年份,但请注意:

如果yearValue是0到99(含)之间的数字,则dateObj的年份设置为1900 + yearValue。 否则,dateObj的year设置为yearValue。

 var theBigDay = new Date(); theBigDay.setYear(96); // sets year to 1996 theBigDay.setYear(1996); // sets year to 1996 theBigDay.setYear(2000); // sets year to 2000 

不过你应该使用Date.setFullYear方法。 另一种方法已被弃用。