javascript 中的 Date 构造函数对字符串“0”到“110”进行字符串解析背后的逻辑是什么?

Lui*_*bia 5 javascript time parsing date timezone-offset

我试图看看依靠执行 aconst myNewDate = new Date(dateString)然后使用 an的结果_.isDate(myNewDate)是否足以验证它是“有效日期”,但后来我想:我可以收到什么dateString

我想到要执行以下操作: for(i=0;i<110;i++) { console.log(i, new Date(String(i)))}

这是我得到的结果:

0 2000-01-01T06:00:00.000Z
1 2001-01-01T06:00:00.000Z
2 2001-02-01T06:00:00.000Z
3 2001-03-01T06:00:00.000Z
4 2001-04-01T06:00:00.000Z
5 2001-05-01T05:00:00.000Z
6 2001-06-01T05:00:00.000Z
7 2001-07-01T05:00:00.000Z
8 2001-08-01T05:00:00.000Z
9 2001-09-01T05:00:00.000Z
10 2001-10-01T05:00:00.000Z
11 2001-11-01T06:00:00.000Z
12 2001-12-01T06:00:00.000Z
13 Invalid Date
14 Invalid Date
15 Invalid Date
16 Invalid Date
17 Invalid Date
18 Invalid Date
19 Invalid Date
20 Invalid Date
21 Invalid Date
22 Invalid Date
23 Invalid Date
24 Invalid Date
25 Invalid Date
26 Invalid Date
27 Invalid Date
28 Invalid Date
29 Invalid Date
30 Invalid Date
31 Invalid Date
32 2032-01-01T06:00:00.000Z
33 2033-01-01T06:00:00.000Z
34 2034-01-01T06:00:00.000Z
35 2035-01-01T06:00:00.000Z
36 2036-01-01T06:00:00.000Z
37 2037-01-01T06:00:00.000Z
38 2038-01-01T06:00:00.000Z
39 2039-01-01T06:00:00.000Z
40 2040-01-01T06:00:00.000Z
41 2041-01-01T06:00:00.000Z
42 2042-01-01T06:00:00.000Z
43 2043-01-01T06:00:00.000Z
44 2044-01-01T06:00:00.000Z
45 2045-01-01T06:00:00.000Z
46 2046-01-01T06:00:00.000Z
47 2047-01-01T06:00:00.000Z
48 2048-01-01T06:00:00.000Z
49 2049-01-01T06:00:00.000Z
50 1950-01-01T06:00:00.000Z
51 1951-01-01T06:00:00.000Z
52 1952-01-01T06:00:00.000Z
53 1953-01-01T06:00:00.000Z
54 1954-01-01T06:00:00.000Z
55 1955-01-01T06:00:00.000Z
56 1956-01-01T06:00:00.000Z
57 1957-01-01T06:00:00.000Z
58 1958-01-01T06:00:00.000Z
59 1959-01-01T06:00:00.000Z
60 1960-01-01T06:00:00.000Z
61 1961-01-01T06:00:00.000Z
62 1962-01-01T06:00:00.000Z
63 1963-01-01T06:00:00.000Z
64 1964-01-01T06:00:00.000Z
65 1965-01-01T06:00:00.000Z
66 1966-01-01T06:00:00.000Z
67 1967-01-01T06:00:00.000Z
68 1968-01-01T06:00:00.000Z
69 1969-01-01T06:00:00.000Z
70 1970-01-01T06:00:00.000Z
71 1971-01-01T06:00:00.000Z
72 1972-01-01T06:00:00.000Z
73 1973-01-01T06:00:00.000Z
74 1974-01-01T06:00:00.000Z
75 1975-01-01T06:00:00.000Z
76 1976-01-01T06:00:00.000Z
77 1977-01-01T06:00:00.000Z
78 1978-01-01T06:00:00.000Z
79 1979-01-01T06:00:00.000Z
80 1980-01-01T06:00:00.000Z
81 1981-01-01T06:00:00.000Z
82 1982-01-01T06:00:00.000Z
83 1983-01-01T06:00:00.000Z
84 1984-01-01T06:00:00.000Z
85 1985-01-01T06:00:00.000Z
86 1986-01-01T06:00:00.000Z
87 1987-01-01T06:00:00.000Z
88 1988-01-01T06:00:00.000Z
89 1989-01-01T06:00:00.000Z
90 1990-01-01T06:00:00.000Z
91 1991-01-01T06:00:00.000Z
92 1992-01-01T06:00:00.000Z
93 1993-01-01T06:00:00.000Z
94 1994-01-01T06:00:00.000Z
95 1995-01-01T06:00:00.000Z
96 1996-01-01T06:00:00.000Z
97 1997-01-01T06:00:00.000Z
98 1998-01-01T06:00:00.000Z
99 1999-01-01T06:00:00.000Z
100 0100-01-01T05:50:36.000Z
101 0101-01-01T05:50:36.000Z
102 0102-01-01T05:50:36.000Z
103 0103-01-01T05:50:36.000Z
104 0104-01-01T05:50:36.000Z
105 0105-01-01T05:50:36.000Z
106 0106-01-01T05:50:36.000Z
107 0107-01-01T05:50:36.000Z
108 0108-01-01T05:50:36.000Z
109 0109-01-01T05:50:36.000Z
Run Code Online (Sandbox Code Playgroud)

