须要知道的JS的日期知识,都在这了

为了保证的可读性,本文采用意译而非直译。前端

想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!git

JS中的 Date 很奇怪。当咱们须要处理日期和时间的时候比较麻烦,常常借助像date-fnsMoment 这样的库。github

可是咱们并不老是须要使用库。若是知道要注意一些老是,日期实际上能够很是简单。接下介绍有关Date对象的全部信息编程

时区

咱们的世界有数百个时区。 在JavaScript中,咱们只关心两个, 本地时间协调世界时(UTC)。数组

  • 本地时间是指你的计算机所在的时区。
  • UTC其实是格林威治标准时间(GMT)的同义词

默认状况下,JS中的几乎每一个日期方法(除了一个)都是本地时间。 只有指定UTC,才能得到 UTC 时间 。编程语言

建立日期

可使用 new Date() 来建立日期,传入的参数一般有4种经常使用的方式:工具

  1. 使用日期字符串参数
  2. 使用一系列的参数
  3. 时间戳参数
  4. 不带参数

使用日期字符串参数

new Date('1988-03-21')

这种方式方便且直观。学习

若是如今写的是21-03-1988,咱们能够绝不费力想表达的是1988年3月21日。可是若是用JS 编写21-03-1988,则会获得无效的日期。ui

clipboard.png

这是有缘由的。spa

在世界的不一样地方以不一样的方式解释日期字符串。 例如11-06-20192019年6月11日仍是 2019年11月6日。你不能肯定我指的是哪个,除非你知道我正在使用的日期系统。

在JS中,若是要使用日期字符串参数,则须要使用全球都能接受的格式,其中一种格式是ISO 8601扩展格式

// ISO 8601 Extended format
`YYYY-MM-DDTHH:mm:ss:sssZ`
  • YYYY:4位数年份
  • MM:两位数月份(即 1月为01,12月为12)
  • DD:两位数的日期(0到31)
  • -:日期分隔符
  • T:表示开始时间
  • HH:24位小时数(0到23)
  • mm:分钟(0到59)
  • ss:秒(0到59)
  • sss:毫秒(0到999)
  • ::时间分隔符
  • Z:若是存在Z,则日期将设置为UTC,若是Z不存在,则为本地时间。

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

new Date('2019-06-11')

在这里要特别注意,使用日期字符串参数建立日期存在很大问题,把建立的日期打印出来就能够发现问题。

若是你住在格林威治标准时间(GMT)晚的的地区,你会获得一个日期是6月10日

clipboard.png

若是你住在比格林威治标准时间早的地区,才会等获得6月11日的日期。

clipboard.png

发生这种状况是由于日期字符串参数的方法具备特殊行为:若是建立日期(未指定时间),则会得到UTC格式设置的日期。

在上面的场景中,使用new Date('2019-06-11') 建立日期时,实际上建立的日期是2019年6月11日,UTC时间上午12点。这就是为何住在格林尼治标准时间以后的地区的人获得的是6月10日而不是6月11日

若是要使用日期字符串参数方法在“本地时间”中建立日期,则须要包括时间。若是包含时间,则须要至少写入HHmm

new Date('2019-06-11T00:00')

clipboard.png

使用日期字符串参数的建立的本地时间与UTC的比较多是一个难以捕捉的错误。因此,建议不要使用日期字符串建立日期方式。

格林威治标准时间GMT
十七世纪,格林威治皇家天文台为了海上霸权的扩张计画而进行天体观测。1675年旧皇家观测所(Old Royal Observatory) 正式成立,到了1884年决定以经过格林威治的子午线做为划分地球东西两半球的经度零度。观测所门口墙上有一个标志24小时的时钟,显示当下的时间,对全球而言,这里所设定的时间是世界时间参考点,全球都以格林威治的时间做为标准来设定时间,这就是咱们耳熟能详的「格林威治标准时间(Greenwich Mean Time,简称G.M.T.)的由来,标示在手表上,则表明此表具备两地时间功能,也就是同时能够显示原居地和另外一个国度的时间。

世界协调时间UTC
多数的两地时间表都以GMT来表示,但也有些两地时间表上看不到GMT字样,出现的反而是UTC这3个英文字母,究竟何谓UTC?事实上,UTC指的是Coordinated Universal Time- 世界协调时间(又称世界标准时间、世界统一时间),是通过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程至关严谨精密,所以若以「世界标准时间」的角度来讲,UTC比GMT来得更加精准。其偏差值必须保持在0.9秒之内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。因此基本上UTC的本质强调的是比GMT更为精确的世界时间标准,不过对于现行表款来讲,GMT与UTC的功能与精确度是没有差异的。

使用一系列的参数建立

最多能够传入七个参数来建立日期/时间。

  1. Year:4位数年份
  2. Month:一年中的某月(0-11)
  3. Day:每个月的某天(1-31),若是省略,则默认为1。
  4. Hour:一天中的小时(0-23),若是省略,则默认为0。
  5. Minutes:分钟(0-59),若是省略,则默认为0。
  6. Seconds:秒(0-59),若是省略,则默认为0。
  7. Milliseconds:毫秒(0-999),若是省略,则默认为0。
// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)

许多开发人员比较少用这种方式,由于它看起来很复杂,但它实际上很是简单。能够从左到右记忆:年、月、日、小时、分钟、秒和毫秒。

Date 中须要注意的地方Month是从0开始的,如1月=== 0,2月=== 1,3月=== 2,依此类推。

