如何使用Moment.js根据指定日期与星期获取对应周的目标日期?
获取同一周内指定星期的日期
要实现根据给定日期和目标星期(名称或数字)获取同一周内对应日期的需求,核心是计算当前日期与目标星期的天数差,直接在原日期基础上调整,而不是盲目增减天数。以下是具体实现思路和代码:
实现思路
- 将输入的日期字符串转换为
Date对象,确保日期有效。 - 定义星期映射表,统一处理星期名称(如"Wednesday")和数字(如3)的转换。
- 将当前日期的星期转换为自定义编号(周一=1,周二=2…周日=7),适配JS原生
getDay()(周日=0,周一=1…周六=6)的规则。 - 计算目标星期与当前星期的天数差:目标星期数 - 当前星期数(差值为负则减天数,为正则加天数)。
- 调整日期后,格式化为
YYYY-MM-DD的字符串输出。
代码实现
// 星期映射表:数字与名称双向对应 const weekMap = { 1: 'Monday', 2: 'Tuesday', 3: 'Wednesday', 4: 'Thursday', 5: 'Friday', 6: 'Saturday', 7: 'Sunday', 'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 'Thursday': 4, 'Friday': 5, 'Saturday': 6, 'Sunday': 7 }; function getSameWeekDate(dateStr, targetWeek) { // 转换为Date对象并验证有效性 const currentDate = new Date(dateStr); if (isNaN(currentDate.getTime())) { throw new Error('无效的日期格式'); } // 获取当前日期的星期编号(周一=1,周日=7) const currentDay = currentDate.getDay(); const currentWeekNum = currentDay === 0 ? 7 : currentDay; // 解析目标星期为数字编号 let targetWeekNum; if (typeof targetWeek === 'number') { if (targetWeek < 1 || targetWeek > 7) { throw new Error('星期数字必须在1-7之间'); } targetWeekNum = targetWeek; } else if (typeof targetWeek === 'string') { targetWeekNum = weekMap[targetWeek]; if (!targetWeekNum) { throw new Error('无效的星期名称'); } } else { throw new Error('目标星期必须是数字或字符串'); } // 计算天数差并调整日期 const dayDiff = targetWeekNum - currentWeekNum; const targetDate = new Date(currentDate); targetDate.setDate(currentDate.getDate() + dayDiff); // 格式化为YYYY-MM-DD const year = targetDate.getFullYear(); const month = String(targetDate.getMonth() + 1).padStart(2, '0'); const day = String(targetDate.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }
测试示例
// 示例1:周一(2022-08-29)获取周三 console.log(getSameWeekDate("2022-08-29", "Wednesday")); // 输出:2022-08-31 console.log(getSameWeekDate("2022-08-29", 3)); // 输出:2022-08-31 // 示例2:周三(2022-08-31)获取周二 console.log(getSameWeekDate("2022-08-31", "Tuesday")); // 输出:2022-08-30 console.log(getSameWeekDate("2022-08-31", 2)); // 输出:2022-08-30
说明
之前的错误在于没有正确计算同一周内的天数差:比如周三(3)到周二(2)的差值是2-3=-1,只需在原日期基础上减1天即可,而非盲目加天数。该方法保证了调整后的日期始终在原日期所在的自然周内。
内容的提问来源于stack exchange,提问作者user3233787
相关产品推荐
相关产品推荐

