index.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import { type ConfigType } from "../utils/dayjs";
  2. import dayjs from '../utils/dayjs';
  3. import { getLunarDate } from "../solar_lunar";
  4. import { LUNAR_FESTIVAL_MAP, SPECIAL_FESTIVAL_HANDLERS, type LunarFestival } from './constants'
  5. /**
  6. * 获取农历节日(包含固定节日和特殊计算节日)
  7. * @param start 开始日期
  8. * @param end 结束日期
  9. */
  10. export const getLunarFestivals = (
  11. start?: ConfigType,
  12. end?: ConfigType
  13. ): { date: string, name: string[] }[] => {
  14. const results: LunarFestival[] = [];
  15. let current = dayjs(start);
  16. const endDate = dayjs(end || start);
  17. // 遍历日期范围
  18. while (current.isBefore(endDate) || current.isSame(endDate)) {
  19. // 处理固定农历节日
  20. const lunar = getLunarDate(current);
  21. if (!lunar.isLeap) {
  22. const festivals = LUNAR_FESTIVAL_MAP[lunar.lunarMon]?.[lunar.lunarDay] || [];
  23. festivals.forEach(name => {
  24. results.push({
  25. date: current.format('YYYY-MM-DD'),
  26. name,
  27. type: 'lunar'
  28. });
  29. });
  30. }
  31. // 运行特殊节日处理器
  32. SPECIAL_FESTIVAL_HANDLERS.forEach(handler => handler(current, results));
  33. current = current.add(1, 'day');
  34. }
  35. // 去重并将同一日期的节日名称合并
  36. return results.reduce((acc: { date: string; name: string[] }[], curr) => {
  37. const existing = acc.find(item => item.date === curr.date)
  38. if (existing) {
  39. existing.name.push(curr.name)
  40. } else {
  41. acc.push({ date: curr.date, name: [curr.name] })
  42. }
  43. return acc
  44. }, [])
  45. };
  46. export default {
  47. getLunarFestivals
  48. }