目录
- 引言
- 一、获取本周一和周日日期
- 二、获取前 i 周的周一和周日日期
- 三、获取后 i 周的周一和周日日期
- 四、获取制定日期区间的周数(不跨年)
- 五、第一学期还涉及到跨年的情况,处理起来相对复杂一些(跨年计算)
- 总结
引言
项目中有一个需求:需要根据学期时间动态的计算出该学期有多少周
通过上网查找,找到了一个工具类moment.js
moment.js是一个JavaScript日期处理类库,能够实现对日期的便捷操作
官网地址:Moment.js
环境: 需要有Node环境支持
首先需要安装moment工具包
npm install moment
然后引入刚才下载的工具包
import moment from "moment"
因为使用的地方比较少,所以是在使用的.vue文件中引入的,如果整个项目使用比较多,可以在main.js中进行引入
一、获取本周一和周日日期
/** | |
* @params | |
* 获取本周周一和周日日期 | |
*/ | |
let start = moment().weekday(1).format('YYYY/MM/DD') //本周一 | |
let end = moment().weekday(7).format('YYYY/MM/DD') //本周日 | |
console.log(start, end) | |
// 输出结果 | |
2022/04/11 2022/04/17 |
二、获取前 i 周的周一和周日日期
/** | |
* @params | |
* 获取前 i 周的周一和周日日期 | |
* 当 i=1,获取的是上周一和上周日的日期; | |
* 当 i=2,获取的是上上周一和上上周日的日期 | |
* ...以此类推 | |
*/ | |
let week = 3 // 周数 | |
let weekOfDay = new Date().getDay() // 今天星期几 | |
for (let i = 0; i < week; i++) { | |
let last_monday = '', last_sunday = '', obj = {}; | |
last_monday = moment().subtract(weekOfDay + 7 * i - 1, 'days').format('YYYY/MM/DD'); | |
last_sunday = moment().subtract(weekOfDay + 7 * (i - 1), 'days').format('YYYY/MM/DD'); | |
obj.date = `${last_monday} ~ ${last_sunday}` | |
console.log(obj) | |
} | |
// 打印结果 | |
{date: '2022/04/11 ~ 2022/04/17'} | |
{date: '2022/04/04 ~ 2022/04/10'} | |
{date: '2022/03/28 ~ 2022/04/03'} |
三、获取后 i 周的周一和周日日期
/** | |
* @params | |
* 获取后 i 周的周一和周日日期 | |
* 当 i = 1,获取的是下周一和下周日的日期 | |
* 当 i = 2,获取的是下下周一和下下周日的日期 | |
* ...以此类推 | |
*/ | |
let week = 3 // 周数 | |
let weekOfDay = new Date().getDay(); // 今天星期几 | |
for (let i = 0; i < week; i++) { | |
let last_monday = '', last_sunday = '', obj = {}; | |
last_monday = moment().add((7 - weekOfDay) + 7 * (i - 1) + 1, 'd').format('YYYY/MM/DD'); | |
last_sunday = moment().add((7 - weekOfDay) + 7 * i, 'd').format('YYYY/MM/DD'); | |
obj.date = `${last_monday} ~ ${last_sunday}` | |
console.log(obj) | |
} | |
// 打印结果 | |
{date: '2022/04/11 ~ 2022/04/17'} | |
{date: '2022/04/18 ~ 2022/04/24'} | |
{date: '2022/04/25 ~ 2022/05/01'} |
subtract:通过减去时间来改变原始的 moment;add:通过增加时间来改变原始的 moment
具体使用方法可以去官方文档查看
四、获取制定日期区间的周数(不跨年)
// 封装一个函数 用来处理 第 1 2 3...周 => 第 一 二 三...周 | |
formatTime(val) { | |
let arr = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]; | |
let len = val.toString().length; | |
if (len == 1) { // 长度为1,可以直接返回 | |
return arr[val - 1]; | |
} else { | |
let newarr = val.toString().split(""); | |
switch (newarr[0]) { | |
case "1": | |
return `${arr[arr.length - 1]}${ | |
newarr[1] == 0 ? "" : arr[newarr[1] - 1] | |
}`; | |
case "2": | |
return `${arr[newarr[0] - 1]}${arr[arr.length - 1]}${ | |
newarr[1] == 0 ? "" : arr[newarr[1] - 1] | |
}`; | |
} | |
} | |
} |
指定一个时间段,并做些简单的处理
/** | |
* @params | |
* 不跨年计算 | |
*/ | |
initTime(){ | |
let time = [ | |
'Thu Sep 01 2022 00:00:00 GMT+0800 (中国标准时间)', | |
'Sat Dec 31 2022 00:00:00 GMT+0800 (中国标准时间)' | |
] | |
// 对起止时间进行处理 | |
let beginTime = new Date(time[0]); | |
let endTime = new Date(time[1]); | |
// 开始时间 | |
let bY = beginTime.getFullYear(); | |
let bM = beginTime.getMonth() + 1; | |
bM = bM >= 10 ? bM : "0" + bM; | |
let bD = beginTime.getDate(); | |
bD = bD >= 10 ? bD : "0" + bD; | |
// 结束时间 | |
let eY = endTime.getFullYear(); | |
let eM = endTime.getMonth() + 1; | |
eM = eM >= 10 ? eM : "0" + eM; | |
let eD = endTime.getDate(); | |
eD = eD >= 10 ? eD : "0" + eD; | |
let week = moment(`${eY}-${eM}-${eD}`).week() - moment(`${bY}-${bM}-${bD}`).week() + 1; // 计算周数 用来循环 | |
let weekOfDay = new Date(`${bY}-${bM}-${bD}`).getDay(); // 获取当前周几 | |
let arr = [] // 存放结果数据 | |
for (let i = 0; i < week; i++) { | |
let next_monday = '', next_sunday = '', obj = {}; | |
next_monday = i == 0 ? `${bM}/${bD}` : moment(`${bY}-${bM}-${bD}`).add((7 - weekOfDay) + 7 * (i - 1) + 1, 'd').format('MM/DD'); | |
next_sunday = i == week - 1 ? `${eM}/${eD}` : moment(`${bY}-${bM}-${bD}`).add((7 - weekOfDay) + 7 * i, 'd').format('MM/DD'); | |
obj.date = `第${this.formatTime(i+1)}周 ${next_monday} ~ ${next_sunday}` | |
arr.push(obj) | |
} | |
console.log(arr); | |
} | |
// 打印结果 | |
{date: '第一周 09/01 ~ 09/04'} | |
{date: '第二周 09/05 ~ 09/11'} | |
{date: '第三周 09/12 ~ 09/18'} | |
{date: '第四周 09/19 ~ 09/25'} | |
{date: '第五周 09/26 ~ 10/02'} | |
{date: '第六周 10/03 ~ 10/09'} | |
{date: '第七周 10/10 ~ 10/16'} | |
{date: '第八周 10/17 ~ 10/23'} | |
{date: '第九周 10/24 ~ 10/30'} | |
{date: '第十周 10/31 ~ 11/06'} | |
{date: '第十一周 11/07 ~ 11/13'} | |
{date: '第十二周 11/14 ~ 11/20'} | |
{date: '第十三周 11/21 ~ 11/27'} | |
{date: '第十四周 11/28 ~ 12/04'} | |
{date: '第十五周 12/05 ~ 12/11'} | |
{date: '第十六周 12/12 ~ 12/18'} | |
{date: '第十七周 12/19 ~ 12/25'} | |
{date: '第十八周 12/26 ~ 12/31'} |
五、第一学期还涉及到跨年的情况,处理起来相对复杂一些(跨年计算)
这是一种通用的方式
// 封装一个方法用来获取时间 | |
formatYear(start, startVal, endVal, len) { | |
let arr = [] | |
let yearStart = new Date(start).getDay(); // 获取周几 | |
let initYearStart = yearStart; // 将周几重新赋值 | |
let initStart = ''; // 用来接收起始时间为周日的明天,也就是下周一个的日期 | |
for (let i = 0; i < len; i++) { | |
let next_monday = '', next_sunday = '', obj = {}; | |
if(yearStart != 0) { // 不等于0表示起始时间不是周日, 正常计算即可 | |
next_monday = i == 0 ? startVal : moment(start).add((7 - yearStart) + 7 * (i - 1) + 1, 'd').format('MM/DD'); | |
next_sunday = i == len - 1 ? endVal : moment(start).add((7 - yearStart) + 7 * i, 'd').format('MM/DD'); | |
} else { // else中表示起始时间是周日 | |
if(initYearStart == 0) { // 周日为0 表示起始时间和截止时间是同一天 | |
next_monday = next_sunday = startVal; | |
initYearStart = 1; // 重新赋值为1 表示以后的从周一开始 | |
initStart = moment(start).add(1, 'd').format('MM/DD'); | |
start = moment(initStart); | |
} else { | |
next_monday = i == 1 ? initStart : moment(start).add((7 - initYearStart) + 7 * (i - 2) + 1, 'd').format('MM/DD'); | |
next_sunday = i == len - 1 ? endVal : moment(start).add((7 - initYearStart) + 7 * (i - 1), 'd').format('MM/DD'); | |
} | |
} | |
obj.date = `第${this.formatTime(i+1)}周 ${next_monday} ~ ${next_sunday}`; // 这个函数在上面有写 | |
arr.push(obj); | |
} | |
return arr; | |
} | |
// 这个函数用来处理时间 | |
initTime(time) { | |
let beginTime = new Date(time[0]); | |
let endTime = new Date(time[1]); | |
// 开始时间 | |
let bY = beginTime.getFullYear(); | |
let bM = beginTime.getMonth() + 1; | |
bM = bM >= 10 ? bM : "0" + bM; | |
let bD = beginTime.getDate(); | |
bD = bD >= 10 ? bD : "0" + bD; | |
// 结束时间 | |
let eY = endTime.getFullYear(); | |
let eM = endTime.getMonth() + 1; | |
eM = eM >= 10 ? eM : "0" + eM; | |
let eD = endTime.getDate(); | |
eD = eD >= 10 ? eD : "0" + eD; | |
let arr = [] | |
let nowDiff = 0, futureWeek = 0 | |
if(bY != eY) { | |
let yearWeek = moment(`${bY}`).weeksInYear(); | |
let nowWeek = moment(`${bY}-${bM}-${bD}`).week(); | |
nowDiff = yearWeek - nowWeek; | |
futureWeek = moment(`${eY}-${eM}-${eD}`).week(); | |
} else { | |
let diff = moment(`${eY}/${eM}/${eD}`).week() - moment(`${bY}-${bM}-${bD}`).week(); | |
if(beginTime.getDay() == 0 && endTime.getDay() != 0) { | |
nowDiff = diff + 2; | |
} else if(beginTime.getDay() != 0 && endTime.getDay() == 0) { | |
nowDiff = diff; | |
} else { | |
nowDiff = diff + 1; | |
} | |
futureWeek = 0; | |
} | |
arr = this.formatYear(`${bY}-${bM}-${bD}`, `${bM}/${bD}`, `${eM}/${eD}`, nowDiff + futureWeek); | |
console.log(arr); | |
} |
测试用例
// 一个月测试 | |
let time = [ | |
'Thu Apr 14 2022 00:00:00 GMT+0800 (中国标准时间)', | |
'Sat May 14 2022 00:00:00 GMT+0800 (中国标准时间)' | |
] | |
initTime(time) | |
{date: '第一周 04/14 ~ 04/17'} | |
{date: '第二周 04/18 ~ 04/24'} | |
{date: '第三周 04/25 ~ 05/01'} | |
{date: '第四周 05/02 ~ 05/08'} | |
{date: '第五周 05/09 ~ 05/14'} | |
// 三个月测试 | |
let time = [ | |
'Thu Apr 14 2022 00:00:00 GMT+0800 (中国标准时间)', | |
'Thu Jul 14 2022 00:00:00 GMT+0800 (中国标准时间)' | |
] | |
{date: '第一周 04/14 ~ 04/17'} | |
{date: '第二周 04/18 ~ 04/24'} | |
{date: '第三周 04/25 ~ 05/01'} | |
{date: '第四周 05/02 ~ 05/08'} | |
{date: '第五周 05/09 ~ 05/15'} | |
{date: '第六周 05/16 ~ 05/22'} | |
{date: '第七周 05/23 ~ 05/29'} | |
{date: '第八周 05/30 ~ 06/05'} | |
{date: '第九周 06/06 ~ 06/12'} | |
{date: '第十周 06/13 ~ 06/19'} | |
{date: '第十一周 06/20 ~ 06/26'} | |
{date: '第十二周 06/27 ~ 07/03'} | |
{date: '第十三周 07/04 ~ 07/10'} | |
{date: '第十四周 07/11 ~ 07/14'} | |
// 跨年测试 | |
{date: '第一周 12/01 ~ 12/04'} | |
{date: '第二周 12/05 ~ 12/11'} | |
{date: '第三周 12/12 ~ 12/18'} | |
{date: '第四周 12/19 ~ 12/25'} | |
{date: '第五周 12/26 ~ 01/01'} | |
{date: '第六周 01/02 ~ 01/08'} | |
{date: '第七周 01/09 ~ 01/15'} | |
{date: '第八周 01/16 ~ 01/22'} | |
{date: '第九周 01/23 ~ 01/31'} | |
// element-ui 日期选择器默认周日为第一天 且 getDay()值为0 (以2022年为例) | |
// 开始时间为周日 结束时间为下周 | |
let time = ['2022-04-10', '2022-04-17'] | |
{date: '第一周 04/10 ~ 04/10'} | |
{date: '第二周 04/11 ~ 04/17'} | |
// 开始时间为周日 结束时间为周日测试 | |
let time = ['2022-04-10', '2022-05-01'] | |
{date: '第一周 04/10 ~ 04/10'} | |
{date: '第二周 04/11 ~ 04/17'} | |
{date: '第三周 04/18 ~ 04/24'} | |
{date: '第四周 04/25 ~ 05/01'} | |
// 开始时间为周日 结束时间为隔周任意 | |
let time = ['2022-04-10', '2022-04-29'] | |
{date: '第一周 04/10 ~ 04/10'} | |
{date: '第二周 04/11 ~ 04/17'} | |
{date: '第三周 04/18 ~ 04/24'} | |
{date: '第四周 04/25 ~ 04/29'} | |
// 开始时间为周日 结束时间为隔周周一 | |
let time = ['2022/04/10', '2022/04/18'] | |
{date: '第一周 04/10 ~ 04/10'} | |
{date: '第二周 04/11 ~ 04/17'} | |
{date: '第三周 04/18 ~ 04/18'} |
第五种方法基本处理了目前为止遇到的问题,更多详细用法可以去moment.js官网查看~