MDN
W3school

ECMAScript的 Date 类型参考了Java早期版本中的 java.util.Date 。为此, Date 类型将日期保存为自协调世界时 (UTC,Universal Time Coordinated)时间1970年1月1日午夜(零时)至今 所经过的毫秒数。使用这种存储格式, Date 类型可以精确表示1970年1月 1日之前及之后285 616年的日期。

时间对象

Date 是 JavaScript 的时间对象,同时也是一个构造函数。

创建日期

  1. let now = new Date();

在不给 Date 构造函数传参数的情况下,创建的对象将保存当前日期 和时间。

要基于其他日期和时间创建日期对象,必须传入其毫秒表示 (UNIX纪元1970年1月1日午夜之后的毫秒数)。ECMAScript为此提供了两 个辅助方法: Date.parse() 和 Date.UTC() 。

Date.parse() 创建指定日期

Date.parse() 方法接收一个表示日期的字符串参数,尝试将这个字 符串转换为表示该日期的毫秒数。ECMA-262第5版定义了 Date.parse() 应该支持的日期格式,填充了第3版遗留的空白。
所有实 现都必须支持下列日期格式:

  1. - “月/日/年”,如 "5/23/2019"
  2. - “月名 日, 年”,如 "May 23, 2019"
  3. - 周几 月名 时:分:秒 时区”,如 "Tue May 23 2019 00:00:00 GMT-0700"
  4. - ISO 8601扩展格式“YYYY-MM-DDTHH:mm:ss.sssZ”,如 2019-05- 23T00:00:00 (只适用于兼容ES5的实现)。

比如,要创建一个表示“2019年5月23日”的日期对象,可以使用以下代 码:

  1. let someDate = new Date(Date.parse("May 23, 2019"));

如果传给 Date.parse() 的字符串并不表示日期,则该方法会返回 NaN 。如果直接把表示日期的字符串传给 Date 构造函数,那么 Date 会 在后台调用 Date.parse() 。换句话说,下面这行代码跟前面那行代码是 等价的:

  1. let someDate = new Date("May 23, 2019");

注意 不同的浏览器对 Date 类型的实现有很多问题。比如,很多浏览 器会选择用当前日期替代越界的日期,因此有些浏览器会将 “January 32, 2019” 解释为 “February 1, 2019” 。Opera则会插入当前月的 当前日,返回 “January 当前日, 2019” 。就是说,如果是在9月21日 运行代码,会返回 “January 21, 2019” 。

Date.UTC()

Date.UTC() 方法也返回日期的毫秒表示,但使用的是跟 Date.parse() 不同的信息来生成这个值。传给 Date.UTC() 的参数是 年、零起点月数(1月是0,2月是1,以此类推)、日(1~31)、时 (0~23)、分、秒和毫秒。这些参数中,只有前两个(年和月)是必需的。 如果不提供日,那么默认为1日。其他参数的默认值都是0。下面是使用 Date.UTC() 的两个例子:

  1. // GMT时间2000年1月1日零点
  2. let y2k = new Date(Date.UTC(2000, 0));
  3. // GMT时间2005年5月5日下午5点55分55秒
  4. let allFives = new Date(Date.UTC(2005, 4, 5, 17, 55,55));

与 Date.parse() 一样, Date.UTC() 也会被 Date 构造函数隐式 调用,但有一个区别:这种情况下创建的是本地日期,不是GMT日期。不 过 Date 构造函数跟 Date.UTC() 接收的参数是一样的。因此,如果第一 个参数是数值,则构造函数假设它是日期中的年,第二个参数就是月,以此 类推。前面的例子也可以这样来写:

  1. // 本地时间2000年1月1日零点
  2. let y2k = new Date(2000, 0);
  3. // 本地时间2005年5月5日下午5点55分55秒
  4. let allFives = new Date(2005, 4, 5, 17, 55, 55);

继承的方法

与其他类型一样, Date 类型重写了 toLocaleString() 、 toString() 和 valueOf() 方法。

但与其他类型不同,重写后这些方法 的返回值不一样。

Date 类型的 toLocaleString() 方法返回与浏览器 运行的本地环境一致的日期和时间。

