1. 程式人生 > 其它 >使用moment獲取本週、前n周、後n周開始結束日期以及動態計算週數

使用moment獲取本週、前n周、後n周開始結束日期以及動態計算週數

原文地址 https://blog.csdn.net/qq_43432158/article/details/124200343

專案中有一個需求:需要根據學期時間動態的計算出該學期有多少周

通過上網查詢,找到了一個工具類moment.js

moment.js是一個JavaScript日期處理類庫,能夠實現對日期的便捷操作

官網地址:Moment.js

環境: 需要有Node環境支援

首先需要安裝moment工具包

npm install moment
1
然後引入剛才下載的工具包

import moment from "moment"
1
因為使用的地方比較少,所以是在使用的.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
1
2
3
4
5
6
7
8
9
二、獲取前 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官網檢視~

今天的分項就到這裡了~