You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用原生JS Date复刻moment.js的fromNow函数,结果差一天如何解决?

问题:原生JS复刻moment.js fromNow函数时日期差一天的问题

你遇到的核心问题有两个:一是Unix时间戳的单位转换错误,二是多余的时区偏移处理导致时间差计算错误。

错误分析

  1. 时间戳单位错误:Date构造函数接收的数字参数是毫秒级Unix时间戳,但你的函数传入的是秒级时间戳,直接创建new Date(targetUnixTimestampInSeconds)会导致目标日期被错误解析。
  2. 时区偏移处理错误:Unix时间戳本身是基于UTC的,now.getTime()和targetDate.getTime()返回的都是UTC毫秒数,计算时间差时不需要额外添加时区偏移,你的代码中+ targetOffsetInSeconds会让目标时间的秒数变大,最终导致计算出的时间差偏小,少算一天。

修正后的函数

const fromNow = targetUnixTimestampInSeconds => {
  const now = new Date();
  const nowInSeconds = Math.floor(now.getTime() / 1000);

  // 正确将秒级时间戳转为Date对象(乘以1000转毫秒)
  const targetDate = new Date(targetUnixTimestampInSeconds * 1000);
  // 直接获取UTC秒数,无需时区偏移
  const targetInSeconds = Math.floor(targetDate.getTime() / 1000);

  const diffInSeconds = nowInSeconds - targetInSeconds;
  if (diffInSeconds < 60) {
    return `${diffInSeconds} second${diffInSeconds === 1 ? "" : "s"} ago`;
  } else if (diffInSeconds < 3600) {
    const minutes = Math.floor(diffInSeconds / 60);
    return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
  } else if (diffInSeconds < 86400) {
    const hours = Math.floor(diffInSeconds / 3600);
    return `${hours} hour${hours === 1 ? "" : "s"} ago`;
  } else if (diffInSeconds < 2592000) {
    const days = Math.floor(diffInSeconds / 86400);
    return `${days} day${days === 1 ? "" : "s"} ago`;
  } else if (diffInSeconds < 31536000) {
    const months = Math.floor(diffInSeconds / 2592000);
    return `${months} month${months === 1 ? "" : "s"} ago`;
  } else {
    const years = Math.floor(diffInSeconds / 31536000);
    return `${years} year${years === 1 ? "" : "s"} ago`;
  }
};

测试验证

使用你的测试代码验证:

const targetUnixTimestampInSeconds = 1689875101441 / 1000; // 毫秒转秒
console.log(fromNow(targetUnixTimestampInSeconds)); // 输出与moment一致的结果
console.log(moment(1689875101441).fromNow());

修正后,函数会正确计算UTC时间差,输出结果与moment.js的fromNow()保持一致。

内容的提问来源于stack exchange,提问作者Dennys Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:37:51