那么,稍微分析一下:

  • 从 0 到 4,该值用于 6:00 的“月”
  • 从 5 到 10,该值再次用于“月”,但在 5:00(为什么?)
  • 11和12,值为“月”,但返回到6:00
  • 13 到 31 是无效日期(为什么?)
  • 从 32 到 49,现在该值属于年份:2000 + 值(为什么?)
  • 从 50 到 99,现在该值属于年份:1900 + 值(为什么?)
  • 从100到110(甚至更多,我尝试了9999,结果相同)它属于年份,字面上:100变成0100年。但是时间,设置为5小时,分钟和秒属于我当前的计算机分钟和秒(为什么?)

这非常令人困惑。我很想找到这个的来源。

技术说明:

  • 这显然是 javascript 代码。
  • 我使用的是节点 12.16.3。
  • 如果我在 Chrome 的控制台中运行它,结果相同。
  • 在 Firefox 中,它返回所有无效日期。

Bin*_*Ury 1

\n

从 0 到 4,该值用于 6:00 的“月”

\n
\n

默认偏移量将是您的区域设置,在这些月份中为 -6。\n根据作者 Ryan Dahl 的说法,“为了KJS兼容性,默认年份为 0 (=> 2000)”。\n您可能已经注意到年份从 2000 年更改为 2001 年\xe2\x80\xa6 我相信这是一个错误。请参阅:现有答案

\n
\n

从 5 到 10,该值再次用于“月”,但在 5:00(为什么?)

\n
\n
\n

11和12,值为“月”,但返回到6:00

\n
\n

DST 在您的区域设置中发生变化,这是默认偏移量

\n
\n

13 到 31 是无效日期(为什么?)

\n
\n

由于提供的字符串不是有效的月份或 YYYY,因此它被解析为 DD,并且仅包含日期值的日期没有意义。为什么它不默认 MM 或 YY 不清楚\xe2\x80\xa6 推测,原因可能是解析时 YY 和 DD 之间的歧义。

\n
\n

从 32 到 49,现在该值属于年份:2000 + 值\n(为什么?)

\n
\n
\n

从 50 到 99,现在该值属于年份:1900 + 值\n(为什么?)

\n
\n

PHP strptime、Pythondatetime.strptime和 UNIX Cstrptime 假设 00-68 年份属于 2000 年,69-99 属于 1900 年。\n这是为了 API 方便,假设较低的数字 32:49,接近当前世纪的数字是当前世纪,而较高的数字 50:99 接近上世纪,则指的是该世纪。

\n
\n

从 100 到 110(甚至更多,我尝试了 9999,结果相同)\n它属于年份,字面意思是:100 变成年份 0100

\n
\n

YYY(当 > 99 时)字面上是YYYAD,类似于 ISO 年

\n
\n

但时间,设置为5小时,分和秒属于我\n当前电脑的分和秒(为什么?)

\n
\n

时区确实会随着时间的推移而变化,并且区域设置解析将尝试考虑这些变化。

\n
> (new Date("1883-05-31")).getTimezoneOffset()\n350\n> (new Date("1893-05-31")).getTimezoneOffset()\n360\n> (new Date("2023-05-31")).getTimezoneOffset()\n300\n
Run Code Online (Sandbox Code Playgroud)\n

但是,Unix 纪元之前的日期从不包含时区名称,并且 1883 年 11 月 18 日之前使用北美语言环境的日期不使用现代 GMT 偏移量,因为它尚未建立

\n
> new Date("1883", "10", "18", "12").toString()\n\'Sun Nov 18 1883 12:00:00 GMT-0550 (Central Standard Time)\'\n> new Date("1883", "10", "18", "13").toString()\n\'Sun Nov 18 1883 13:00:00 GMT-0600 (Central Standard Time)\'\n
Run Code Online (Sandbox Code Playgroud)\n

(变化发生在中午)

\n
> new Date("1883", "10", "18", "12", "09").toString()\n\'Sun Nov 18 1883 12:09:00 GMT-0550 (Central Standard Time)\'\n> new Date("1883", "10", "18", "12", "09", "24").toString()\n\'Sun Nov 18 1883 12:09:24 GMT-0600 (Central Standard Time)\'\n
Run Code Online (Sandbox Code Playgroud)\n


归档时间:

查看次数:

265 次

最近记录:

3 年,10 月 前