这样的 dayjs 你敢用?

337 阅读3分钟

没错,这是个标题党,只是发现了一个 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 年了至今未发布)

image.png

还有去年一年的代码提交频率:

image.png

image.png

再来看看 PR 的数量:

image.png

可以看到,这个库近一年仅有作者本人在维护,使用者提出的 bug 并不少,还有人直接提 PR 去修复,但项目的更新频率却很低。合理猜测作者并无精力去维护这个项目,issue 和 PR 都看不过来了,并且没有合作者能分担工作。

诚然,开源一个库需要无私奉献,为爱发电,很值得歌颂。但这个库在中文世界实在太流行了,几乎每个公众号在介绍 js 时间处理库的时候都会重点提到它。而年久失修的它可能已经无力支撑起大家的期望。

展望未来

也许我们该把目光放长远一点,看看现在我们还能用啥时间处理工具:

  • momentjs,老牌选手,除了体积大,没什么问题
  • date-fns,一个同样流行的第三方库,本人未深度使用,不确定有没有坑
  • DateTimeFormat,浏览器内置对象,只需要格式化时间的场景可以使用,兼容性强
  • Temporal,浏览器内置对象,可以对时间进行复杂操作,目前尚未有主流浏览器实现

最后,希望 dayjs 能越来越好,如果作者遇到什么困难,可以在社区抛出来看看能否得到帮助。