插播一个新系列:时间库 dayjs
的源码解析。
用官方的描述 “Day.js
是 Moment.js
的 2kB 轻量化方案,拥有同样强大的 API
”。优点是如下三个:
- 简易:
Day.js
是一个轻量的处理时间和日期的JavaScript
库,和Moment.js
的API
设计保持完全一样。 - 不可变:所有的
API
操作都将返回一个新的Dayjs
实例。这种设计能避免bug
产生,节约调试时间。 - 国际化:
Day.js
对国际化支持良好。但除非手动加载,多国语言默认是不会被打包到工程里的。
总的来说,dayjs
的优点就是 plugin
和 locale
手动按需加载,减少打包体积。
dayjs
是饿了么的大佬 iamkun 开发维护的,大佬同时也是 ElementUI
的开发者。解析之前先从dayjs 源代码仓库 fork
了一份:github.com/MageeLin/da… 。
时间是 2020 年 12 月 7 日,commitID
是 eb5fbc4c
。解析时从 master
分支拉了一个新分支 analysis
。
打算分五章完成,目录如下:
- dayjs 源码解析(一):概念、locale、constant、utils
- dayjs 源码解析(二):Dayjs 类
- dayjs 源码解析(三):插件(上)
- dayjs 源码解析(四):插件(中)
- dayjs 源码解析(五):插件(下)
代码结构
目录结构
源代码的目录结构如下所示:
依赖结构
入口 src/index.js
的依赖如下所示:
可以发现依赖链特别简单,没有依赖到 locale
和 plugin
目录下的语言包和插件。这也就是 dayjs
的核心优点。
基础概念
在分析源码之前,先理解下一些相关的基础概念。
时间标准
几种时间标准的解释来自维基百科。
GMT
格林尼治平均时间(Greenwich Mean Time,GMT
)是指位于英国伦敦郊区的皇家格林尼治天文台当地的平太阳时,因为本初子午线被定义为通过那里的经线。
自 1924 年 2 月 5 日开始,格林尼治天文台负责每隔一小时向全世界发放调时信息。
格林尼治标准时间的正午是指当平太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。由于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治平时基于天文观测本身的缺陷,已经被原子钟报时的协调世界时(UTC
)所取代。
UTC
协调世界时(英语:Coordinated Universal Time
,法语:Temps Universel Coordonné
,简称 UTC
)是最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林威治标准时间。
协调世界时是世界上调节时钟和时间的主要时间标准,它与 0
度经线的平太阳时相差不超过 1
秒,并不遵守夏令时。
现行的协调世界时根据国际电信联盟的建议《Standard-frequency and time-signal emissions》(ITU-R TF.460-6)所确定。UTC
基于国际原子时,并在必要时通过不规则的加入闰秒来抵消地球自转变慢的影响。
如果本地时间比 UTC
时间快,例如中国、蒙古、菲律宾、新加坡、马来西亚、澳大利亚西部的时间比 UTC
快 8
小时,就会写作 UTC+8
,俗称东八区
。相反,如果本地时间比 UTC
时间慢,例如夏威夷的时间比 UTC
时间慢 10
小时,就会写作 UTC-10
,俗称西十区
。
ISO
国际标准 ISO 8601,是国际标准化组织的日期和时间的表示
方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》。目前是 2004 年 12 月 1 日发行的第三版“ISO8601:2004”
在 Javascript 中的 Date.prototype.toISOString()
中,返回的是 YYYY-MM-DDTHH:mm:ss.sssZ
格式的字符串,时区总是 UTC(协调世界时),加一个后缀“Z”标识。
Date 对象输出时间的格式
Javascript 的 Date.prototype 上有很多种方式可以输出时间,以时间戳 1607561462990
为例,在 Chrome87 中返回值如下表:
方法 | 格式 | 输出 | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
valueOf | 时间戳 | 1607561462990 | getTime | GMT 时间戳 | 1607561462990 | toString | 英语格式的本地时间字符串 | Thu Dec 10 2020 08:51:02 GMT+0800 (中国标准时间) | toUTCString | 英语格式的 UTC 时间字符串 | Thu, 10 Dec 2020 00:51:02 GMT | toGMTString(标准已废弃) | 英语格式的 GMT 时间字符串 | Thu, 10 Dec 2020 00:51:02 GMT | toISOString | ISO 格式的 UTC 时间字符串 | 2020-12-10T00:51:02.990Z | toLocaleString | 字符串格式因不同语言而不同 | 2020/12/10 上午 8:51:02 | toJSON | 与 toISOString 相同 | 2020-12-10T00:51:02.990Z |
语言(文化)代码
不同语言对事物的描述方式肯定不同,即使同一种语言由于文化地区差异,对相同事物的描述也有区别,所以国际上就形成了一套标准来识别各种语言。
先放一篇 Hax 的回答和 BCP47 规范,对于汉语代码来说,按照标准应该使用 zh-cmn-Hans-CN
、zh-cmn-Hant-HK
、zh-cmn-Hans-SG
、zh-cmn-Hant-TW
。但是由于历史的原因,广泛应用的是zh-CN
、zh-HK
、zh-SG
、zh-TW
。
引用一个通用的语言列表:
locale
对于 day.js
来说,同样也是实现了很多种语言的国际化,都放置在 src/locale
目录下,跟语言代码稍微有点不同的就是命名全部小写。
由于 day.js
是按需加载的,所以在使用某种语言前需要提前引入:
其实 dayjs/locale/xxx.js
种保存的是对应语言的各种模板和配置,以 zh-cn.js
为例:
除了配置以外,可以发现,最后两步中首先把 locale
对象加载并保存,然后把 locale
对象默认导出。所以虽然官方没明说,但是也可以如下导入:
constant
src/constant.js
中存放的是一些常量和正则表达式。包括不同单位包含的秒数和毫秒数、标准的时间单位表达、默认格式化模板、无效时间和两个正则表达式。
这两个正则表达式比较有意思,第一个正则表达式 REGEX_PARSE
是用来解析字符串格式的时间,便于生成 Dayjs
实例关联的 Date
对象;第二个正则表达式 REGEX_FORMAT
用于解析 format
参数,返回想要的时间格式。
utils
src/utils.js
中存放的是一些工具函数。其实在 index.js
中也放置了很多工具函数,只不过那些工具函数需要用到一些 index.js
的全局变量,所以不能定义在 utils.js
中。但是在 index.js
中最后还是把它们放在了一个 Utils
对象里共同管理。
本篇内容完成,下一篇文章来分析 day.js
的核心 src/index.js
文件,学习 Dayjs
类的实现。
前端记事本,不定期更新,欢迎关注!
- 微信公众号: 林景宜的记事本
- 博客:林景宜的记事本
- 掘金专栏:林景宜的记事本
- 知乎专栏: 林景宜的记事本
- Github: MageeLin
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!