Nuxt中使用Dayjs获取指定ISO周日期的异常问题咨询
问题分析与修复方案
这个问题的核心是你混淆了格里高利年份和ISO周年份的设置方式,同时周起始的获取方法也不符合ISO周的规则。让我一步步拆解:
问题根源
- 错误使用年份设置方法:你用了
.year(year)来设置年份,但这个方法是针对格里高利日历的年份。而ISO周的年份可能和格里高利年份不完全重合(比如2023年1月1日属于2022年的ISO周52)。正确的ISO周年份设置应该用.isoWeekYear(year)方法。 - 周起始获取方式不对:你用
.day(1)来获取周一开始的日期,但Dayjs默认的周起始是周日,这个方法会把日期调到当前默认周(周日起)的周一,而不是ISO周(周一启)的周一。正确的做法是用.startOf('isoWeek')来直接获取ISO周的起始日。
修复后的代码
const year = 2023 const calendarWeek = 1 // 1 到 53,符合ISO周编号规则 const dayjs = this.$dayjs const isoWeek = require('dayjs/plugin/isoWeek') dayjs.extend(isoWeek) // 关键变更:用isoWeekYear设置ISO周年份,而非year const week = dayjs().isoWeekYear(year).isoWeek(calendarWeek) // 关键变更:用startOf('isoWeek')获取ISO周的周一起始 const startOfWeek = dayjs(week).startOf('isoWeek') const weekdays = new Array(7).fill(startOfWeek).map( (day, idx) => day.add(idx, 'day').format('dddd, DD MMM YYYY') )
为什么之前2022年正常?
2022年的ISO周1和格里高利年份完全重合:2022年1月3日(周一)到9日(周日)都是2022年,所以.year(2022).isoWeek(1)刚好能定位到正确的周。但2023年的ISO周1从1月2日开始,而1月1日属于2022年的ISO周52,用.year(2023)强制锁定格里高利年份后,Dayjs的.isoWeek(1)会错误地定位到下一个符合条件的周(也就是1月9日开始的ISO周2),这就是你看到异常的原因。
额外说明
ISO周的规则是:
- 每周从周一开始
- 一年的第一周是包含当年1月4日的那一周(等价于包含当年第一个周四的周)
- 周编号范围是1到53,不存在0周(你之前设置
calendarWeek=0能得到正确结果,是因为Dayjs把0周解析为上一年的最后一周,刚好巧合匹配了2023年的ISO周1)
内容的提问来源于stack exchange,提问作者Philippe




