关于JavaScript中的Date你须要知道的一切

Date 对象在 JavaScript 中是很是奇怪的,以致于咱们在处理时间和日期时,须要使用第三方库 date-fnsMoment 来处理。javascript

可是并非任什么时候候都须要引入这些库,若是你足够了解日期对象的话它其实很简单,在这篇文章中我将带你了解全部关于日期对象的信息。css

首先,先从时区开始。java

时区

世界上有几百个时区,但在 JavaScript 中,你只须要了解两个就行:当地时间和世界协调时(UTC)。git

当地时间:指你的计算机所在的时区 世界协调时:是最主要的世界时间标准,是最接近格林威治标准时间(GMT),默认状况下,Date 对象建立的都是当地时间,只有在指定 UTC 时它才会建立世界协调时。github

有了这个,就能够来谈论日期建立了。数组

建立日期

你能够经过 new Date() 来建立日期,它有四种使用方式:浏览器

  1. 日期字符串
  2. 日期参数
  3. 时间戳
  4. 无参数

1.日期字符串

new Date 传递一个日期字符串来建立工具

new Date('1988-03-21');
复制代码

在建立日期时,咱们倾向于这种日期字符串方法。由于这很天然符合咱们的默认习惯。若是你写成 21-03-1988,在 JavaScript 中它是无效的。ui

缘由是由于:spa

在世界上不一样的地方,对日期字符有不一样的理解,例如: 11-06-2019 你能够认为是 11th June, 2019 你也能够认为是 6th November 2019。若是不告诉你时间系统,根本没法得知到底该是哪一个。

JavaScript 中,若是你想使用日期字符串,就必须使用一种全世界通用的格式,其中的一种格式就是 ISO 8601 Extended format

// ISO 8601 Extended format
`YYYY-MM-DDTHH:mm:ss:sssZ`
复制代码

其中:

  • YYYY:4 位数的年份
  • MM:2 位数的月份(01-12)
  • DD:2 位数的日期(0-31)
  • -:日期分隔符
  • T:指示时间的开始
  • HH: 小时 (0 to 23)
  • mm: 分钟 (0 to 59)
  • ss: 秒数 (0 to 59)
  • sss: 毫秒 (0 to 999)
  • : :时间分隔符
  • Z:时区,有 Z 采用 UTC 时区,没有则是当地时区(仅限有时间的状况)

注意:原文中的 DD:2 位数的日期(0-31)有误,经求证 DD 应为 (01 to 31)可查看Date Time String Format

其中,小时、分钟、秒和毫秒是可选的。所以,若是想建立一个日期 2019年6月11日,你能够这么作:

new Date('2019-06-11')
复制代码

请注意,若是你用 console.log 打印出这个日期,会发现存在一个很大的问题。

若是此时你在 GMT 时区「以后」的地区,获得的是:6月10日。

若是此时你是在 GMT 时区「以前」的地区,你获得的是:6月11日。

出现这种现象的缘由是:当使用日期字符串时它会有一个特殊的行为:若是建立一个不指定时间的日期,它会以 UTC(世界协调时) 为时区。

因此若是你想建立本地时间,你须要加上 HHmm

new Date('2019-06-11T00:00')
复制代码

经过上面可以看出使用日期字符串时,可能会由于本地时间和世界协调时出现何难捕捉的错误。

因此推荐你不要使用日期字符串来建立日期

顺便说一下,MDN 也警告不要使用日期字符串方法,由于浏览器可能会以不一样的方式解析日期字符串。

若是要建立日期,请使用参数或时间戳。

2.参数

你最多能够传递 7 个参数来建立日期。

  • Year: 4 为数年份
  • Month: 月份 (0-11),默认值为 0
  • Day:天(1-31),默认值为 1
  • Hour:小时(0-23),默认值为 0
  • Minutes:分钟 (0-59),默认值为 0
  • Seconds:秒数(0-59),默认值为 0
  • Milliseconds: 毫秒数 (0-999),默认值为 0
// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
复制代码

由于它看起来复杂,致使不少开发人员都不常用此方法来建立日期,但事实上却很简单。

它的参数从左到右分别为:年,月,日,时,分,秒,毫秒。就是这么简单。

new Date(2017, 3, 22, 5, 23, 50)

// This date can be easily read if you follow the left-right formula.
// Year: 2017,
// Month: April (because month is zero-indexed)
// Date: 22
// Hours: 05
// Minutes: 23
// Seconds: 50
复制代码

惟一最大的问题就是月份的索引是从 0 开始的。如1月=== 0,2月=== 1,3月=== 2等等。

咱们不知道为何月份的索引是从 0 开始的,但确实如此,与其争论为何不从 1 开始,不如试着去接收,一旦你接收了这个事实,它就变得容易多了。

经过几个例子熟悉一下:

// 21st March 1988, 12am, Local Time.
new Date(1988, 2, 21)

