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

如何自定义date-fns的formatDistance实现特定场景日期显示格式

实现自定义日期显示规则(当天/昨天/一周内/超过一个月)

你可以通过分条件判断日期区间来实现这个自定义显示规则,不用依赖formatDistance(它更适合显示相对时长,比如"3小时前")。下面提供两种实现方案:


方案一:使用date-fns(推荐,简洁可靠)

借助date-fns的工具函数可以避免手动处理时间边界的坑,代码更清晰:

import { format, isToday, isYesterday, differenceInCalendarDays, differenceInCalendarMonths, parseISO } from 'date-fns';
import { zhCN } from 'date-fns/locale'; // 中文环境用这个locale,对应「周五」「昨天」这类文案

function formatCustomDate(wroteTime) {
  const targetDate = parseISO(wroteTime); // 解析后端返回的ISO格式日期
  const now = new Date();

  // 当天:仅显示时分
  if (isToday(targetDate)) {
    return format(targetDate, 'HH:mm');
  }

  // 昨天:显示「昨天 时分」
  if (isYesterday(targetDate)) {
    return `昨天 ${format(targetDate, 'HH:mm')}`;
  }

  // 一周内(不含今天、昨天):显示「星期 时分」
  const dayDiff = differenceInCalendarDays(now, targetDate);
  if (dayDiff > 1 && dayDiff <= 7) {
    return format(targetDate, 'ccc HH:mm', { locale: zhCN }); // ccc是星期简写,比如「周五」
  }

  // 超过一个月:显示MM/DD/YYYY
  const monthDiff = differenceInCalendarMonths(now, targetDate);
  if (monthDiff >= 1) {
    return format(targetDate, 'MM/dd/yyyy');
  }

  // 一周到一个月之间的情况(用户未明确,这里默认用MM/DD/YYYY,可按需调整)
  return format(targetDate, 'MM/dd/yyyy');
}

代码说明:

  • parseISO:比直接new Date()更可靠地解析ISO格式日期字符串
  • isToday/isYesterday:直接判断日期是否为今天/昨天,无需手动计算时间戳
  • ccc格式符:在中文locale下会返回「周一」「周五」这类星期简写
  • differenceInCalendarMonths:按自然月份计算差值,比用30天近似更准确

方案二:原生JavaScript实现(无依赖)

如果不想引入第三方库,可以用原生JS手动处理:

function formatCustomDate(wroteTime) {
  const targetDate = new Date(wroteTime);
  const now = new Date();

  // 转换为当天0点,用于判断今天/昨天
  const targetMidnight = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate());
  const nowMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate());

  const oneDayMs = 24 * 60 * 60 * 1000;
  const timeDiff = nowMidnight - targetMidnight;

  // 格式化时分的工具函数
  const formatTime = (date) => {
    return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
  };

  // 星期简写映射
  const weekShortNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];

  // 当天
  if (timeDiff === 0) {
    return formatTime(targetDate);
  }

  // 昨天
  if (timeDiff === oneDayMs) {
    return `昨天 ${formatTime(targetDate)}`;
  }

  // 一周内
  if (timeDiff > oneDayMs && timeDiff <= 7 * oneDayMs) {
    const weekIndex = targetDate.getDay();
    return `${weekShortNames[weekIndex]} ${formatTime(targetDate)}`;
  }

  // 判断是否超过一个月
  const isOverOneMonth = now.getFullYear() > targetDate.getFullYear() 
    || (now.getFullYear() === targetDate.getFullYear() && now.getMonth() - targetDate.getMonth() >= 1);

  // 超过一个月:显示MM/DD/YYYY
  if (isOverOneMonth) {
    const month = (targetDate.getMonth() + 1).toString().padStart(2, '0');
    const day = targetDate.getDate().toString().padStart(2, '0');
    return `${month}/${day}/${targetDate.getFullYear()}`;
  }

  // 一周到一个月之间的默认处理
  const month = (targetDate.getMonth() + 1).toString().padStart(2, '0');
  const day = targetDate.getDate().toString().padStart(2, '0');
  return `${month}/${day}/${targetDate.getFullYear()}`;
}

使用方式:

直接调用函数传入后端返回的日期字符串即可:

const displayDate = formatCustomDate('2022-10-20T10:41:31.095');
console.log(displayDate); // 根据当前日期会输出对应格式

内容的提问来源于stack exchange,提问作者Гришко Шкарта

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:50:26