123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import fs from "fs";
- import ical, {
- ICalEventClass,
- ICalEventStatus,
- ICalEventTransparency,
- } from "ical-generator";
- import generate from "../src/holidays/generate";
- import dayjs, { Dayjs } from "../src/utils/dayjs";
- import { Holiday } from "../src/holidays/arrangement";
- const { holidays, workdays, inLieuDays } = generate();
- const endYear = Number(Object.keys(holidays)[0].slice(0, 4))
- // 创建一个新的日历
- const cal = ical({
- name: "中国节假日",
- timezone: "Asia/Shanghai",
- prodId: { company: "yaavi.me", product: "Chinese Days", language: "CN" },
- });
- // 设置日历描述
- cal.description(`${endYear - 2}~${endYear}年中国节假日日历`);
- // 添加时区信息
- cal.timezone({
- name: "Asia/Shanghai",
- generator: (tzid) => `
- BEGIN:VTIMEZONE
- TZID:${tzid}
- X-LIC-LOCATION:${tzid}
- BEGIN:STANDARD
- TZOFFSETFROM:+0800
- TZOFFSETTO:+0800
- TZNAME:CST
- DTSTART:19700101T000000
- END:STANDARD
- END:VTIMEZONE`,
- });
- const buildHolidays = (
- year: number,
- days: Record<string, Holiday>,
- mark: "(休)" | "(班)" | string
- ) => {
- // 合并相同节日的日期
- const mergedHolidays: Record<
- string,
- {
- chineseName: string;
- dates: string[];
- }
- > = {};
- for (const [date, info] of Object.entries(days)) {
- if (date.startsWith(String(year))) {
- const [name, chineseName] = info.split(",");
- if (!mergedHolidays[name]) {
- mergedHolidays[name] = {
- chineseName,
- dates: [],
- };
- }
- mergedHolidays[name].dates.push(date);
- }
- }
- // 检查日期是否连续的函数
- const areDatesContinuous = (date1: Dayjs, date2: Dayjs) => {
- return dayjs(date2).diff(dayjs(date1), "day") === 1;
- };
- for (const [name, details] of Object.entries(mergedHolidays)) {
- const { chineseName, dates } = details;
- dates.sort(); // 确保日期按顺序排列
- let startDate = dayjs(dates[0]);
- let endDate = startDate;
- for (let i = 1; i < dates.length; i++) {
- const currentDate = dayjs(dates[i]);
- if (areDatesContinuous(endDate, currentDate)) {
- endDate = currentDate;
- } else {
- // 添加当前事件
- cal.createEvent({
- start: startDate.toDate(),
- end: endDate.add(1, "day").toDate(),
- description: `${chineseName}放假: 共${mark === '(休)' ? '休息' : '需补班'} ${dates.length} 天`,
- status: ICalEventStatus.CONFIRMED,
- summary: `${chineseName}${mark}`,
- transparency: ICalEventTransparency.TRANSPARENT,
- allDay: true,
- class: ICalEventClass.PUBLIC,
- });
- // 重置开始和结束日期
- startDate = currentDate;
- endDate = currentDate;
- }
- }
- // 添加最后一个事件
- cal.createEvent({
- start: startDate.toDate(),
- end: endDate.add(1, "day").toDate(),
- description: `${chineseName}放假: 共${mark === '(休)' ? '休息' : '需补班'} ${dates.length} 天`,
- status: ICalEventStatus.CONFIRMED,
- summary: `${chineseName}${mark}`,
- transparency: ICalEventTransparency.TRANSPARENT,
- allDay: true,
- class: ICalEventClass.PUBLIC,
- });
- }
- };
- for (let i = endYear; i > endYear - 3; i--) {
- buildHolidays(i, holidays, "(休)");
- buildHolidays(i, workdays, "(班)");
- }
- // 将日历保存到 ./dist/holidays.ics 文件
- fs.writeFile("./dist/holidays.ics", cal.toString(), "utf8", (err) => {
- if (err) throw err;
- console.log("The ICS file has been saved!");
- });
|