你可能不知道的 Date 类

2017-12-17 14:20:07 +08:00
 xcold

原文链接: http://blog.lxstart.net/2017/12/17/%E4%BD%A0%E5%8F%AF%E8%83%BD%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84-Date-%E7%B1%BB/

Date 是 JS 中的重要的一个内置对象,其实例主要用于处理时间和日期,其时间基于 1970-1-1 (世界标准时间)起的毫秒数,时间戳长度为 13 位(不同于 Unix 时间戳的长度 10 位)。对于日期和时间,我们有无数的使用场景,因此需要特别注意一些细节和约定。

1. 构造函数

通过 new Date() 可以进行实例化,得到一个 Date 对象实例,值得注意的是如果直接执行 Date() ,将得到一个时间字符串。

new Date();
new Date(value);
new Date(dateString);
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

其中对构造函数的参数说明(参考 MDN ):

2. 空值处理

// 以 chrome 为例
new Date();
// Mon Oct 23 2017 23:38:02 GMT+0800 (CST)

new Date(false);
// Thu Jan 01 1970 08:00:00 GMT+0800 (CST)

new Date(0);
// Thu Jan 01 1970 08:00:00 GMT+0800 (CST)

new Date(null);
// Thu Jan 01 1970 08:00:00 GMT+0800 (CST)

new Date('');
// Invalid Date

new Date(undefined);
// Invalid Date

3. 特别提示

[Firefox]

不支持带 '-' 的完整时间,比如 new Date('2012-07-08 00:00:00') 为无效的值,而 new Date('2012-07-08') 是正确的值。

[month]

4. 值的边界

不同执行环境下的边界值有差异,Chrome 下甚至连负值都能支持。在实际生产环境中,不仅需要考虑时间的展示,还需要考虑其存储、计算等,因此在特定的场景下,我们需要尽可能考虑到数据库和浏览器中 Date 的有效范围。

以数据库 Derby 存储时间为例,其边界为:

| 说明 | 边界值 | | :--- | :--- | | 最小的日期 | 0001-01-01 | | 最大的日期 | 9999-12-31 | | 最小的时间 | 00:00:00 | | 最大的时间 | 24:00:00 | | 最小的时间戳 | 0001-01-01-00.00.00.000000 | | 最大的时间戳 | 9999-12-31-23.59.59.999999 |

mysql 中,其范围定义为 1000-01-01to9999-12-31; 在 js 中,时间戳的最小值为 -8640000000000000 即公元前 271,821 年 4 月 20 日,最大值为 8640000000000000,即 275,760 年 9 月 13 日。规范中时间范围为 1970/1/1 前后 100,000,000 天。

5. 2038 年虫

听说,2038 年之后时间戳不够用了。

在计算机应用上,2038 年问题可能会导致某些软件在 2038 年无法正常工作。所有使用 UNIX 时间表示时间的程序都将受其影响,因为它们以自 1970 年 1 月 1 日经过的秒数(忽略闰秒)来表示时间。这种时间表示法在类 Unix ( Unix-like )操作系统上是一个标准,并会影响以其 C 编程语言开发给其他大部份操作系统使用的软件。在大部份的 32 位操作系统上,此“ time_t ”数据模式使用一个有正负号的 32 位元整数(signedint32)存储计算的秒数。依照此“ time_t ”标准,在此格式能被表示的最后时间是 2038 年 1 月 19 日 03:14:07,星期二( UTC )。超过此一瞬间,时间将会被掩盖( wrap around )且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为 2038 年,而可能会依个别实作而跳回 1970 年或 1901 年。错误的计算及动作可能因此产生。

实际上参考第 4 部分,Date 的上限绰绰有余,大家可以拿起手头的设备测试一下 2038 年会出现怎样的异状。

6. 参考

1、EmacScript 语言规范 - http://ecma-international.org/ecma-262/5.1/#sec-15.9

2、Mysql 时间范围 - https://dev.mysql.com/doc/refman/5.5/en/datetime.html

3、JS 时间戳边界 - https://stackoverflow.com/questions/11526504/minimum-and-maximum-date

7. 库

1712 次点击
所在节点    问与答
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/415450

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX