chinese-days
Version:
中国节假日、调休日、工作日、24节气查询,农历阳历互转,支持 TS、CommonJS、UMD 模块化使用,提供 ics 日历格式,可供 Google Calendar、Apple Calendar、Microsoft Outlook 等客户端订阅。
116 lines (101 loc) • 3.52 kB
text/typescript
import dayjs, { Dayjs, type ConfigType } from "../utils/dayjs";
import { wrapDate, getDates } from '../utils'
import generate from './generate';
const { holidays, workdays, inLieuDays } = generate()
const _validateDate = (...dates: ConfigType[]): Dayjs | Dayjs[] => {
if (dates.length !== 1) {
return dates.map(date => _validateDate(date)) as Dayjs[];
}
const date = wrapDate(dates[0]);
if (!date.isValid()) {
throw new Error(`unsupported type ${typeof date}, expected type is Date or Dayjs`);
}
return date;
}
/** 是否节假日 */
const isHoliday = (date: ConfigType): boolean => {
return !isWorkday(date);
}
/** 是否工作日 */
const isWorkday = (date: ConfigType): boolean => {
const validDate = _validateDate(date) as Dayjs;
const weekday = validDate.day();
const formattedDate = validDate.format('YYYY-MM-DD');
return !!(workdays[formattedDate] || (weekday >= 1 && weekday <= 5 && !holidays[formattedDate]));
}
/** 是否调休日 - 是节假日,但后续有需要补班 */
const isInLieu = (date: ConfigType): boolean => {
date = _validateDate(date) as Dayjs;
return !!inLieuDays[date.format('YYYY-MM-DD')];
}
/** 获取工作日详情 */
const getDayDetail = (date: ConfigType): { work: boolean, name: string, date: string } => {
date = _validateDate(date) as Dayjs;
const formattedDate = date.format('YYYY-MM-DD')
if (workdays[formattedDate]) {
return {
date: formattedDate,
work: true,
name: workdays[formattedDate]
}
} else if (holidays[formattedDate]) {
return {
date: formattedDate,
work: false,
name: holidays[formattedDate]
}
} else {
const weekday = date.day();
return {
date: formattedDate,
work: weekday !== 0 && weekday !== 6,
name: date.format('dddd')
}
}
}
/** 获取节假日 */
const getHolidaysInRange = (start: ConfigType, end: ConfigType, includeWeekends: boolean = true): string[] => {
start = _validateDate(start) as Dayjs;
end = _validateDate(end) as Dayjs;
if (includeWeekends) {
return getDates(start, end).filter(isHoliday).map(date => date.format('YYYY-MM-DD'));
}
return getDates(start, end).filter(date => holidays[date.format('YYYY-MM-DD')]).map(date => date.format('YYYY-MM-DD'));
}
/** 获取工作日 */
const getWorkdaysInRange = (start: ConfigType, end: ConfigType, includeWeekends: boolean = true): string[] => {
start = _validateDate(start) as Dayjs;
end = _validateDate(end) as Dayjs;
if (includeWeekends) {
return getDates(start, end).filter(isWorkday).map(date => date.format('YYYY-MM-DD'));
}
return getDates(start, end).filter(date => isWorkday(date) && date.day() >= 1 && date.day() <= 5).map(date => date.format('YYYY-MM-DD'));
}
/* 查找从 date 开始 第 n 个工作日, 0 为当天 */
const findWorkday = (deltaDays: number = 0, date: ConfigType = dayjs()): string => {
date = wrapDate(date);
if (deltaDays === 0) {
if (isWorkday(date)) {
return date.format('YYYY-MM-DD');
}
deltaDays = 1;
}
const sign = deltaDays > 0 ? 1 : -1;
let daysToAdd = Math.abs(deltaDays);
while (daysToAdd > 0) {
date = date.add(sign, 'day');
if (isWorkday(date)) {
daysToAdd--;
}
}
return date.format('YYYY-MM-DD');
}
export {
isHoliday,
isWorkday,
isInLieu,
getDayDetail,
getHolidaysInRange,
getWorkdaysInRange,
findWorkday,
}