最近在写Nodejs,其中有一个业务为计算某一天属于年中的第几周。在网上的代码大都为计算当前日期和当年1月1日之间的天数,然后除以7,结果线上取整。但是这种方式并不符合定义的规则。问题出现在刚好跨年的时间点上。按照规定,如果旧的一年所占一个星期中的周一至周四,那么该周划归为旧一年的最后一周,否则算作新一年的第一周。
例如
- 2019年1月1号(周二),按照上述规则,2019年1月1号属于2019年第一周。
- 2016年1月1日(周五),按照上述规则,2016年1月1号属于2015年最后一周。
按照上述规则,有几个等价的规则。
- 上一年的12月28号必然属于当年的最后一周。
- 一个星期中的周四属于那年那周,所在星期即为那年那周
所以产生了一下的代码
function getWeek (date) {
let value = getThursdayDate(date);
let fullYear = new Date(value).getFullYear(),
timestamp = new Date(value).getTime(),
timeObj = new Date(fullYear + "/01/01");
//获取1月1日获取属于星期几
let day = timeObj.getDay();
//第一周开始的时间戳
let firstWeekTimestamp = 0;
if ([1,2,3,4].includes(day)) {
//1月1日属于第一周
firstWeekTimestamp = (timeObj.getTime()) - (day * 24 * 3600000);
} else {
let num = day > 0 ? 8 : 1;
//1月1日 不属于第一周
firstWeekTimestamp = (timeObj.getTime()) + (num - day) * 24 * 3600000;
}
if (timestamp >= firstWeekTimestamp) {
//如果属于本年度的周数
let num = Math.ceil((timestamp - firstWeekTimestamp) / 7 / 24 / 3600000);
return {year: fullYear,week: num};
} else {
//如果属于上一年的周数
let string = (fullYear - 1) + "/12/28";
return this.getWeek(string);
}
}
//获取周四的时间戳
function getThursdayDate (date) {
let dateObj = new Date(date), timestamp = dateObj.getTime();
let day = dateObj.getDay();
if ([0, 1, 2, 3].includes(day)) {
timestamp += (4 - day) * 24 * 3600000;
} else if ([5, 6].includes(day)) {
timestamp -= (day - 4) * 24 * 3600000;
}
return timestamp;
}
代用上面的代码 getWeek (date); 获取指定日期所在的周数
getWeek("2016/1/1"); //结果为{year: 2015, week: 53}
getWeek("2019/1/1"); //结果为{year: 2019, week: 1}