UNPKG

jm-mrc-components

Version:

移动端可复用组件库

184 lines (168 loc) 3.87 kB
import { solarToLunar } from 'chinese-lunar' import memoize from 'lodash/memoize' export const holidays = { // 新历假日 gregorian: { '1-1': '元旦', '2-14': '情人节', '3-8': '妇女节', '5-1': '劳动节', '5-4': '青年节', '6-1': '儿童节', '7-1': '建党节', '8-1': '建军节', '9-10': '教师节', '10-1': '国庆节', // 动态节日(节气都是动态节日,暂时不展示) // '4-4': '清明节', // '12-22': '冬至', // '6-22': '夏至', '12-25': '圣诞节', }, lunar: { '12-8': '腊八', '12-29-leap': '除夕', '12-30': '除夕', '1-1': '春节', '1-15': '元宵节', '5-5': '端午节', '7-7': '七夕', '8-15': '中秋节', '9-9': '重阳节', }, byWeek: { '5-2-0': '母亲节', // 六月第三个星期日 '6-3-0': '父亲节', }, } /** * 获取节假日 */ export default function getHoliday(date: Date) { const gregorian = `${date.getMonth() + 1}-${date.getDate()}` if (gregorian in holidays.gregorian) { return holidays.gregorian[gregorian] } // 动态节日 const dynamicHolidays = getDynamicHoliday(date.getFullYear()) if (gregorian in dynamicHolidays) { return dynamicHolidays[gregorian] } for (let key in holidays.byWeek) { const [month, week, day] = key.split('-').map(i => parseInt(i)) if (month !== date.getMonth() + 1) { continue } if (day !== date.getDay()) { continue } const holiday = getNthWeek(date, week, day) if (holiday.getDate() === date.getDate()) { return holidays.byWeek[key] } } // 农历节假日 const lunar = solarToLunar(date) let lunarKey = `${lunar.month}-${lunar.day}` if (lunar.leap && lunar.month === 12) { lunarKey += '-leap' } return holidays.lunar[lunarKey] } export const getDynamicHoliday = memoize((year: number) => { let result: { [key: string]: string } = {} try { // const dongzhi = getDongzhiForYear(year) // result[`12-${dongzhi}`] = '冬至' const qingming = getQingMingForYear(year) result[`4-${qingming}`] = '清明' } catch { // ignore } return result }) export function getDongzhiForYear(year: number) { if (year == 2767) { return 23 } if (year == 2227 || year == 3068) { return 22 } if (year < 1700) { throw new TypeError('1700年以前暂时不支持') } if (year >= 3100) { throw new TypeError('3100年以后暂时不支持') } const coefficient = [ 22.11, 22.39, 22.66, 21.9, 22.18, 22.472, 22.72, 21.995, 22.27, 22.51, 22.75, 22.02, 22.27, 22.519, 22.8, ] const mod = year % 100 const index = Math.trunc(year / 100 - 17) return Math.trunc(mod * 0.2422 + coefficient[index] - Math.trunc(mod / 4)) } export function getQingMingForYear(year: number) { if (year == 2231) { return 23 } if (year == 2227 || year == 3068) { return 22 } if (year < 1700) { throw new TypeError('1700年以前暂时不支持') } if (year >= 3100) { throw new TypeError('3100年以后暂时不支持') } const coefficient = [ 5.15, 5.37, 5.59, 4.82, 5.02, 5.26, 5.48, 4.7, 4.92, 5.135, 5.36, 4.6, 4.81, 5.04, 5.26, ] const mod = year % 100 const index = Math.trunc(year / 100 - 17) return Math.trunc(mod * 0.2422 + coefficient[index] - Math.trunc(mod / 4)) } /** * 获取当月第N个星期* */ export function getNthWeek(date: Date, n: number, day: number) { const copy = new Date(date) copy.setDate(1) let firstDay = copy.getDay() // first week end if (firstDay > day) { copy.setDate(1 + 7 - (firstDay - day)) } else { copy.setDate(1 + (day - firstDay)) } copy.setDate(copy.getDate() + (n - 1) * 7) return copy }