资讯专栏INFORMATION COLUMN

你可能不知道的 Date 类

missonce / 1785人阅读

摘要:构造函数通过可以进行实例化,得到一个对象实例,值得注意的是如果直接执行,将得到一个时间字符串。依照此标准,在此格式能被表示的最后时间是年月日,星期二。错误的计算及动作可能因此产生。

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 ):

如果没有输入任何参数,则Date的构造器会依据系统设置的当前时间来创建一个Date对象。

如果提供了至少两个参数,其余的参数均会默认设置为1(如果没有提供day参数)或者0。

JavaScript的时间是由世界标准时间(UTC)1970年1月1日开始,用毫秒计时,一天由86,400,000毫秒组成。Date对象的范围是-100,000,000天至100,000,000天(等效的毫秒值)。

JavaScript的Date对象为跨平台提供了统一的行为。时间属性可以在不同的系统中表示相同的时刻,而如果使用了本地时间对象,则反映当地的时间。

JavaScript 的Date对象提供了数个UTC时间的方法,也相应提供了当地时间的方法。UTC,也就是我们所说的格林威治时间,指的是time中的世界时间标准。而当地时间则是指执行JavaScript的客户端电脑所设置的时间。

以一个函数的形式来调用JavaScript的Date对象(i.e., 不使用 new 操作符)会返回一个代表当前日期和时间的字符串。

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]

new Date(year, month, ……) 中的month从0开始计算

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. 库

moment - 重量级时间处理库,支持时间解析、格式化、计算等,功能强大,支持浏览器和 Node.js,压缩后体积约为 16.3 KB

date-fns - 较 moment 更轻量级的事件处理库,体积更小

dayjs - 更轻量级的 moment.js

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97692.html

相关文章

  • Java 包(package)介绍

    摘要:实际上,一个完整的类名就是包名与类名的组合。例如一个文件内容如下这表示和都属于这个包,它们的完整类名分别是和。包就是文件夹包代表的是一种树形结构的路径,而在操作系统和压缩包当中,路径都是以文件夹的形式展现的。 1. 为什么 Java 会有包的概念? 我们知道 Class(类)是 Java 中的一等公民,所有的 Java 代码,都要写在类里面。 我们也知道,在命名规则下,你可以给类起任何...

    Sanchi 评论0 收藏0
  • 如何看待Spring下单例模式与线程安全矛盾

    摘要:线程安全问题都是由全局变量及静态变量引起的。常量始终是线程安全的,因为只存在读操作。局部变量是线程安全的。有状态对象,就是有实例变量的对象,可以保存数据,是非线程安全的。 前言 有多少人在使用Spring框架时,很多时候不知道或者忽视了多线程的问题?   因为写程序时,或做单元测试时,很难有机会碰到多线程的问题,因为没有那么容易模拟多线程测试的环境。那么当多个线程调用同一个bean的时...

    dinfer 评论0 收藏0
  • 如何看待Spring下单例模式与线程安全矛盾

    摘要:线程安全问题都是由全局变量及静态变量引起的。常量始终是线程安全的,因为只存在读操作。局部变量是线程安全的。有状态对象,就是有实例变量的对象,可以保存数据,是非线程安全的。 前言 有多少人在使用Spring框架时,很多时候不知道或者忽视了多线程的问题?   因为写程序时,或做单元测试时,很难有机会碰到多线程的问题,因为没有那么容易模拟多线程测试的环境。那么当多个线程调用同一个bean的时...

    刘永祥 评论0 收藏0
  • 【译】State and Lifecycle (State和生命周期)

    摘要:结果如下打开试试下一步,我们将把组件功能自己设置定时器并且能每秒更新。这是一个设置定时器的好地方注意我们是怎么保存定时器的。我们将在这个生命周期的函数方法中卸载掉定时器最后,我们会每一秒跑方法。 下面是react官方文档的个人翻译,如有翻译错误,请多多指出原文地址:https://facebook.github.io/re... Consider the ticking clock e...

    dadong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<