Javascript日期01/01/0001

Nar*_*sim 41 javascript datetime date

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

我试过了

d = new Date(); d.setYear(1);
console.log(d);
Run Code Online (Sandbox Code Playgroud)

但它给了1901年

d = new Date(1,1,1)
console.log(d);
Run Code Online (Sandbox Code Playgroud)

没门.

我该如何创建这个日期?

obe*_*iro 44

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

正确的答案是你不能可靠地做到这一点.夏令时适用于第1年吗?有多少闰年?有没有?等等.但@Daniel的答案将使用它!

更新:更不用说@MattJohnson关于DST的帖子了.在第1年的夏令时,实际上JS(ES5无论如何)将谎言并使用当前的DST规则所有年份

因此,请不要愚弄自己能够可靠地使用低于1970年的日期的想法.(即使在该时间范围内,您也会遇到很多问题和惊喜.)

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

var d = new Date(); d.setFullYear(1);
Run Code Online (Sandbox Code Playgroud)

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


在JS中有4种方法可以创建Date:

new Date()
new Date(milliseconds)
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
Run Code Online (Sandbox Code Playgroud)

1)新的Date()创建当前日期(在您当地的时区),所以我们现在对它不感兴趣.


2)new Date(number)创建一个新的日期对象为零时间加上数字.零时间是1970年1月1日00:00:00 UTC.

所以在这种情况下JS的时间从1970年算起.

(new Date(0)).toUTCString()
"Thu, 01 Jan 1970 00:00:00 GMT
Run Code Online (Sandbox Code Playgroud)

如果你使用负数,你可以在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 )
Run Code Online (Sandbox Code Playgroud)

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


3)new Date(dateString)这是最"可靠"的方式.DateString - 表示RFC2822或ISO 8601日期的字符串.

RFC2822/IETF日期语法(RFC2822第3.3节),例如"Mon,25 Dec 1995 13:30:00 GMT"

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

(new Date('01 January -1 00:00:00 UTC')).getFullYear()
NaN
Run Code Online (Sandbox Code Playgroud)

如果您使用年份更高或等于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
Run Code Online (Sandbox Code Playgroud)

如果您使用更高或等于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
Run Code Online (Sandbox Code Playgroud)

等于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
Run Code Online (Sandbox Code Playgroud)

因此,我们无法使用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)
Run Code Online (Sandbox Code Playgroud)

我们最感兴趣的是'完成约会'

(new Date('0001-01-01')).toUTCString()
"Mon, 01 Jan 1 00:00:00 GMT"
Run Code Online (Sandbox Code Playgroud)

雅虎!(或者最好说Google!:)),我们可以使用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"
Run Code Online (Sandbox Code Playgroud)

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)"
Run Code Online (Sandbox Code Playgroud)

从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)"
Run Code Online (Sandbox Code Playgroud)

从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)"
Run Code Online (Sandbox Code Playgroud)

而高于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"
Run Code Online (Sandbox Code Playgroud)

UPD:

新日期(Date.UTC(1,1,1))将与新日期(年,月,日,小时,分钟,秒,毫秒)相同的症状更安全.因为Date.UTC功能.

  • 不,他们不是,或者我们不能确定.那时(或没有)有其他各种日历系统.[格里高利历](http://en.wikipedia.org/wiki/Gregorian_calendar)在1582年开始逐步开始.JS(以及大多数其他人)使用ISO-8601日历,这是一个***的保证***阳历日历.这意味着它就好像这个日历*总是*有效,即使我们清楚地知道它不是.换句话说,JavaScript的"第一年"是我们*年前的2014年,但它与当时正在使用的其他日历上的"第一年"不同. (4认同)
  • 这是你的说法:"这是一团糟"? (2认同)

Dan*_*ite 38

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

var d = new Date(); d.setFullYear(1);
document.write(d);
Run Code Online (Sandbox Code Playgroud)

  • 多么复古:)为了怀旧的目的而投入`document.write`! (9认同)