ECMAScript的 Date 类型参考了Java早期版本中的 java.util.Date 。为此, Date 类型将日期保存为自协调世界时 (UTC,Universal Time Coordinated)时间1970年1月1日午夜(零时)至今 所经过的毫秒数。使用这种存储格式, Date 类型可以精确表示1970年1月 1日之前及之后285 616年的日期。
时间对象
Date
是 JavaScript 的时间对象,同时也是一个构造函数。
创建日期
let now = new Date();
在不给 Date 构造函数传参数的情况下,创建的对象将保存当前日期 和时间。
要基于其他日期和时间创建日期对象,必须传入其毫秒表示 (UNIX纪元1970年1月1日午夜之后的毫秒数)。ECMAScript为此提供了两 个辅助方法: Date.parse() 和 Date.UTC() 。
Date.parse() 创建指定日期
Date.parse() 方法接收一个表示日期的字符串参数,尝试将这个字 符串转换为表示该日期的毫秒数。ECMA-262第5版定义了 Date.parse() 应该支持的日期格式,填充了第3版遗留的空白。
所有实 现都必须支持下列日期格式:
- “月/日/年”,如 "5/23/2019" ;
- “月名 日, 年”,如 "May 23, 2019" ;
- 周几 月名 日 年 时:分:秒 时区”,如 "Tue May 23 2019 00:00:00 GMT-0700" ;
- ISO 8601扩展格式“YYYY-MM-DDTHH:mm:ss.sssZ”,如 2019-05- 23T00:00:00 (只适用于兼容ES5的实现)。
比如,要创建一个表示“2019年5月23日”的日期对象,可以使用以下代 码:
let someDate = new Date(Date.parse("May 23, 2019"));
如果传给 Date.parse() 的字符串并不表示日期,则该方法会返回 NaN 。如果直接把表示日期的字符串传给 Date 构造函数,那么 Date 会 在后台调用 Date.parse() 。换句话说,下面这行代码跟前面那行代码是 等价的:
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() 的两个例子:
// GMT时间2000年1月1日零点
let y2k = new Date(Date.UTC(2000, 0));
// GMT时间2005年5月5日下午5点55分55秒
let allFives = new Date(Date.UTC(2005, 4, 5, 17, 55,55));
与 Date.parse() 一样, Date.UTC() 也会被 Date 构造函数隐式 调用,但有一个区别:这种情况下创建的是本地日期,不是GMT日期。不 过 Date 构造函数跟 Date.UTC() 接收的参数是一样的。因此,如果第一 个参数是数值,则构造函数假设它是日期中的年,第二个参数就是月,以此 类推。前面的例子也可以这样来写:
// 本地时间2000年1月1日零点
let y2k = new Date(2000, 0);
// 本地时间2005年5月5日下午5点55分55秒
let allFives = new Date(2005, 4, 5, 17, 55, 55);
继承的方法
与其他类型一样, Date 类型重写了 toLocaleString() 、 toString() 和 valueOf() 方法。
但与其他类型不同,重写后这些方法 的返回值不一样。
Date 类型的 toLocaleString() 方法返回与浏览器 运行的本地环境一致的日期和时间。
这通常意味着格式中包含针对时间的 AM(上午)或PM(下午),但不包含时区信息(具体格式可能因浏览器而 不同)。
toString() 方法通常返回带时区信息的日期和时间,而时间也 是以24小时制(0~23)表示的。
valeOf
Date 类型的 valueOf() 方法根本就不返回字符串,这个方法被重 写后返回的是日期的毫秒表示。因此,操作符(如小于号和大于号)可以直 接使用它返回的值。比如下面的例子:
let date1 = new Date(2019, 0, 1); // 2019年1月1日
let date2 = new Date(2019, 1, 1); // 2019年2月1日
console.log(date1 < date2); // true
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() 。
日期/时间组件常用方法
new Date().getFullYear() // 2018 | 年
new Date().getMonth() // 9 | 月 (0 ~ 11 代表 1 - 12 月份)
new Date().getDate() // 21 | 日
new Date().getDay() // 5 | 星期几
new Date().getHours() // 14 | 时
new Date().getMinutes() // 20 | 分
new Date().getSeconds() // 14 | 秒
new Date().getMilliseconds() // 930 | 毫秒
new Date().getTime() // 1537510914079 | 时间戳
时间运算
编程中的时间运算,通常都是通过时间戳来加减,之后在把时间戳转换成 标准时间格式
。
// 得到一个7天后的时间对象
new Date(new Date().getTime() + (7 * 24 * 60 * 60 * 1000)) // + 7天
标准时间格式
时间的显示形式,有一个约定俗成的标准 2018-9-21 14:32:18
,日常我们所见的,都是这种格式。格式的统一方便在不同语言中处理,大部分的现代高级语言,内置的时间处理工具,都能轻易的把时间对象格式成这种格式,但是 JavaScript 并没有这种能力,它转换出来的时间格式不标准。
new Date().toLocaleDateString() // 2018/9/21
new Date().toLocaleString() // "2018/9/21 下午2:38:22"
moment 是一个 JavaScript 的第三方时间处理工具,它能方便的得到我们想要的 | moment().format('YYYY-MM-DD HH:mm:ss')
进退位操作
js 中 Date 在处理时间的时候会做进位退位操作。
常用格式处理
2019年7月10日 星期三
getTodayString() {
var weeks = ["日", "一", "二", "三", "四", "五", "六"];
var today = new Date();
return today.getFullYear() + "年" + (today.getMonth() + 1) + "月" + today.getDate() + "日 星期" + weeks[today.getDay()];
}
// expected output: 2019年7月10日 星期三
月份小于10加0
month = month < 10 ? '0'+ month : month
分钟小于 10 加 0
var StartMinute = startDate.getMinutes().toString().length >= 2 ? startDate.getMinutes() : '0' + startDate.getHours();
var StartMinute = `00${hours}`.slice(-2)` // 先统一加零再取后两位