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

如何用moment.js获取带详细细分时长的已过去时间?

解决moment.js细分已过去时长的问题

你当前的问题在于直接调用diff()获取的是总时长差值,比如1年2个月的日期,diff('months')会返回14,diff('days')会返回这1年2个月的总天数,所以需要逐步扣除已统计的时长,再计算剩余部分。

可以通过以下步骤修正:

  • 创建当前时间的副本,避免修改原moment实例
  • 先计算年数,然后把基准时间加上对应的年数,再计算剩余的月数
  • 同理,加上月数后计算剩余的天数
  • 收集所有非零的时长部分,最后拼接成符合要求的字符串

修正后的代码如下:

function passedTimeMoment(date: number | undefined): string {
  if (date === undefined) return '';

  const now = moment().startOf('day');
  const targetDate = moment(date).startOf('day');
  const parts: string[] = [];

  // 计算年数并调整基准时间
  const years = now.diff(targetDate, 'years');
  if (years > 0) {
    parts.push(`${years} year${years > 1 ? 's' : ''}`);
    targetDate.add(years, 'years');
  }

  // 计算剩余月数并调整基准时间
  const months = now.diff(targetDate, 'months');
  if (months > 0) {
    parts.push(`${months} month${months > 1 ? 's' : ''}`);
    targetDate.add(months, 'months');
  }

  // 计算剩余天数
  const days = now.diff(targetDate, 'days');
  if (days > 0 || parts.length === 0) { // 如果前面都为0,至少显示天数
    parts.push(`${days} day${days > 1 ? 's' : ''}`);
  }

  // 拼接字符串,处理"and"的位置
  if (parts.length === 1) {
    return `${parts[0]} ago`;
  } else if (parts.length === 2) {
    return `${parts[0]} and ${parts[1]} ago`;
  } else {
    const lastPart = parts.pop();
    return `${parts.join(', ')} and ${lastPart} ago`;
  }
}

关键说明:

  • 每次计算完一个时间单位后,用add()把目标日期往前推进对应的时长,这样后续的diff()只会计算剩余的时间,不会包含已统计的年月部分
  • 加入了单复数处理(比如1 year vs 2 years)
  • 优化了字符串拼接逻辑,避免出现多余的"and",同时处理了只有单个时间单位的情况

内容的提问来源于stack exchange,提问作者Hasan Parasteh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:47:16