这通常意味着格式中包含针对时间的 AM(上午)或PM(下午),但不包含时区信息(具体格式可能因浏览器而 不同)。
image.png

toString() 方法通常返回带时区信息的日期和时间,而时间也 是以24小时制(0~23)表示的。
image.png

chrome浏览器控制台测试结果。

valeOf

Date 类型的 valueOf() 方法根本就不返回字符串,这个方法被重 写后返回的是日期的毫秒表示。因此,操作符(如小于号和大于号)可以直 接使用它返回的值。比如下面的例子:

  1. let date1 = new Date(2019, 0, 1); // 2019年1月1日
  2. let date2 = new Date(2019, 1, 1); // 2019年2月1日
  3. console.log(date1 < date2); // true
  4. console.log(date1 > date2); // false

日期2019年1月1日在2019年2月1日之前,所以说前者小于后者没问题。 因为2019年1月1日的毫秒表示小于2019年2月1日的毫秒表示,所以用小于号 比较这两个日期时会返回 true 。这也是确保日期先后的一个简单方式。

日期格式化

Date 类型有几个专门用于格式化日期的方法,它们都会返回字符 串:

toDateString() 显示日期中的周几、月、日、年(格式特定于实 现);
toTimeString() 显示日期中的时、分、秒和时区(格式特定于实 现);
toLocaleDateString() 显示日期中的周几、月、日、年(格式特 定于实现和地区);
toLocaleTimeString() 显示日期中的时、分、秒(格式特定于实 现);
toUTCString() 显示完整的UTC日期(格式特定于实现)。

这些方法的输出与 toLocaleString() 和 toString() 一样,会 因浏览器而异。因此不能用于在用户界面上一致地显示日期。

注意 还有一个方法叫 toGMTString() ,这个方法跟 toUTCString() 是一样的,目的是为了向后兼容。不过,规范建议新 代码使用 toUTCString() 。

日期/时间组件常用方法

  1. new Date().getFullYear() // 2018 | 年
  2. new Date().getMonth() // 9 | 月 (0 ~ 11 代表 1 - 12 月份)
  3. new Date().getDate() // 21 | 日
  4. new Date().getDay() // 5 | 星期几
  5. new Date().getHours() // 14 | 时
  6. new Date().getMinutes() // 20 | 分
  7. new Date().getSeconds() // 14 | 秒
  8. new Date().getMilliseconds() // 930 | 毫秒
  9. new Date().getTime() // 1537510914079 | 时间戳

时间运算

image.png

编程中的时间运算,通常都是通过时间戳来加减,之后在把时间戳转换成 标准时间格式

  1. // 得到一个7天后的时间对象
  2. new Date(new Date().getTime() + (7 * 24 * 60 * 60 * 1000)) // + 7天

标准时间格式

时间的显示形式,有一个约定俗成的标准 2018-9-21 14:32:18,日常我们所见的,都是这种格式。格式的统一方便在不同语言中处理,大部分的现代高级语言,内置的时间处理工具,都能轻易的把时间对象格式成这种格式,但是 JavaScript 并没有这种能力,它转换出来的时间格式不标准。

  1. new Date().toLocaleDateString() // 2018/9/21
  2. new Date().toLocaleString() // "2018/9/21 下午2:38:22"
  1. moment 是一个 JavaScript 的第三方时间处理工具,它能方便的得到我们想要的 | moment().format('YYYY-MM-DD HH:mm:ss')

进退位操作

js 中 Date 在处理时间的时候会做进位退位操作

image.png

常用格式处理

2019年7月10日 星期三

  1. getTodayString() {
  2. var weeks = ["日", "一", "二", "三", "四", "五", "六"];
  3. var today = new Date();
  4. return today.getFullYear() + "年" + (today.getMonth() + 1) + "月" + today.getDate() + "日 星期" + weeks[today.getDay()];
  5. }
  6. // expected output: 2019年7月10日 星期三

月份小于10加0

  1. month = month < 10 ? '0'+ month : month

分钟小于 10 加 0

  1. var StartMinute = startDate.getMinutes().toString().length >= 2 ? startDate.getMinutes() : '0' + startDate.getHours();
  2. var StartMinute = `00${hours}`.slice(-2)` // 先统一加零再取后两位