再来一些事件熟悉一下多个参数的用法

// 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之间混淆,若是须要UTC时间,请以这种方式建立UTC 日期:

// 11th June 2019, 12am, UTC.
new Date(Date.UTC(2019, 5, 11))

使用时间戳来建立日期

在JS中,时间戳是自1970年1月1日以来通过的毫秒数(1970年1月1日也称为Unix纪元时间)。 根据个人经验,不多使用时间戳来建立日期,通常使用时间戳来比较不一样的日期或者格式化日期,后面在讨论。

不带参数的形式建立日期

若是建立没有任何参数的日期,则会将日期设置为当前时间(以本地时间为单位)。

new Date()

clipboard.png

小结一波

  1. 使用 new Date() 建立日期
  2. 有四种可能的语法:

    • 使用字符串日期值
    • 使用一系列参数
    • 使用时间戳
    • 不带参数
  3. 最好不要使用字符串日期值的方法建立日期
  4. 最好使用一系列参数方式建立日期
  5. 记住月份是从0开始的

格式化日期

多数编程语言都提供了一种格式工具来创您想要的任何日期格式 例如,在PHP中,能够将date("d M Y")格式化成23 1月 2019这样的日期。

可是在JS 中格式化日期并不容易。

原生 Date 对象提供了七种格式化方法,这七种方法中的每一种都会给你一个特定的价值,并且它们毫无用处。

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:格式化成 "2019/1/23 下午5:23:42"
  4. toLocaleDateString:格式化成 "2019/1/23"
  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.000Z"

若是须要自定义格式,则要本身建立。

编写自定义日期格式

假设想要 2019年1月23日 星期四这样的日期格式。须要知道 Date对象日期方法。

要获取这样的格式,用到 Date 中的四个方法:

  1. getFullYear:获取当地时间4位数的年份
  2. getMonth:获取当时时间的月份,注意从 0 开始
  3. getDate:获取当地时间月中的某一天(1-31)
  4. getDay:获取当地时间的星期几(0-6),星期日(0)开始,到星期六(6)结束。
const d = new Date(2019, 0, 23)
const year = d.getFullYear() // 2019
const date = d.getDate() // 23

由于星期和月份是从0开始的,因此咱们能够建立一个映射表:

const months = {
  0: '1月',
  1: '2月',
  2: '3月',
  3: '4月',
  4: '5月',
  5: '6月',
  6: '7月',
  7: '8月',
  8: '9月',
  9: '10月',
  10: '11月',
  11: '12月'
}

因为月份是0开始的的,咱们可使用数组代替对象,结果同样:

const months = [
  '1月',
  '2月',
  '3月',
  '4月',
  '5月',
  '6月',
  '7月',
  '8月',
  '9月',
  '10月',
  '11月',
  '12月'
}

要获得1月份,你须要

const monthIndex = d.getMonth()
const monthName = months[monthIndex]
console.log(monthName) // 1月

简化一下:

const monthName = months(d.getMonth())
console.log(monthName) // 1月

为了获取 星期四,还须要 作一样的事情:

const days = [
  '星期日',
  '星期一',
  '星期二',
  '星期三',
  '星期四',
  '星期五',
  '星期六'
]

获取方式:

const dayName = days[d.getDay()] // 星期四

接着就产拼接起来。这是相对乏味的。

若是须要建立自定义格式的时间,可使用如下方法

  1. getHours:获取当地时间获取小时数(0-23)。
  2. getMinutes:获取本地时间获取分钟(0-59)。
  3. getSeconds:获取本地时间获取秒数(0-59)。
  4. 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

若是只想检查两个日期是否在同一天,能够比较他们的getFullYeargetMonthgetDate值。

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. setNubytes:设置分
  6. setSeconds:设置秒
  7. setMilliseconds:设置毫秒

例如,若是想将日期设置为每个月15日,可使用setDate(15)

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

console.log(d) // 15 January 2019
注意:上面的 setter方法会改变原始日期对象。 在实际中,咱们不该该改变对象,应该在新的日期对象上执行这些操做。
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

从另外一个日期添加/减去增量

添加/减去增量有两种通用方法。 第一种方法在Stack Overflow上更受欢迎,它简洁,但更难掌握。 第二种方法更冗长,但更容易理解。

假设但愿得到从今天起三天的日期。 对于这个例子,假设今天是2019年3月28日

第一种方法

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

首先,咱们建立一个新的Date对象,这样就不会改变原始日期

const finalDate = new Date(today)

接下来,咱们须要知道要更改的值。由于咱们要改变日期,因此咱们能够用getDate得到日期

const currentDate = today.getDate()

由于获取三天后的日期,因此须要在获得的日期加3

setDate(currentDate + 3)

完整代码:

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

console.log(finalDate) // 31 March 2019

第二种方法

使用getFullYeargetMonthgetDate方法,更改对应的值, 而后,咱们使用new Date建立最终日期。

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

自动日期校订

若是为Date提供一个超出其可接受范围的值,JS 将自动从新计算日期。

以下所示,假设咱们把日期定在2019年3月33日,日历上没有33日,JS 会自动将3月33日调整为4月2日

clipboard.png

这意味着在建立增量时无需担忧计算分钟,小时,天,月等,JavaScript会自动处理。

clipboard.png

代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

交流

干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。

https://github.com/qq44924588...

我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,便可看到福利,你懂的。

clipboard.png

相关文章
相关标签/搜索