You need to enable JavaScript to run this app. 如何用Moment.js或纯JS实现多维度分区间的帖子相对时间展示
优惠活动
大模型
产品
解决方案
定价
更多

如何用Moment.js或纯JS实现多维度分区间的帖子相对时间展示

基于Moment.js的修改实现

直接替换原有fromNow()的单维度输出逻辑,自定义多维度时间差生成规则,完全覆盖需求场景:

核心逻辑说明

  • 特殊场景优先判断:间隔小于1分钟输出Just Now,当日发布输出Today,不会出现空值
  • 非当日场景按年、月、周、天的优先级拆分非零时间单位
  • 自动适配单复数规则,用逗号拼接多个时间单位后加ago后缀

修改后的完整可运行代码

$(document).ready(function () {
  var publishedDate = ".iso-date";
  var displayDate = ".display-date";

  $(publishedDate).each(function (i, e) {
    const rawDate = $(e).text().trim();
    const $target = $(e).next(displayDate);
    const publishedMoment = moment(rawDate);

    // 跳过无效日期
    if (!publishedMoment.isValid()) return;

    const now = moment();
    let outputText = "";

    // 特殊场景处理
    if (now.diff(publishedMoment, 'minutes') < 1) {
      outputText = "Just Now";
    } else if (now.isSame(publishedMoment, 'day')) {
      outputText = "Today";
    } else {
      // 拆分多维度时间差
      const duration = moment.duration(now.diff(publishedMoment));
      const timeUnits = [];

      // 按优先级从高到低取非零单位
      const years = duration.years();
      if (years) timeUnits.push(`${years} ${years === 1 ? 'year' : 'years'}`);

      const months = duration.months();
      if (months) timeUnits.push(`${months} ${months === 1 ? 'month' : 'months'}`);

      const weeks = duration.weeks();
      if (weeks) timeUnits.push(`${weeks} ${weeks === 1 ? 'week' : 'weeks'}`);

      const days = duration.days();
      if (days) timeUnits.push(`${days} ${days === 1 ? 'day' : 'days'}`);

      outputText = timeUnits.join(', ') + ' ago';
    }

    $target.text(`Posted ${outputText}`);
  });
});

可选精简配置

如果不需要展示所有层级的时间单位,只展示最高优先级的1-2个区间,只需在timeUnits生成后添加截取逻辑即可:

// 仅保留优先级最高的2个时间单位
if (timeUnits.length > 2) timeUnits.length = 2;
outputText = timeUnits.join(', ') + ' ago';

无额外依赖的纯JavaScript实现

无需引入Moment.js、jQuery等第三方库,用原生API即可实现同等效果:

实现代码

document.addEventListener('DOMContentLoaded', function () {
  const publishedDateEls = document.querySelectorAll('.iso-date');
  const displayDateSelector = '.display-date';

  publishedDateEls.forEach(el => {
    const rawDate = el.textContent.trim();
    const targetEl = el.nextElementSibling;
    // 校验相邻元素是否为目标输出节点
    if (!targetEl || !targetEl.matches(displayDateSelector)) return;

    const publishedTime = new Date(rawDate).getTime();
    // 跳过无效日期
    if (isNaN(publishedTime)) return;

    const now = new Date();
    const nowTime = now.getTime();
    let outputText = '';

    const diffMs = nowTime - publishedTime;
    const diffMinutes = Math.floor(diffMs / (1000 * 60));

    // 特殊场景处理
    if (diffMinutes < 1) {
      outputText = 'Just Now';
    } else {
      const publishedDateObj = new Date(publishedTime);
      // 校验是否为同一自然日
      const isSameDay = now.getFullYear() === publishedDateObj.getFullYear()
        && now.getMonth() === publishedDateObj.getMonth()
        && now.getDate() === publishedDateObj.getDate();
      
      if (isSameDay) {
        outputText = 'Today';
      } else {
        const timeUnits = [];

        // 计算年差,修正未到发布月的情况
        let years = now.getFullYear() - publishedDateObj.getFullYear();
        if (now.getMonth() < publishedDateObj.getMonth() || 
            (now.getMonth() === publishedDateObj.getMonth() && now.getDate() < publishedDateObj.getDate())) {
          years--;
        }
        if (years > 0) timeUnits.push(`${years} ${years === 1 ? 'year' : 'years'}`);

        // 计算剩余月差
        let totalMonths = (now.getFullYear() - publishedDateObj.getFullYear()) * 12 + now.getMonth() - publishedDateObj.getMonth();
        if (now.getDate() < publishedDateObj.getDate()) totalMonths--;
        const months = totalMonths % 12;
        if (months > 0) timeUnits.push(`${months} ${months === 1 ? 'month' : 'months'}`);

        // 计算剩余天、周差
        const totalDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
        const remainDays = totalDays - years * 365 - months * 30;
        const weeks = Math.floor(remainDays / 7);
        const days = remainDays % 7;

        if (weeks > 0) timeUnits.push(`${weeks} ${weeks === 1 ? 'week' : 'weeks'}`);
        if (days > 0) timeUnits.push(`${days} ${days === 1 ? 'day' : 'days'}`);

        outputText = timeUnits.join(', ') + ' ago';
      }
    }

    targetEl.textContent = `Posted ${outputText}`;
  });
});

精度说明

原生实现的年、月、天拆分采用近似规则(年按365天、月按30天计算),满足绝大多数内容展示场景;如果需要和日历完全对齐的精确差值,可自行调整年、月的修正逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 17:24:01