而回复也多表示,这个“坑”是来自 Java 的。那么问题来了:

1. 这个“坑”真的来自 Java 吗?如果不是,又是来自何处?

2. 这个“坑”我们在业务中真要直接面对吗?

3. 关于时间、日期等,还有没有其它类似的“坑”?


Unix epoch 与 struct tm

大家都知道,Date.now() 或是 Date 对象的 getTime() 方法可以得到一个数字,俗称“时间戳”,或是“Unix 时间戳”。不少朋友还知道,常见的编程语言都能处理这个“时间戳”,也有不少在线工具可以帮我们将“时间戳”转为可阅读的时间日期,如 https://tool.lu/timestamp/ 及 https://tool.chinaz.com/tools/unixtime.aspx 等等。这个“时间戳”,英文名为 Unix epoch、POSIX time,本质就是给定时间在 UTC 1970年1月1日零点之后的秒数。注意,在 TS、JS 等语言里使用的是毫秒数。

在 C 语言中,不晚于 C89 / C90 标准,<time.h> 就已将 Unix epoch 对应的32位有符号整数定义为 time_t 。自然,C 语言也能将 Unix epoch 和具体日期的年月日时分秒等相互转换。struct tm 就是同样定义于 <time.h> 的结构体,mktime 和 localtime / gmtime 就是 time_t 和 struct tm 的转换函数。我们来看看  struct tm 的成员对象:

如仅想使用本地化的相对时间功能, timeago.js 也是个不错的选择,本文不作详述。注意在简体中文环境下,moment.js 与 timeago.js 对于将来时刻的输出是有所不同的,moment.js 是“n 天内”,而 timeago.js 是"n 天后"。

如果说日期时间的加减计算不使用任何第三方库的问题不大,那么相对时间与日历时间就完全不建议这么做了。举个例子,时间单位的单复数就是大麻烦。更何况 moment.js 还自带几十种语言的本地化。


时长

看惯了便于阅读的相对时间显示,再看到惯用的 hh:mm:ss 的时长显示,是不是瞬间觉得可阅读行太差了呢?特别是当时长较长且策划 / 产品经理死也不同意使用相对时间来显示时,策划 / 产品经理往往会给出一些毫无常识、宛如智障的显示格式,比如... 01:02:03:04:05,这叫“一个月零两天三小时四分五秒”。这种显示,不是非蠢即坏,就是单纯的又蠢又坏。遗憾的是,包括 moment.js 在内的大部分日期时间库都没有时长相关的处理。这里我们使用 Humanize Duration 来解决这个问题。