在JavaScript中使用日期可能很复杂。学习所有的技巧以及如何使用它们。
处理日期可以很“复杂”。无论使用什么技术,开发人员都会感到痛苦。
JavaScript提供了一个通过强大的内置对象Date
来处理日期的功能。
日期对象
一个日期对象实例表示一个时间点。
尽管名字是Date
,它也处理时间。
初始化日期对象
我们使用以下方式初始化一个日期对象。
new Date()
这将创建一个指向当前时间点的日期对象。
在内部,日期以从1970年1月1日(UTC)以来的毫秒表示。这个日期很重要,因为在计算机看来,一切都是在那一天开始的。
您可能对UNIX时间戳很熟悉:它代表了自那个著名日期以来经过的秒数。
如果我们有一个UNIX时间戳,我们可以使用以下方式实例化一个JavaScript日期对象:
const timestamp = 1530826365;
new Date(timestamp * 1000);
除非时间戳是由JS生成的,否则它已经在正确的比例上。
确保传递一个数字(字符串将得到一个“无效的日期”结果 - 如有疑问请使用parseInt()
)
如果我们传递0,我们将得到一个代表1970年1月1日(UTC)时间的日期对象:
new Date(0)
如果我们传递一个字符串而不是数字,那么日期对象将使用parse
方法来确定您传递的日期。例如:
new Date('2018-07-22')
new Date('2018-07') // 2018年7月1日,00:00:00
new Date('2018') // 2018年1月1日,00:00:00
new Date('07/22/2018')
new Date('2018/07/22')
new Date('2018/7/22')
new Date('July 22, 2018')
new Date('July 22, 2018 07:22:13')
new Date('2018-07-22 07:22:13')
new Date('2018-07-22T07:22:13')
new Date('25 March 2018')
new Date('25 Mar 2018')
new Date('25 March, 2018')
new Date('March 25, 2018')
new Date('March 25 2018')
new Date('March 2018') // 2018年3月1日,00:00:00
new Date('2018 March') // 2018年3月1日,00:00:00
new Date('2018 MARCH') // 2018年3月1日,00:00:00
new Date('2018 march') // 2018年3月1日,00:00:00
这里有很大的灵活性。您可以在月份或日期中添加或省略前导零。
注意月份/日期的位置,否则可能导致将月份误解为日期。
您也可以使用Date.parse
:
Date.parse('2018-07-22')
Date.parse('2018-07') // 2018年7月1日,00:00:00
Date.parse('2018') // 2018年1月1日,00:00:00
Date.parse('07/22/2018')
Date.parse('2018/07/22')
Date.parse('2018/7/22')
Date.parse('July 22, 2018')
Date.parse('July 22, 2018 07:22:13')
Date.parse('2018-07-22 07:22:13')
Date.parse('2018-07-22T07:22:13')
Date.parse
将返回一个时间戳(以毫秒为单位),而不是一个日期对象。
您也可以传递一组有序的值,表示日期的每个部分:年份,月份(从0开始),日期,小时,分钟,秒和毫秒:
new Date(2018, 6, 22, 7, 22, 13, 0)
new Date(2018, 6, 22)
最少应该有3个参数,但大多数JavaScript引擎也会处理比这些参数更少的情况:
new Date(2018, 6) // 2018年7月1日,00:00:00 GMT+0200(中央欧洲夏令时)
new Date(2018) // 1970年1月1日星期四,01:00:02 GMT+0100(中欧标准时间)
在上述任何情况下,所得到的日期都相对于计算机的时区。这意味着两台不同的计算机可能会为相同的日期对象输出不同的值。
JavaScript在没有关于时区的任何信息的情况下,会将日期视为UTC,并自动将其转换为当前计算机时区。
所以,总结一下,您可以通过以下4种方式创建一个新的日期对象
- 不传递任何参数,创建一个表示“现在”的日期对象
- 传递一个数字,它表示从1970年1月1日00:00 GMT开始的毫秒数
- 传递一个字符串,它表示一个日期
- 传递一组参数,它们表示日期的不同部分
时区
当初始化日期时,您可以通过添加+HOURS
格式的时区或将时区名称添加到括号中来指定时区:
new Date('July 22, 2018 07:22:13 +0700')
new Date('July 22, 2018 07:22:13 (CET)')
如果您在括号中指定了错误的时区名称,JavaScript将默认为UTC,而不会报错。
如果您指定了错误的数字格式,JavaScript将给出“Invalid Date”错误。
日期转换和格式化
给定一个日期对象,有许多方法可以从该日期生成一个字符串:
const date = new Date('July 22, 2018 07:22:13')
date.toString() // "Sun Jul 22 2018 07:22:13 GMT+0200 (中央欧洲夏时制)"
date.toTimeString() //"07:22:13 GMT+0200 (中央欧洲夏时制)"
date.toUTCString() //"Sun, 22 Jul 2018 05:22:13 GMT"
date.toDateString() //"Sun Jul 22 2018"
date.toISOString() //"2018-07-22T05:22:13.000Z"(ISO 8601格式)
date.toLocaleString() //"22/07/2018, 07:22:13"
date.toLocaleTimeString() //"07:22:13"
date.getTime() //1532236933000
date.getTime() //1532236933000
日期对象的获取器方法
日期对象提供了几种方法来检查其值。这些都取决于计算机的当前时区:
const date = new Date('July 22, 2018 07:22:13')
date.getDate() //22
date.getDay() //0(0表示星期天,1表示星期一..)
date.getFullYear() //2018
date.getMonth() //6(从0开始)
date.getHours() //7
date.getMinutes() //22
date.getSeconds() //13
date.getMilliseconds() //0(未指定)
date.getTime() //1532236933000
date.getTimezoneOffset() //-120(取决于您所在位置和检查的时间 - 在夏季为CET)。返回表示时区差异的分钟数
这些方法都有等效的UTC版本,返回的是与您当前时区适应的值,而不是UTC值:
date.getUTCDate() //22
date.getUTCDay() //0(0表示星期天,1表示星期一..)
date.getUTCFullYear() //2018
date.getUTCMonth() //6(从0开始)
date.getUTCHours() //5(不是上面的7)
date.getUTCMinutes() //22
date.getUTCSeconds() //13
date.getUTCMilliseconds() //0(未指定)
编辑日期
日期对象提供了几种方法来编辑日期值:
const date = new Date('July 22, 2018 07:22:13')
date.setDate(newValue)
date.setFullYear(newValue) //注意:避免使用setYear(),它已被弃用
date.setMonth(newValue)
date.setHours(newValue)
date.setMinutes(newValue)
date.setSeconds(newValue)
date.setMilliseconds(newValue)
date.setTime(newValue)
setDate
和setMonth
从0开始计数,所以例如3月是第2个月。
例如:
const date = new Date('July 22, 2018 07:22:13')
date.setDate(23)
date // July 23, 2018 07:22:13
有趣的是,这些方法是“重叠”的,所以如果您设置了date.setHours(48)
,那么日期也会增加一天。
好知道的是,您可以向setHours()
添加多个参数,以同时设置分钟、秒和毫秒:setHours(0, 0, 0, 0)
- 对于setMinutes
和setSeconds
也是如此。
与get *方法类似,set *方法也有一个UTC等效方法,可以返回UTC值而不是适应您当前时区的值:
const date = new Date('July 22, 2018 07:22:13')
date.setUTCDate(newValue)
date.setUTCDay(newValue)
date.setUTCFullYear(newValue)
date.setUTCMonth(newValue)
date.setUTCHours(newValue)
date.setUTCMinutes(newValue)
date.setUTCSeconds(newValue)
date.setUTCMilliseconds(newValue)
获取当前时间戳
如果您想获取当前时间戳的毫秒数,您可以使用以下简写:
Date.now()
而不是:
new Date().getTime()
JavaScript会尽力工作
请注意。如果您超出一个月的天数,将没有错误,并且日期将进入下个月:
new Date(2018, 6, 40) //Thu Aug 09 2018 00:00:00 GMT+0200(中欧夏令时)
月份、小时、分钟、秒和毫秒也是如此。
根据区域设置格式化日期
国际化API在现代浏览器中得到了很好的支持(值得注意的是:UC浏览器是一个明显的例外),它允许您翻译日期。
这是由Intl对象公开的,它还有助于本地化数字、字符串和货币。
我们感兴趣的是Intl.DateTimeFormat()
。
下面是如何使用它。
根据计算机默认区域设置格式化日期:
// "12/22/2017"
const date = new Date('July 22, 2018 07:22:13')
new Intl.DateTimeFormat().format(date) //"22/07/2018" in my locale
根据不同的区域设置格式化日期:
new Intl.DateTimeFormat('en-US').format(date) //"7/22/2018"
Intl.DateTimeFormat
方法接受一个可选参数,允许您自定义输出。要同时显示小时、分钟和秒,可以使用以下方法:
const options = {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}
new Intl.DateTimeFormat('en-US', options).format(date) //"7/22/2018, 7:22:13 AM"
new Intl.DateTimeFormat('it-IT', options2).format(date) //"22/7/2018, 07:22:13"
比较两个日期
您可以使用Date.getTime()
计算两个日期之间的差异:
const date1 = new Date('July 10, 2018 07:22:13')
const date2 = new Date('July 22, 2018 07:22:13')
const diff = date2.getTime() - date1.getTime() //以毫秒为单位的差异
同样,您可以检查两个日期是否相等:
const date1 = new Date('July 10, 2018 07:22:13')
const date2 = new Date('July 10, 2018 07:22:13')
if (date2.getTime() === date1.getTime()) {
//日期相等
}
请记住getTime()
返回毫秒数,所以您需要考虑在比较中的时间。July 10, 2018 07:22:13
不等于新的July 10, 2018
。在这种情况下,您可以使用setHours(0, 0, 0, 0)
来重置时间。