UNPKG

chinese-days

Version:

中国节假日、调休日、工作日、24节气查询,农历阳历互转,支持 TS、CommonJS、UMD 模块化使用,提供 ics 日历格式,可供 Google Calendar、Apple Calendar、Microsoft Outlook 等客户端订阅。

142 lines (127 loc) 4.13 kB
import dayjs, { Dayjs, type ConfigType } from "../utils/dayjs"; import { wrapDate } from '../utils' import { SOLAR_TERMS_C_NUMS, SOLAR_TERMS_DELTA, SOLAR_TERMS_MONTH, SOLAR_TERMS, type SolarTermKey, } from "./constants"; /* Get solar term date => 获取节气日期 */ const getSolarTermDate = ( year: number, month: number, term: SolarTermKey ): string => { const century = year >= 2000 ? 21 : 20; const Y = year % 100; const D = 0.2422; const C = SOLAR_TERMS_C_NUMS[term][century === 21 ? 1 : 0]; let L = Math.floor(Y / 4); if ( [ "lesser_cold", "greater_cold", "the_beginning_of_spring", "rain_water", ].includes(term) ) { L = Math.floor((Y - 1) / 4); } let day = Math.floor(Y * D + C) - L; const delta = SOLAR_TERMS_DELTA[`${year}_${term}` as keyof typeof SOLAR_TERMS_DELTA]; if (delta) { day += delta; } return dayjs(`${year}-${month}-${day}`).format('YYYY-MM-DD'); }; export interface SolarTerm { date: string; term: SolarTermKey; name: string; index?: number; }; /** * Get solar terms => 获取范围日期内的节气 开始的日期 * @param start 开始日期 * @param end 不传只查当天 * @returns Array of solar terms => 节气开始日数组 */ const getSolarTerms = ( start?: ConfigType, end?: ConfigType ): SolarTerm[] => { const result: SolarTerm[] = []; let current = wrapDate(start); const endDate = wrapDate(end || start); while (current.isBefore(endDate) || current.isSame(endDate)) { const year = current.year(); const month = current.month() + 1; SOLAR_TERMS_MONTH[month].forEach((term: SolarTermKey) => { const solarTermDate = dayjs(getSolarTermDate(year, month, term)); if ( (solarTermDate?.isBefore(endDate) || solarTermDate?.isSame(endDate)) && (solarTermDate?.isAfter(current) || solarTermDate?.isSame(current)) ) { result.push({ date: solarTermDate.format("YYYY-MM-DD"), term, name: SOLAR_TERMS[term], index: 1, }); } }); /* 处理下个日期 */ month === 12 ? (current = current.add(1, "year").startOf("year")) : (current = current.add(1, "month").startOf("month")); } return result; }; /** * Get solar terms => 获取范围日期内的节气 * @param start 开始日期 * @param end 不传只查当天 * @returns Array of solar terms => 节气日数组 */ const getSolarTermsInRange = ( start?: ConfigType, end?: ConfigType ): SolarTerm[] => { // 从开始日减一个月 - 结束日下一个月 计算所有节气 let current = wrapDate(start).subtract(1, 'month'); const endDate = wrapDate(end || start).add(1, 'month'); const allTerms: { term: SolarTermKey, date: Dayjs }[] = [] while (current.isBefore(endDate) || current.isSame(endDate)) { const year = current.year(); const month = current.month() + 1; SOLAR_TERMS_MONTH[month].forEach((term: SolarTermKey) => { const solarTermDate = dayjs(getSolarTermDate(year, month, term)); allTerms.push({ term, date: solarTermDate }); }); if (current.month() === 11) { current = current.add(1, 'year').startOf('year'); } else { current = current.add(1, 'month').startOf('month'); } } // 计算中间的所有日期 const deltaDays: (Omit<SolarTerm, 'date'> & {day: Dayjs})[] = [] allTerms.forEach((term, index) => { for (let date = term.date; allTerms[index + 1] && date.isBefore(allTerms[index + 1].date); date = date.add(1, 'day')) { deltaDays.push({ day: date, term: term.term, name: SOLAR_TERMS[term.term], index: date.diff(term.date, 'day') + 1 }) } }) if (!end) end = start return deltaDays.filter(trem => trem.day.isBetween(start, end, 'day')).map(trem => ({ date: trem.day.format('YYYY-MM-DD'), term: trem.term, name: trem.name, index: trem.index })); }; export { getSolarTermDate, getSolarTerms, getSolarTermsInRange, }