Javascript日期01/01/0001

时间:2015-04-30 12:44:38

标签: javascript date datetime

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

我试过

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

但它给出了1901年

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

没办法。

如何创建此日期?

5 个答案:

答案 0 :(得分:41)

首先,它根本不是Y2K问题!(更新:在某些情况下 - 它与Y2K问题有关,但这不是问题)

正确答案是无法可靠地执行此操作。夏令时适用于第1年吗?有多少闰年?有没有?等等。但@Daniel的答案将使用它!

更新:更不用说@MattJohnson关于DST的帖子了。 DST in year 1, actually JS (ES5 anyway) will lie and use the current DST rule for all years

所以请不要愚弄自己能够可靠地处理低于1970年的日期的想法。(即使在那个时间范围内,你也会遇到很多问题和惊喜。)

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

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

但在你使用它之前,请阅读...

有四种方法可以在JS中创建日期:

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

1)新日期()会创建当前日期(在您当地的时区),因此我们暂时对它不感兴趣。

2)新日期(数字)创建一个新的日期对象为零时间加上数字。零时间是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)新日期(dateString)这是最“可靠”的方式。 DateString - 表示RFC2822或ISO 8601日期的字符串。

RFC2822 / IETF日期语法(RFC2822第3.3节),例如“星期一,1995年12月25日格林尼治标准时间13:30:00”

问题在于,如果你使用负数,你将在所有方法的结果中得到一个不正确的日期和NaN

(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 / IETF日期语法创建第1年

关于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)

我们对'完成日期'最感兴趣

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

<强>雅虎! (或者最好说谷歌!:)),我们可以使用ISO 8601创建第1年的日期

但要小心,不要尝试使用负数或短年数,因为解析这些数字可能因本地化或疯狂而有所不同:)

(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)新日期(年,月,日,小时,分钟,秒,毫秒)

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

警告!此日期将在您当前的时区创建!所以小心使用它!

UPD: @ matt-johnson的澄清

  

...实际上Date对象总是反映本地时区。您不能将它放在另一个时区,即使使用UTC时间戳初始化它,它仍会在大多数功能中反映当地时区。在内部,它通过数字时间戳跟踪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的数字将是无效日期

(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.UTC(1,1,1))将与新日期(年,月,日,小时,分钟,秒,毫秒)相同的症状更安全。因为Date.UTC函数。

答案 1 :(得分:36)

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

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

答案 2 :(得分:2)

您可以使用构造函数的字符串版本:

console.log(new Date("0001-01-01"));

答案 3 :(得分:1)

处理JavaScript日期对象时,您必须指定ex,1950而不是50的全年。文档中提到了它。所以代码应该像丹尼尔所说的那样,

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

答案 4 :(得分:1)

(已弃用)Date.setYear方法设置指定日期的年份,但请注意:

  

如果yearValue是0到99之间的数字(含),那么年份   for dateObj设置为1900 + yearValue。否则,今年   dateObj设置为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方法。另一种方法已被弃用。