[译] JAVASCRIPT 日期权威指南

在 JavaScript 中使用日期是很复杂的。请试着学习全部特性并学会如何使用它。javascript

引言

在工做中使用日期是很是复杂的。不管开发人员的技术如何,都会感觉到至关痛苦。前端

JavaScript 经过一个强大的 Date 内建对象来提供处理日期的功能。java

这篇文章不会讨论 Moment.js 这个我认为是处理日期的最好的库,你应该在绝大多数场景下用它来处理日期。android

Date 对象

一个 Date 对象实例描述一个单一的时间点。ios

尽管其被命名为 Date,但其也操纵着 具体的时间(译者注:意为其也能够描述时分秒)。git

初始化一个 Date 对象

咱们经过如下方式初始化一个 Date 对象:github

new Date()
复制代码

这将会创造一个指向当前时刻的 Date 对象。后端

从内部来看,Date 对象是表示距离 1970 年 1 月 1 日(UTC)所过去的毫秒数。这一天(1970 年 1 月 1 日)是很是重要的,由于就计算机而言,这是一切开始的地方。浏览器

你可能比较熟悉 UNIX 时间戳:它表示距离众人皆知的那天(1970 年 1 月 1 日)所过去的秒数。bash

要点:UNIX 时间戳的结果是“秒”,JavaScript 的 Date 对象的结果是“毫秒”。

若是咱们有一个 UNIX 时间戳,咱们能够经过下面的方法类比出一个 JavaScript Date 对象:

const timestamp = 1530826365
new Date(timestamp * 1000)
复制代码

若是咱们传值为 0,咱们将会获得一个表示 1970年1月1日的 JavaScript Date 对象:

new Date(0)
复制代码

若是咱们传值一个字符串而不是数字,那么Date对象将会调用 parse 去肯定你想传入的日期。例如:

new Date('2018-07-22')
new Date('2018-07') //July 1st 2018, 00:00:00
new Date('2018') //Jan 1st 2018, 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') //Mar 1st 2018, 00:00:00
new Date('2018 March') //Mar 1st 2018, 00:00:00
new Date('2018 MARCH') //Mar 1st 2018, 00:00:00
new Date('2018 march') //Mar 1st 2018, 00:00:00
复制代码

这个方法很是灵活。你能够在月份或者日期字段添加或省略前导零。

当心月份/日期的位置,否则你或许会将月份错当作是日期。

你也可使用 Date.parse 方法:

Date.parse('2018-07-22')
Date.parse('2018-07') //July 1st 2018, 00:00:00(译者注:此处的结果为一个时间戳数字,该数字表明 July 1st 2018, 00:00:00 时刻)
Date.parse('2018') //Jan 1st 2018, 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 方法将会返回一个时间戳(以毫秒计)而不是 Date 对象。

你也能够经过设置一串有序的表示以一个日期的各个部分的数值来建立一个 Date 对象:年份,月份(从 0 开始),日期,小时,分钟,秒数和毫秒数:

new Date(2018, 6, 22, 7, 22, 13, 0)
new Date(2018, 6, 22)
复制代码

这个方法最少须要三个参数,可是大多数 JavaScript 引擎也能够解析更少参数的状况:

new Date(2018, 6) //Sun Jul 01 2018 00:00:00 GMT+0200 (Central European Summer Time)
new Date(2018) //Thu Jan 01 1970 01:00:02 GMT+0100 (Central European Standard Time)
复制代码

在上述所用的状况下,所生成的 Date 都是与你如今所在的时区相关联的。这意味着 两个不一样的电脑可能将同一个 Date 对象实例解释成不一样的值。

JavaScript 在没有找到任何关于时区的信息时,会把时区设置成 UTC,同时也会自动地(对非当前时区的 Date 对象)进行到当前计算机时区的转换。

总结一下,你能够经过四种方式来建立一个 Date 对象:

  • 不传任何参数 ,这将建立一个指向“当前时刻”的 Date 对象
  • 传递 一个数字,该参数将表示建立的 Date 对象距离 1970 年 1 月 1 日 00:00(GMT)所过去的毫秒数
  • 传递 一个字符串,该字符串应该是一个描述日期的字符串
  • 传递 一串参数,这些参数会分别描述一个 Date 对象的某一部分

