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

如何在TypeScript中获取指定星期几的最近日期(YYYY-MM-DD格式)

用date-fns实现获取最近指定中文星期的日期(TypeScript)

实现思路

核心是通过计算当前星期与目标星期的差值,确定需要回溯的天数,再利用date-fns的addDays(支持负数参数)得到目标日期,最后格式化输出。

完整TypeScript代码

import { getDay, addDays, format } from 'date-fns';

// 中文星期与date-fns星期数字的映射(0=周日,1=周一...6=周六)
const chineseWeekdayMap: Record<string, number> = {
  "周日": 0,
  "周一": 1,
  "周二": 2,
  "周三": 3,
  "周四": 4,
  "周五": 5,
  "周六": 6
};

/**
 * 获取距离当前日期最近的指定中文星期的日期(格式YYYY-MM-DD)
 * @param chineseWeekday 中文星期,如"周三"、"周六"
 * @returns 格式化后的日期字符串
 */
function getRecentWeekdayDate(chineseWeekday: string): string {
  const targetDay = chineseWeekdayMap[chineseWeekday];
  if (targetDay === undefined) {
    throw new Error('请输入有效的中文星期,例如"周三"、"周六"');
  }

  const today = new Date();
  const currentDay = getDay(today);
  const diff = currentDay - targetDay;

  let daysToSubtract: number;
  if (diff === 0) {
    // 今天就是目标星期,取上周同一天
    daysToSubtract = 7;
  } else if (diff > 0) {
    // 本周目标星期已过,回溯diff天
    daysToSubtract = diff;
  } else {
    // 本周目标星期未到,取上周的对应日期,回溯(diff + 7)天
    daysToSubtract = diff + 7;
  }

  const targetDate = addDays(today, -daysToSubtract);
  return format(targetDate, 'yyyy-MM-dd');
}

// 测试示例(假设当前日期是2023-01-26 周四)
console.log(getRecentWeekdayDate("周三")); // 输出:2023-01-25
console.log(getRecentWeekdayDate("周四")); // 输出:2023-01-19
console.log(getRecentWeekdayDate("周六")); // 输出:2023-01-21

关键说明

  1. 关于date-fns的addDays支持负数:你之前的误解是错误的,addDays完全支持传入负数参数,传入-n就等价于减去n天,这是实现回溯的核心。
  2. 星期映射逻辑:date-fns的getDay返回0(周日)到6(周六)的数字,所以需要建立中文星期到对应数字的映射表。
  3. 差值计算逻辑:
    • 若当天就是目标星期,直接回溯7天取上周同一天
    • 若本周目标星期已过,回溯天数等于当前星期与目标星期的差值
    • 若本周目标星期未到,回溯天数为差值加7(等价于回溯到上周的目标星期)

注意事项

  • 确保输入的中文星期在映射表范围内,否则会抛出错误,可根据需求调整错误处理逻辑(比如返回默认值)
  • 如果需要基于UTC时间计算,可将getDay替换为getUTCDay
  • 需先安装date-fns依赖:npm install date-fns

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:51:38