JavaScript 时间与日期处理实战:你确定被坑过

2020年06月23日 阅读数:84
这篇文章主要向大家介绍JavaScript 时间与日期处理实战:你确定被坑过,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

转载自:http://web.jobbole.com/89120/javascript

本部分的知识图谱请参考编程语言知识图谱-时间与日期
83517123-5835b547b3165_articlexcss

本文JavaScript 时间与日期处理实战:你确定被坑过从属于笔者的Web 前端入门与最佳实践中 JavaScript 入门与最佳实践系列文章。html

JavaScript DateTime

标准时间

GMT即「格林威治标准时间」(Greenwich Mean Time,简称G.M.T.),指位于英国伦敦郊区的皇家格林威治天文台的标准时间,由于本初子午线被定义为经过那里的经线。然而因为地球的不规则自转,致使GMT时间有偏差,所以目前已不被看成标准时间使用。UTC是最主要的世界时间标准,是通过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间。UTC比GMT来得更加精准。其偏差值必须保持在0.9秒之内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。不过平常使用中,GMT与UTC的功能与精确度是没有差异的。协调世界时区会使用“Z”来表示。而在航空上,全部使用的时间划一规定是协调世界时。并且Z在无线电中应读做“Zulu”(可参见北约音标字母),协调世界时也会被称为“Zulu time”。前端

TimeZone&UTC Offsets:时区与偏移

人们常常会把时区与UTC偏移量搞混,UTC偏移量表明了某个具体的时间值与UTC时间之间的差别,一般用HH:mm形式表述。而TimeZone则表示某个地理区域,某个TimeZone中每每会包含多个偏移量,而多个时区可能在一年的某些时间有相同的偏移量。譬如America/Chicago, America/Denver, 以及 America/Belize在一年中不一样的时间都会包含 -06:00 这个偏移。java

时间戳

Unix时间戳表示当前时间到1970年1月1日00:00:00 UTC对应的秒数。注意,JavaScript内的时间戳指的是当前时间到1970年1月1日00:00:00 UTC对应的毫秒数,和unix时间戳不是一个概念,后者表示秒数,差了1000倍。git

时间数字字符串格式

RFC2822

ISO 8601

国际标准化组织的国际标准ISO 8601是日期和时间的表示方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》。目前最新为第三版ISO8601:2004,初版为ISO8601:1988,第二版为ISO8601:2000。年由4位数组成,以公历公元1年为0001年,以公元前1年为0000年,公元前2年为-0001年,其余以此类推。应用其余纪年法要换算成公历,但若是发送和接受信息的双方有共同一致赞成的其余纪年法,能够自行应用。github

Reference

Date

JavaScript为咱们提供了不是很好用的Date对象做为时间日期对象,Date()直接返回当前时间字符串,无论参数是number仍是任何string。而new Date()则是会根据参数来返回对应的值,无参数的时候,返回当前时间的字符串形式;有参数的时候返回参数所对应时间的字符串。new Date()对参数不论是格式仍是内容都要求,且只返回字符串,标准的构造Date对象的方法有:web

这里须要注意的是,月份month参数,其计数方式从0开始,而天day参数,其计数方式从1开始chrome

Parse:解析

TimeStamp:时间戳

若是须要从当前的时间对象获取其相应的时间戳,咱们可使用getTime或者valueOf(),返回距离1970年1月1日0点的毫秒数:npm

另外Date对象还有一个静态方法一样返回给定日期的毫秒数。但其参数并非一个字符串,而是分别表明年、月、日、时、分、秒、毫秒的数字参数:

仍是须要强调下,JavaScript内的时间戳指的是当前时间到1970年1月1日00:00:00 UTC对应的毫秒数,和unix时间戳不是一个概念,后者表示秒数,差了1000倍。new Date(timestamp)中的时间戳必须是number格式,string会返回Invalid Date。因此好比new Date('11111111')这种写法是错的。

DateTimeString:时间日期字符串

JavaScript原生Date对于时间字符串的解析真的是槽点满满,假设咱们但愿以DD/MM/YYYY的格式进行解析,那么它是没法识别的:

另外,在ES5的标准中,其对ISO 8601标准的字符串进行了一个神奇的断言:全部没有提供时区的字符串默认为标准时区。换言之,你会发现你解析出来的时间和你预期中的不同,并且它打印的时候是按照本地时区又进行了转换:

ES 2015标准中则是修复了该Bug,不过仍是会让人以为头大,毕竟你不知道你代码的最终运行环境会是ES5仍是ES6。Date对象也有一个parse方法,用于解析一个日期字符串,参数是一个包含待解析的日期和时间的字符串,返回从1970年1月1日0点到给定日期的毫秒数。该方法会根据日期时间字符串格式规则来解析字符串的格式,除了标准格式外,如下格式也支持。若是字符串没法识别,将返回NaN。

  • ‘月/日/年’ 如6/13/2004
  • ‘月 日,年’ 如January 12,2004或Jan 12,2004
  • ‘星期 月 日 年 时:分:秒 时区’ Tue May 25 2004 00:00:00 GMT-0700

在ECMAScript5中,若是使用标准的日期时间字符串格式规则的字符串中,数学前有前置0,则会解析为UTC时间,时间没有前置0,则会解析为本地时间。其余状况通常都会解析为本地时间

Manipulate:时间对象操做

Get&Set

Date对象提供了一系列get*方法,用来获取实例对象某个方面的值。具体的Get函数列表详见附录:

一样的,Date对象还提供了一系列的Set方法:

Add&Subtract

咱们能够巧用Set方法的特性,set*方法的参数都会自动折算。以setDate为例,若是参数超过当月的最大天数,则向下一个月顺延,若是参数是负数,表示从上个月的最后一天开始减去的天数。

Diff:计算差值

类型转换时,Date对象的实例若是转为数值,则等于对应的毫秒数;若是转为字符串,则等于对应的日期字符串。因此,两个日期对象进行减法运算,返回的就是它们间隔的毫秒数;进行加法运算,返回的就是链接后的两个字符串。

Display:时间展现

Format:格式化

Date对象提供了一系列的to*方法来支持从Date对象转化为字符串,具体的函数列表详见附录:

Durations:时长

i18n:国际化

浏览器获取当前用户所在的时区等信息只和系统的日期和时间设置里的时区以及时间有关。区域和语言设置影响的是浏览器默认时间函数(Date.prototype.toLocaleString等)显示的格式,不会对时区等有影响。Date有个Date.prototype.toLocaleString()方法能够将时间字符串返回用户本地字符串格式,这个方法还有两个子方法Date.prototype.toLocaleDateString和Date.prototype.toLocaleTimeString,这两个方法返回值分别表示日期和时间,加一块儿就是Date.prototype.toLocaleString的结果。这个方法的默认参数会对时间字符串作一次转换,将其转换成用户当前所在时区的时间,并按照对应的系统设置时间格式返回字符串结果。然而不一样浏览器对用户本地所使用的语言格式的判断依据是不一样的。

  • IE:获取系统当前的区域和语言-格式中设置的格式,依照其对应的格式来显示当前时间结果;IE浏览器实时查询该系统设置(即你在浏览器窗口打开后去更改系统设置也会引发返回格式变化)。假设系统语言为 ja-JP,系统unicode语言为zh-CN日期格式为nl-NL,浏览器语言设置(accept-language)为de,浏览器界面语言为en-US(其余条件不变,浏览器界面语言改成zh-CN的时候结果也是同样),
  • FF:获取方式和结果与IE浏览器相同,区别在于FF只会在浏览器进程第一次启动的时候获取一次系统设置,中间无论怎么系统设置怎么变化,FF都没法获取到当前系统设置。除非重启FF浏览器。当浏览器界面语言为zh-CN,accept-language首位为en-US的时候:
  • Chrome:获取方式和以上两个都不一样。chrome无视系统的区域和语言-格式格式,只依照本身浏览器的界面设置的菜单语言来处理。(好比英文界面则按系统’en-US’格式返回字符串,中文界面则按系统’zh-CN’格式返回结果)。当浏览器界面语言为zh-CN,accept-language首位为en-US的时候:

Calendar:日历操做

Moment.js

57395441-5835b4de3ac5e_articlex

Moment.js为JavaScript Date对象提供了封装与统一好的API接口,而且提供了更多的功能。首先须要了解的是,Moment提供的moment对象是可变的,即当咱们对该对象执行相似于增减或者设置的时候,其对象自己的值会发生变化,譬以下面这段代码:

而若是咱们不但愿改变原有的值,特别是在须要建立多个时间日期对象的时候,咱们能够利用clone方法:

笔者是习惯在Webpack中进行打包,相似于Node下的安装方式:

若是你须要引入某个语言包,那么能够用以下方式:

Parse

TimeStamp

DateTimeString

Manipulate

Get/Set

Add&Subtract

Comparison

Diff

Display

Format

Relative Format

Duration

i18n

附录

Date APIs

Date 对象用于处理日期和时间。其核心的方法以下列表所示:

方法 描述
Date() 返回当日的日期和时间。
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。