时区

当你初始化一个 Date 对象时能够选择时区,这样作的话 Date 对象不会是默认的 UTC 时区,同时也会覆盖你所在的时区。

你能够经过添加 +HOURS 的格式,或者经过一个被圆括号包裹的时区名来描述一个时区:

new Date('July 22, 2018 07:22:13 +0700')
new Date('July 22, 2018 07:22:13 (CET)')
复制代码

若是你使用时区名的方式但在圆括号中定义了一个错误的时区名,JavaScript 将会静默地将时区设置为默认的 UTC。

若是你使用 +HOURS 的方式但传入的数字格式是错误的,JavaScript 将会抛出一个 “Invalid Date” 的 Error。

Date 转换及格式化

给定一个 Date 对象,会有许多种能够生成与该时间相关的字符串的方式。

const date = new Date('July 22, 2018 07:22:13')

date.toString() // "Sun Jul 22 2018 07:22:13 GMT+0200 (Central European Summer Time)"
date.toTimeString() //"07:22:13 GMT+0200 (Central European Summer Time)"
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 format)
date.toLocaleString() //"22/07/2018, 07:22:13"
date.toLocaleTimeString()	//"07:22:13"
date.getTime() //1532236933000
date.getTime() //1532236933000
复制代码

Date 对象的 get(获取)方法

一个 Date 对象会提供以下方法去查看它的值。这些值会取决于你计算机所处的时区。

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 对象建立时指定毫秒值,JavaScript 默认将毫秒数设置为 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(未标明)
复制代码

修改 Date

一个 Date 对象提供如下修改 Date 值的方法:

const date = new Date('July 22, 2018 07:22:13')

date.setDate(newValue)
date.setDay(newValue)
date.setFullYear(newValue) //note:不要使用 setYear(),它已经被废弃了
date.setMonth(newValue)
date.setHours(newValue)
date.setMinutes(newValue)
date.setSeconds(newValue)
date.setMilliseconds(newValue)
date.setTime(newValue)
date.setTimezoneOffset(newValue)
复制代码

setDaysetMonth 的取值范围从 0 开始,举个例子,三月的值为 2。

一个有趣的事实是:这些方法是互相重合的,举个例子,若是你运行 date.setHours(48),这也会将日期数变大。

很棒的知识点:你能够对 setHours() 添加超过一个参数来设置分钟,秒钟和毫秒:setHours(0, 0, 0, 0) ——这也适用于 setMinutessetSeconds。(译者注:即 setMinutes 能够设置分钟,秒和毫秒,setSeconds 能够设置秒和毫秒)

和 get(获取)方法同样,set(修改)方法也有相同的 UTC 版本:

const date = new Date('July 22, 2018 07:22:13')

date.setUTCDate(newalue)
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 费尽心思让代码工做正常

请注意。若是你定义的日期天数超过了一个月,这将不会报错,同时 Date 对象将会指向下一个月:

new Date(2018, 6, 40) //Thu Aug 09 2018 00:00:00 GMT+0200 (Central European Summer Time)
复制代码

这对月份,小时,分钟,秒钟,毫秒一样有效。

基于你的地点来格式化 Date

全球化的API,在现代化的浏览器中被很好地支持(值得注意的例外:UC 浏览器),而这容许你去转化(世界各地的)日期。

这些方法由 Intl 项目公布,它同时也帮助咱们本地化数字,字符串和货币。

咱们对 Intl.DateTimeFormat() 很是有兴趣。

这里说的是如何使用它:

按照电脑所在地区来格式化一个 Date 对象:

// "12/22/2017"
const date = new Date('July 22, 2018 07:22:13')
new Intl.DateTimeFormat().format(date) //"22/07/2018" 是我所在地区的格式
复制代码

按照不一样地区来格式化一个 Date 对象:

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

你能够经过 Date.getTime() 的值来比较两个 Date 对象:

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() //以毫秒计的差距
复制代码

一样的方法,你也能够去检查两个 Date 对象是否相等:

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) 来重置当日时刻。

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。

掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索