说说日期和时间格式
JackChou: 前端程序员,最近专注 webGis 开发,个人微信:MasonChou123, 欢迎交流,加我进技术交流群。
开发中尤其是接口交互时,经常会遇到后端给出奇奇怪怪的日期格式,偶尔造成误解,代码解析时非常容易错误,所以了解日期格式规范和在项目中统一使用一种日期格式是非常有必要的,能极大降低沟通成本和降低时间格式导致的 bug。
常用的日期时间规范有 ISO 8601
和 RFC 3339
,都介绍他们,最后比较一下他们的优缺点。
相同的团队或者同一个项目,把日期格式都统一成某种格式,能有效避免误解和某些解析 bug,给协作极大方便。
ISO 8601
ISO-8601 是国际标准化组织(ISO)制定的日期和时间的表示方法,全称是《数据存储和交换形式-信息交换-日期和时间的表示》。最新版本是 2024 年发布的 ISO 8601:2019, 已经发布过的有 ISO 8601:2004、ISO 8601:2000、ISO 8601:1988。
基本原则
按照从大到小的顺序排列,年、月、日、时、分、秒,这里利于排序和比较。
每个时间位数固定,不足的用左补0,年份是4位,月份、日期、小时、分钟、秒数是2位,毫秒是3位,
+hh:mm
和=hh:mm
表示相对于零时区的时间偏移,-
表示西时区,+
表示东时区,T
分隔日期和时间,.
后是毫秒。
整时区,
:mm
可省略,hh
、mm
都必须是两位数,没有提供时区,通常认为是系统或者用户所在时区。
比如 -06:00
西6时区,+08
东8时区,+03:45
尼泊尔的时区,+05:30
印度的时区。
2019-06-11T14:00:00 # 2019年6月11日14点
2019-06-11T14:00:00.109 # 2019年6月11日14点0分0秒109毫秒
2019-06-11T14:00:00+08:00 # 2019年6月11日14点东8时区
两个基本格式
只有数字、 T
、 +
和 -
,没有其他字符。
19850412T101530+04 # 1985年4月12日10点15分30秒东4时区
这种可读性差,容易误解。
含有 -
、 :
、 .
、 +
和 T
。
-
用于分隔年月日, :
用于分隔时分秒, .
用于分隔秒和毫秒, +
和 -
用于表示时区, T
用于分隔日期和时间。
2020-12-18T08:24:35 # 2020年12月18日8点24分35秒
2020-12-18T08:24:35.109 # 2020年12月18日8点24分35秒109毫秒
2020-12-18T08:24:35+08:00 # 2020年12月18日8点24分35秒东8时区
2024-12-19 # 2024年12月19日
2019-10-12T14:20:50.52+07:00 # (UTC+7)
2019-10-12T03:20:50.52-04:00 # (UTC-4)
2019 的版要求在日期和时间之间使用大写的
T
,而不是小写的t
,不可以省略。其他版本可省略 T, 不能是其他字符。
换句话说,下面的格式也是合法的。
2020-12-18 08:24:35 # 2020年12月18日8点24分35秒
2020-12-18 08:24:35.109 # 2020年12月18日8点24分35秒109毫秒
2020-12-18 08:24:35+08:00 # 2020年12月18日8点24分35秒东8时区
使用这些分隔,可有效提高可读性,方便解析。
持续时间
P(n)Y(n)M(n)DT(n)H(n)M(n)S # P 开头(period),Y 表示年,M 表示月,D 表示日,T 表示时间,H 表示小时,M 表示分钟,S 表示秒
P3Y6M4DT12H30M5S # 3年6个月4天12小时30分钟5秒
RFC 3339
RFC 3339 是 IETF(Internet Engineering Task Force )制定的日期和时间的表示方法,全称是《Date and Time on the Internet: Timestamps》。它规范了互联网上的时间格式,和 ISO 8601 有差异,有重叠。
和 ISO 8601 区别较小,主要是时区的表示:
RFC 3339 使用
Z
或+00:00
或-00:00
表示 UTC 时区,而 ISO 8601 使用+00:00
或-00:00
表示 UTC 时区。
RFC 3339 日期和时间的分隔符号可以是:
T
、t
和' '
(空格)。
RFC 3339 不允许省略日期中的分隔符号
-
,日期和时间必须有分隔符号T
或t
或' '
。
RFC 3339 没看到规定持续时间的表示方法。
2019-10-12T07:20:50.52Z # (UTC+0) RFC 3339 零时区
20191012T07:20:50 # ISO 8601 ✅ RFC 3339 ❌ 没有时区
20191012T07:20:50+08 # ISO 8601 ✅ RFC 3339 ❌ 时区必须完整
2019-10-12 072050 # ISO 8601 ✅ RFC 3339 ❌ 没有时区
RFC 3339 日期和时间的分隔符号可以是:
T
、t
和' '
(空格)。
2019-10-12T07:20:50.52Z # (UTC+0) RFC 3339
2019-10-12 07:20:50.52+00:00 # (UTC+0) RFC 3339 ISO 8601
如何表示一天的开始和结束?
00:00:00.000
作为一天的开始, 23:59:59.999
作为一天的结束。
哪个规范更适合用于互联网软件开发?
RFC 3339 的日期可读性更好,且能兼容 ISO 8601,所以在项目中使用 RFC 3339 格式是更好的选择。
吐槽:ISO 8601 的标准文档居然要收费,而 RFC 3339 是完全公开免费的,这是不是有点不合理?难怪 RFC 标准能被互联网广泛使用。
ISO 的规范比较混乱,文档也不好查询,而 RFC 3339 的文档清晰,易懂,所以推荐使用 RFC 3339。
对比两者的关键区别
维度 | RFC 3339 | ISO 8601 |
---|---|---|
时区 | 必须 | 可选 |
日期分隔符 | - 如 2025-05-31 | 允许省略 如 20250531 |
日期时间分隔符 | T 、t 、'' | T |
时区偏移 | +hh:mm 、-hh:mm 和Z | +hh:mm 、-hh:mm 、-hh 和Z |
总结
- 系统中统一使用一种日期时间格式,能有效避免误解和某些解析 bug,给协作极大方便。
- ISO 8601 和 RFC 3339 都是国际标准,但 RFC 3339 的日期可读性更好。
- 推荐在项目使用
YYYY-MM-DD HH:mm:ss
格式。 - 如果涉及到跨时区的情况,务必带上时区:
YYYY-MM-DD HH:mm:ssZ
。 - 使用
时间戳
也是一种不错的选择,但是不够直观,不方便人类阅读。 - 前端开发中,推荐使用 dayjs 处理时间和日期,它支持大部分常用的日期格式,小巧,api 易用。
两种规范比较。
经过上面的介绍,推荐在日常开发中使用这几种格式:
格式 | 优点 | 缺点 |
---|---|---|
YYYY-MM-DD | 人类和机器都友好 | |
YYYY-MM-DDTHH:mm:ss | 人类和机器都友好 | |
YYYY-MM-DDTHH:mm:ssZ | 人类和机器都友好 | |
YYYY-MM-DD HH:mm:ss | 人类和机器都友好 | 不符合 RFC3339 和 ISO8601 规范 |
YYYY-MM-DD HH:mm:ssZ | 人类和机器都友好 | 不符合 RFC3339 和 ISO8601 规范 |
时间戳 | 机器都友好,方便比较 | 人类不可读 |
在公司项目或者团队开发中禁用其他格式。
JackChou: 前端程序员,最近专注 webGis 开发,个人微信:MasonChou123, 欢迎交流,加我进技术交流群。
更多参考
Understanding about RFC 3339 for Datetime and Timezone Formatting in Software Engineering
What's the difference between ISO 8601 and RFC 3339 Date Formats?