// 25th December 2019, 8am, Local Time.
new Date(2019, 11, 25, 8)

// 6th November 2023, 2:20am, Local Time
new Date(2023, 10, 6, 2, 20)

// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
复制代码

你会发现使用参数建立的时间都是本地时间,这也是它的好处之一,不会像日期字符串那样会产生不一样的结果。

若是你想建立UTC(世界协调时)的话,能够这么作:

// 11th June 2019, 12am, UTC.
new Date(Date.UTC(2019, 5, 11))
复制代码

3.时间戳

在 JavaScript 中,时间戳是指自1970年1月1日到如今的毫秒数。据个人经验不多有人用它来建立日期,由于这个数字每每大的惊人,很很差计算。更多的是使用它来比较两个日期的大小。

// 11th June 2019, 8am (in my Local Time, Singapore)
new Date(1560211200000)
复制代码

4.无参数

若是建立不带有任何的参数,它会返回当前的日期(本地时间)

new Date()
复制代码

总结

  1. 你能够经过 new Date()来建立一个日期
  2. 有四种语法能够建立:
    • 日期字符串
    • 日期参数
    • 时间戳
    • 无参数
  3. 不推荐使用日期字符串,由于它会有不一样的结果。
  4. 最好的方式是使用参数方式建立,分别对应为:年,月,日,时,分,秒,毫秒
  5. 记住用参数建立时月份的索引从0开始。

接下来咱们来谈谈日期格式的转换。

格式化日期

在其余语言中会提供格式化工具来建立一个你想要的日期格式,例如:在 PHP 中你能够用 date("d M Y") 来建立一个像23 Jan 2019这种格式的。

可是在 JavaScript 中格式化日期并无简单的方法。原生 Date 对象提供了 7 种格式化的方法,可是这 7 种方法返回的都是一个特定的值,并没有使用价值。

const date = new Date(2019, 0, 23, 17, 23, 42)
复制代码
  1. toString:返回 Wed Jan 23 2019 17:23:42 GMT+0800 (中国标准时间)
  2. toDateString:Wed Jan 23 2019
  3. toLocaleString:返回 23/01/2019, 17:23:42
  4. toLocaleDateString:23/01/2019
  5. toGMTString:Wed, 23 Jan 2019 09:23:42 GMT
  6. toUTCString:Wed, 23 Jan 2019 09:23:42 GMT
  7. toISOString:2019-01-23T09:23:42.079Z

若是想要一个自定义的值,此时就须要本身动手实现。

自定义格式

好比你想要一个像 Thu, 23 January 2019这种日期,你须要用到下面四种方法:

  1. getFullYear:根据当地时间获取4位数的年份
  2. getMonth:根据当地时间获取一年中的月份(0-11)。月份是零索引的
  3. getDate:根据当地时间获取一个月中的某一天(1-31)
  4. getDay:根据当地时间获取一周中的某一天(0-6)。一周中的一天从星期日(0)开始,到星期六(6)结束。

获取年份和日期很是简单,直接使用 getFullYeargetDate便可。

const d = new Date(2019, 0, 23)
const year = d.getFullYear() // 2019
const date = d.getDate() // 23
复制代码

难的是获取ThuJanuary

想要获取January能够建立一个对象,而后让十二个月的值映射到各自的名称上。

const months = {
  0: 'January',
  1: 'February',
  2: 'March',
  3: 'April',
  4: 'May',
  5: 'June',
  6: 'July',
  7: 'August',
  8: 'September',
  9: 'October',
  10: 'November',
  11: 'December'
}
复制代码

由于月份的索引是从 0 开始的,因此咱们可使用数组来代替对象,其结果是同样的。

const months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
]
复制代码

获取January,你须要:

  1. 使用 getMonth获取到索引
  2. 从 months 获取到名称。
const monthIndex = d.getMonth()
const monthName = months[monthIndex]
console.log(monthName) // January
复制代码

可合并为

const monthName = months(d.getMonth())
console.log(monthName) // January
复制代码

一样的你能够用相同的方式来获取到 Thu

const days = [
  'Sun',
  'Mon',
  'Tue',
  'Wed',
  'Thu',
  'Fri',
  'Sat'
]
复制代码

而后:

  1. 使用 getDay 获取索引
  2. 从 days 获取到名称。
const dayName = days[d.getDay()] // Thu
复制代码

至此,咱们把上面的字符所有链接起来,就能够获得想要的结果。

const formatted = `${dayName}, ${date} ${monthName} ${year}`
console.log(formatted) // Thu, 23 January 2019
复制代码

若是想建立自定义时间格式,能够用下面几个方法:

  • getHours:根据当地时间获取小时数(0-23)。
  • getMinutes: 根据当地时间获取分钟数(0-59)。
  • getSeconds: 根据当地时间获取秒(0-59)。
  • getMilliseconds: 根据本地时间获取毫秒(0-999)。

