如何用JavaScript Date或Luxon获取指定日期的当月星期几出现次数
实现给定日期返回当月第N个星期几的方法
原生JavaScript Date实现
核心逻辑是先定位当月第一个目标星期几的日期,再通过目标日期与该日期的差值计算出现次数:
- 解析目标日期生成
Date对象,同时获取当月第一天的Date对象 - 映射星期数到中文名称(注意原生
getDay()返回0=周日,1=周一……6=周六) - 计算当月第一个目标星期几的日期:
- 若当月第一天的星期数 ≤ 目标星期数,第一个目标日期为
1 + (目标星期数 - 第一天星期数) - 反之,第一个目标日期为
1 + (7 - (第一天星期数 - 目标星期数))
- 若当月第一天的星期数 ≤ 目标星期数,第一个目标日期为
- 通过
(目标日期日数 - 第一个目标日期日数) / 7 + 1得到出现次数
代码示例:
function getWeekdayOccurrence(dateString) { // 星期中文映射,对应getDay()返回值(0=周日,1=周一...6=周六) const weekdayNames = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; const targetDate = new Date(dateString); const year = targetDate.getFullYear(); const month = targetDate.getMonth(); const targetDay = targetDate.getDate(); const targetWeekday = targetDate.getDay(); const weekdayName = weekdayNames[targetWeekday]; // 获取当月第一天 const firstDayOfMonth = new Date(year, month, 1); const firstDayWeekday = firstDayOfMonth.getDay(); // 计算当月第一个目标星期几的日期 let firstOccurrenceDate; if (firstDayWeekday <= targetWeekday) { firstOccurrenceDate = 1 + (targetWeekday - firstDayWeekday); } else { firstOccurrenceDate = 1 + (7 - (firstDayWeekday - targetWeekday)); } // 计算出现次数 const occurrenceCount = Math.floor((targetDay - firstOccurrenceDate) / 7) + 1; return `第${occurrenceCount}个${weekdayName}`; } // 测试:2022年11月22日 console.log(getWeekdayOccurrence('2022-11-22')); // 输出:第4个星期二
Luxon实现
Luxon提供了更简洁的日期操作API,无需手动处理复杂的星期偏移计算:
- 用
DateTime.fromISO解析目标日期 - 映射星期数到中文名称(注意Luxon的
weekday是1=周一,7=周日) - 获取当月第一天的
DateTime对象,设置到第一个目标星期几的日期;若设置后跨月,则回退一周 - 计算目标日期与第一个目标日期的周数差,加1得到出现次数
代码示例:
import { DateTime } from 'luxon'; function getWeekdayOccurrenceLuxon(dateString) { // 星期中文映射,对应Luxon的weekday(1=周一,2=周二...7=周日) const weekdayNames = ['', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']; const targetDt = DateTime.fromISO(dateString); const targetWeekday = targetDt.weekday; const weekdayName = weekdayNames[targetWeekday]; const targetDay = targetDt.day; // 获取当月第一个目标星期几的日期 const firstDayOfMonth = targetDt.startOf('month'); let firstOccurrenceDt = firstDayOfMonth.set({ weekday: targetWeekday }); // 若设置后跨月,说明第一个目标星期几在上一周 if (firstOccurrenceDt.month !== targetDt.month) { firstOccurrenceDt = firstOccurrenceDt.minus({ weeks: 1 }); } const firstOccurrenceDate = firstOccurrenceDt.day; // 计算出现次数 const occurrenceCount = Math.floor((targetDay - firstOccurrenceDate) / 7) + 1; return `第${occurrenceCount}个${weekdayName}`; } // 测试:2022年11月22日 console.log(getWeekdayOccurrenceLuxon('2022-11-22')); // 输出:第4个星期二
内容的提问来源于stack exchange,提问作者dblinkhorn
相关产品推荐
相关产品推荐

