没错,这是个标题党,只是发现了一个 bug 而已。不过且听我吐槽完再看待这个库的质量。
问题起因
三年前,我遇到一个需求,需要用户在日期选择器上选中一个日期后,展示的时候显示这是这一年的第几周。 于是我找到了 dayjs 这个库,它提供了一个 week 方法,可以实现这个功能。 (需要引入 timezone 和 weekOfYear 插件)
const weekOk = dayjs.tz("2025-01-02", "Asia/Shanghai").week();
// 输出 1
很好,看来能用。这个需求还需要在英国上线,换个时区看看:
const weekOk = dayjs.tz("2025-01-02", "Europe/London").week();
// 输出 5
什么鬼?同一天即使有时差,也不至于差个四周的时间吧?难道是我用得不对?
我翻遍了文档没找到别的写法,翻阅代码才发现,坑很深。
timezone 插件会给 dayjs 对象设置 utc 信息,而 weekOfYear 会对时间进行运算。 问题就出现在时间运算上。这里给出一个复现的例子:
const originDay = dayjs(timeStr).utcOffset(0, true);
const addOneMinute = originDay.add(1, "minute");
originDay.format();
// 2025-01-02T00:00:00Z
addOneMinute.format();
// 2025-01-01T16:01:00Z 时间倒退 8 小时了
为了方便不信邪的朋友验证,这里给出 codesandbox 的链接。
对了,这是我 3 年前就发现并反馈的 bug,至今没得到任何有价值的回应。有一个 PR 尝试修复这个问题,也没得到作者的回复是合入还是不合入。
项目现状
再看看这个库中关于 bug 的 issue:
(这里有彩蛋,22 年 5 月就已经有 2.0 alpha 版,过去快 3 年了至今未发布)
还有去年一年的代码提交频率:
再来看看 PR 的数量:
可以看到,这个库近一年仅有作者本人在维护,使用者提出的 bug 并不少,还有人直接提 PR 去修复,但项目的更新频率却很低。合理猜测作者并无精力去维护这个项目,issue 和 PR 都看不过来了,并且没有合作者能分担工作。
诚然,开源一个库需要无私奉献,为爱发电,很值得歌颂。但这个库在中文世界实在太流行了,几乎每个公众号在介绍 js 时间处理库的时候都会重点提到它。而年久失修的它可能已经无力支撑起大家的期望。
展望未来
也许我们该把目光放长远一点,看看现在我们还能用啥时间处理工具:
momentjs,老牌选手,除了体积大,没什么问题date-fns,一个同样流行的第三方库,本人未深度使用,不确定有没有坑DateTimeFormat,浏览器内置对象,只需要格式化时间的场景可以使用,兼容性强Temporal,浏览器内置对象,可以对时间进行复杂操作,目前尚未有主流浏览器实现
最后,希望 dayjs 能越来越好,如果作者遇到什么困难,可以在社区抛出来看看能否得到帮助。