接下来,咱们来继续谈日期的比较。

日期比较

若是想比较两个日期的大小,可直接使用比较符 >、<、>=、<= 。

const earlier = new Date(2019, 0, 26)
const later = new Date(2019, 0, 27)

console.log(earlier < later) // true
复制代码

但若是你想比较两个日期是否相等,此时使用 == 或 === 却无能为力了。

const a = new Date(2019, 0, 26)
const b = new Date(2019, 0, 26)

console.log(a == b) // false
console.log(a === b) // false
复制代码

想要比较两个日期是否相等,可使用 getTime 来获取时间戳来进行比较。

const isSameTime = (a, b) => {
  return a.getTime() === b.getTime()
}

const a = new Date(2019, 0, 26)
const b = new Date(2019, 0, 26)
console.log(isSameTime(a, b)) // true
复制代码

若是想检查两个日期是否在同一天,能够检查它们的 getFullYear、getMonth 和 getDate 的值。

const isSameDay = (a, b) => {
  return a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate()=== b.getDate()
}

const a = new Date(2019, 0, 26, 10) // 26 Jan 2019, 10am
const b = new Date(2019, 0, 26, 12) // 26 Jan 2019, 12pm
console.log(isSameDay(a, b)) // true
复制代码

最后咱们在谈一件事

计算日期

有两种可能的状况:

  1. 设置特定日期/时间
  2. 增长/减小日期

设定特定日期

你能够用如下方法设定日期:

  1. setFullYear:设置年份
  2. setMonth:设置月份
  3. setDate:设置天
  4. setHours:设置时
  5. setMinutes:设置分钟
  6. setSeconds:设置秒数
  7. setMilliseconds:设置毫秒数

例如能够将日期设置为 15号:

const d = new Date(2019, 0, 10)
d.setDate(15)

console.log(d) // 15 January 2019
复制代码

若是想将月份设置为 6 月,能够用 setMonth (月的索引要从 0 开始)

const d = new Date(2019, 0, 10)
d.setMonth(5)

console.log(d) // 10 June 2019
复制代码

注意:上面的方法咱们都修改了原始的对象,实际上咱们不该该这么改变对象为何在这里,应该建立一个新的对象进行操做。

const d = new Date(2019, 0, 10)
const newDate = new Date(d)
newDate.setMonth(5)

console.log(d) // 10 January 2019
console.log(newDate) // 10 June 2019
复制代码

增长/减小 日期

想要计算改变后的日期,首先你须要获取到它们:

  1. getFullYear:根据当地时间获取4位数的年份
  2. getMonth:根据当地时间获取一年中的月份(0-11)。月份是零索引的
  3. getDate:根据当地时间获取一个月中的某一天(1-31)
  4. getHours:根据当地时间获取小时数(0-23)。
  5. getMinutes: 根据当地时间获取分钟数(0-59)。
  6. getSeconds: 根据当地时间获取秒(0-59)。
  7. getMilliseconds: 根据本地时间获取毫秒(0-999)。

一般有两种方法实现日期的增长或减小。第一种:简介但难理解,第二种,冗长但好理解。

一块儿来看

假设如今是2019年3月28日,我想要获得三天后的日期。

第一种方法:

const today = new Date(2019, 2, 28)
const finalDate = new Date(today)
finalDate.setDate(today.getDate() + 3)

console.log(finalDate) // 31 March 2019
复制代码

第二种方法:

在这里,咱们使用getFullYear、getMonth、getDate 和其余getter方法,直到找到想要更改的值的类型。而后咱们用新日期建立最终日期。

const today = new Date(2019, 2, 28)

// Getting required values
const year = today.getFullYear()
const month = today.getMonh()
const day = today.getDate()

// Creating a new Date (with the delta)
const finalDate = new Date(year, month, day + 3)

console.log(finalDate) // 31 March 2019
复制代码

以上两种方式都是有效的,你能够选择一种去作。

自动修正

若是你提供的日期值超出了其可接受的范围,JavaScript 会自动从新计算日期。

好比:把日期定在2019年3月33日,在这种状况下,JavaScript会自动将3月33日调整到4月2日。

// 33rd March => 2nd April
new Date(2019, 2, 33)
复制代码

这意味着咱们不须要担忧计算分钟、小时、天、月等。 JavaScript 会自动帮助咱们处理。

// 33rd March => 2nd April
new Date(2019, 2, 30 + 3)
复制代码

到这里,有关于日期对象的全部东西你都已经了解啦。

原文:css-tricks.com/everything-…
翻译:六小登登
更多优质文章:六小登登的博客

我是一名爱写做的技术人。 关注公众号:六小登登,后台回复「1024」便可免费获取惊喜福利!后台回复「加群」群里天天都会全网搜罗好文章给你。

相关文章
相关标签/搜索