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;
};