1. 程式人生 > >日歷方法整合

日歷方法整合

handle new 日歷 min ret format true 方便 nth

const ONEDAYTIME = 24 * 3600 * 1000;
/**
 * 獲取日期屬性(年,月,日,每周的第幾天)
 * @param {Date} time
 */
const getTimePart = (time) => {
    const year = time.getFullYear();
    const month = time.getMonth();
    const day = time.getDate();
    const week = time.getDay();
    return {year, month, day, week};
};

/**
 * 獲取下月的年和月
 * @param {*} year
 * @param {*} month
 */
const getNext = (year, month) => {
    let nextYear = year;
    let nextMonth = month + 1;
    if (month >= 11) {
        nextYear += 1;
        nextMonth = 0;
    };
    return {
        nextYear,
        nextMonth
    };
};

/**
 * 判斷是否是閏年
 * @param {*} year
 */
const isLeapYear = (year) => {
    return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
};

/**
 * 判斷這個月有多少天,2月的特殊
 * @param {*} year
 * @param {*} month
 */
const getDay = (year, month) => {
    const months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    return month === 1 && isLeapYear(year) ? 29 : months[month];
};

/**
 * 獲取本月第一天
 * @param {*} year
 * @param {*} month
 */
const getMinDay = (year, month) => {
    const time = new Date(year, month, 1);
    const timePart = getTimePart(time);
    let {week} = timePart;
    week === 0 && (week = 7); // 方便計算時間
    const minDay = new Date(time.getTime() - (week - 1) * ONEDAYTIME);
    return minDay;
};

/**
 * 獲取本月最後一天
 * @param {*} year
 * @param {*} month
 */
const getMaxDay = (year, month) => {
    const day = getDay(year, month);
    const time = new Date(year, month, day);
    const timePart = getTimePart(time);
    let {week} = timePart;
    // 防止多出一行日期
    week === 0 && (week = 7);
    const maxDay = new Date(time.getTime() + (7 - week) * ONEDAYTIME);
    return maxDay;
};

/**
 * 獲取某月的日期數據
 * @param {*} year
 * @param {*} month
 */
const getCalendar = (year, month) => {
    const minDay = getMinDay(year, month);
    const maxDay = getMaxDay(year, month);
    const currentDate = getTimePart(new Date());
    const {year: currentYear, month: currentMonth, day: currentDay} = currentDate;
    const calendar = [];
    let time = minDay.getTime();
    const maxTime = maxDay.getTime();
    while (time <= maxTime) {
        const timePart = getTimePart(new Date(time));
        const {month: calendarM, year: calendarY, day} = timePart;
        // 判斷是不是今天
        const isEqualToday = (calendarY === currentYear && calendarM === currentMonth && day === currentDay);
        // 判斷是不是本月且小於今天
        const isLessToday = (calendarY === currentYear && calendarM === currentMonth && day < currentDay);
        calendar.push({
            ...timePart,
            isLastMonth: calendarM !== month ? true : false,
            isLessToday: isLessToday ? true : false,
            format: calendarY + '-' + addZero(calendarM + 1) + '-' + addZero(day),
            stamp: time,
            text: isEqualToday ? '今天' : day,
            showStyle: isEqualToday ? 'text' : 'num'
        });
        time += ONEDAYTIME;
    };
    return calendar;
};

/**
 * 判斷日歷數據中是否包含節假日信息
 * 包含的話將日期改為對應的文字
 * @param {*} calendarData 日歷基本數據
 * @param {*} holidayData 節假日數據
 */
const handleHoliday = (calendarData, holidayData) => {
    try {
        calendarData.forEach((item, index) => {
            const {data = []} = item;
            data.forEach((i, j) => {
                const {format} = i;
                holidayData.forEach((m, n) => {
                    const {date, festival = ''} = m;
                    if (format === date && festival !== '') {
                        i.text = festival;
                        i.showStyle = 'text';
                    }
                });
            });
        });
    } catch (error) {
        console.log(error);
    }
};

/**
 * 獲取日歷數據
 * @param {*} holidayData 節假日,借用特殊接口數據,可以根據自己使用的接口,調整handleHoliday函數
 * @param {*} renderM 顯示幾個月份
 */
export const initCalendar = (holidayData, renderM) => {
    const now = new Date();
    const currentDate = getTimePart(now);
    const calendarData = [];
    const maxMonthNum = renderM; // 顯示幾個月份
    let {
        year: currentYear,
        month: currentMonth
    } = currentDate;
    for (let i = 0; i < maxMonthNum; i++) {
        calendarData.push({
            year: currentYear,
            month: currentMonth,
            data: getCalendar(currentYear, currentMonth, holidayData)
        });
        const next = getNext(currentYear, currentMonth);
        currentYear = next.nextYear;
        currentMonth = next.nextMonth;
    }
    handleHoliday(calendarData, holidayData);
    return calendarData;
};

日歷方法整合