date-fns 相对时间显示 60 seconds,为什么没有变成 1 minute
formatDistanceStrict 接近单位边界时可能显示 60 seconds、60 minutes 或 24 hours。说明 date-fns 4.4.0 先选单位再取整的路径,按页面约定选择取整和文案。
刚过 59 秒,相对时间标签先显示 60 seconds,下一刻才变成 1 minute;接近一小时或一天时,也可能显示 60 minutes、24 hours。使用 date-fns 的 formatDistanceStrict() 时,这个现象来自选单位与取整的先后顺序。
4.4.0 先用未取整的差值选择 second、minute 或 hour,再计算该单位中的取整数值。59.5 秒仍属于 second 分支,默认 round 随后把它变成 60,函数不会重新进入 minute 分支。formatDistanceToNowStrict 使用当前时间作为另一端,也会遇到同样的边界。
显示规则决定怎么处理边界
如果页面要求“未满一分钟仍显示秒”,可以明确采用向下取整:
import { formatDistanceStrict } from 'date-fns';
const base = new Date(2026, 9, 1, 12, 0, 0);
const later = new Date(base.getTime() + 59500);
const label = formatDistanceStrict(later, base, {
roundingMethod: 'floor',
});
这一组输入显示 59 秒,而不是提前显示一分钟。它也会影响其他区间的数字,不能只修改 59.5 秒这一帧就忽略整个页面的取整约定。选项 ceil 会更早向上取整,不能解决“60 秒”这个要求。
如果产品允许“大约一分钟”“不到一分钟”一类近似语言,可评估普通 formatDistance()。它采用另一套区间与文案,不保证与 Strict 逐条对应;更换前应确认 locale、后缀及所有边界都符合页面语言。
不要只替换最后的字符串
把字符串中的 60 seconds 替换成 1 minute,只覆盖一种语言和一种数量。中文、其他 locale、过去未来后缀以及强制 unit 的用法都会漏掉;直接替换 24 hours 还可能混淆固定小时与日历日。
若页面必须使用自定义的“取整后提升单位”规则,应在自己的格式化层明确有限的单位、阈值、负方向和本地化,再由对应单位输出。不能在默认库输出上做无差别文本替换,也不要推断月份永远等于三十个实际日历日。
显式传入 unit: 'second' 时,显示六十秒可能正是调用方的要求。库的月份分支还对自动单位的 12 个月有单独提升逻辑,因此也不应把“所有单位都绝不提升”写成结论。
4.4.0 正式实现仍采用上述顺序。检查时保留 59.499、59.5 和 60 秒,以及接近一小时、一天的样本;跨夏令时还需沿原来的时区条件核对,因为天、月、年的差值使用夏令时归一化。最终应确认显示符合约定,而不是只看某一个英文标签不再出现。


