Browse Source

op: 目录文件结构

Yaavi 1 year ago
parent
commit
c24aad157e

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 node_modules/
 node_modules/
+dist/
 
 
 .DS_Store
 .DS_Store

+ 3 - 0
README.md

@@ -1,5 +1,8 @@
 # 中国节假日
 # 中国节假日
 
 
+![GitHub License](https://img.shields.io/github/license/vsme/china-days)
+
+
 本项目提供了一系列用于管理和查询中国节假日、调休日、工作日及二十四节气的函数。通过使用这些函数,用户可以方便地检查指定日期的状态,获取日期范围内的节假日或工作日,并查找特定的工作日。此外,项目还支持查询二十四节气的日期,帮助用户了解中国传统节气的时间安排。
 本项目提供了一系列用于管理和查询中国节假日、调休日、工作日及二十四节气的函数。通过使用这些函数,用户可以方便地检查指定日期的状态,获取日期范围内的节假日或工作日,并查找特定的工作日。此外,项目还支持查询二十四节气的日期,帮助用户了解中国传统节气的时间安排。
 
 
 支持 2004年 至 2024年,包括 2020年 的春节延长。
 支持 2004年 至 2024年,包括 2020年 的春节延长。

+ 1 - 1
index.html

@@ -7,6 +7,6 @@
   </head>
   </head>
   <body>
   <body>
     <!-- <script type="module" src="./solar_terms/index.ts"></script> -->
     <!-- <script type="module" src="./solar_terms/index.ts"></script> -->
-    <script type="module" src="./src/holidays/index.ts"></script>
+    <script type="module" src="./scripts/generate.ts"></script>
   </body>
   </body>
 </html>
 </html>

File diff suppressed because it is too large
+ 431 - 173
package-lock.json


+ 7 - 2
package.json

@@ -2,9 +2,11 @@
   "name": "china-days",
   "name": "china-days",
   "version": "1.0.0",
   "version": "1.0.0",
   "description": "中国日期的TS库,含有节假日、调休日、24节气等。",
   "description": "中国日期的TS库,含有节假日、调休日、24节气等。",
-  "main": "index.ts",
+  "main": "./src/index.ts",
+  "type": "module",
   "scripts": {
   "scripts": {
     "dev": "vite",
     "dev": "vite",
+    "generate": "ts-node scripts/generate.ts",
     "build": "tsc && vite build",
     "build": "tsc && vite build",
     "preview": "vite preview"
     "preview": "vite preview"
   },
   },
@@ -17,8 +19,11 @@
   "author": "Yaavi",
   "author": "Yaavi",
   "license": "MIT",
   "license": "MIT",
   "dependencies": {
   "dependencies": {
-    "dayjs": "^1.11.11",
+    "dayjs": "^1.11.11"
+  },
+  "devDependencies": {
     "serve": "^14.2.3",
     "serve": "^14.2.3",
+    "ts-node": "^10.9.2",
     "typescript": "^5.4.5",
     "typescript": "^5.4.5",
     "vite": "^5.2.11"
     "vite": "^5.2.11"
   }
   }

+ 15 - 2
src/holidays/generate.ts → scripts/generate.ts

@@ -1,6 +1,7 @@
-import { arrangement } from "./arrangement"
+import Arrangement from "../src/holidays/arrangement.ts"
 
 
 const generate = () => {
 const generate = () => {
+  const arrangement = new Arrangement()
   /**
   /**
    * 2024
    * 2024
    * https://www.gov.cn/zhengce/content/202310/content_6911527.htm
    * https://www.gov.cn/zhengce/content/202310/content_6911527.htm
@@ -469,6 +470,18 @@ const generate = () => {
   * 2002: https://zh.wikisource.org/zh-hans/国务院办公厅关于2002年部分节假日休息安排的通知
   * 2002: https://zh.wikisource.org/zh-hans/国务院办公厅关于2002年部分节假日休息安排的通知
   * 2001: https://zh.wikisource.org/zh-hans/国务院办公厅关于2001年春节、“五一”、“十一”放假安排的通知
   * 2001: https://zh.wikisource.org/zh-hans/国务院办公厅关于2001年春节、“五一”、“十一”放假安排的通知
   */
   */
+
+  console.log({
+    holidays: arrangement.holidays,
+    workdays: arrangement.workdays,
+    inLieuDays: arrangement.inLieuDays,
+  })
+
+  return {
+    holidays: arrangement.holidays,
+    workdays: arrangement.workdays,
+    inLieuDays: arrangement.inLieuDays,
+  }
 }
 }
 
 
-export default generate
+generate()

+ 0 - 0
scripts/init.js


+ 95 - 75
src/holidays/arrangement.ts

@@ -1,4 +1,4 @@
-import dayjs from 'dayjs';
+import dayjs from "dayjs";
 
 
 export enum Holiday {
 export enum Holiday {
   NewYearsDay = "New Year's Day,元旦,1",
   NewYearsDay = "New Year's Day,元旦,1",
@@ -27,90 +27,110 @@ enum DayType {
   InLieu = 3,
   InLieu = 3,
 }
 }
 
 
-const dayDetails: DayDetails = {};
+class Arrangement {
+  private dayDetails: DayDetails = {};
+  public holidays: Record<string, Holiday> = {};
+  public workdays: Record<string, Holiday> = {};
+  public inLieuDays: Record<string, Holiday> = {};
 
 
-const holidays: Record<string, Holiday> = {};
-const workdays: Record<string, Holiday> = {};
-const inLieuDays: Record<string, Holiday> = {};
+  yearAt(year: number) {
+    this.dayDetails.year = year;
+    return this;
+  }
 
 
-const yearAt = (year: number) => {
-  dayDetails.year = year;
-  return arrangement;
-}
+  mark(holiday: Holiday) {
+    this.dayDetails.holiday = holiday;
+    return this;
+  }
 
 
-const mark = (holiday: Holiday) => {
-  dayDetails.holiday = holiday;
-  return arrangement;
-}
+  save(month: number, day: number, dayType: DayType) {
+    if (!this.dayDetails.year) {
+      throw new Error("should set year before saving holiday");
+    }
+    if (!this.dayDetails.holiday) {
+      throw new Error("should set holiday before saving holiday");
+    }
+    this.dayDetails.dayType = dayType;
+    const date = dayjs(`${this.dayDetails.year}-${month}-${day}`);
+    if (dayType === DayType.Holiday) {
+      this.holidays[date.format("YYYY-MM-DD")] = this.dayDetails.holiday;
+    } else if (dayType === DayType.Workday) {
+      this.workdays[date.format("YYYY-MM-DD")] = this.dayDetails.holiday;
+    } else if (dayType === DayType.InLieu) {
+      this.inLieuDays[date.format("YYYY-MM-DD")] = this.dayDetails.holiday;
+    }
+    this.dayDetails.month = month;
+    this.dayDetails.day = day;
+    return this;
+  }
 
 
-/* 存储 */
-const save = (month: number, day: number, dayType: DayType) => {
-  if (!dayDetails.year) {
-    throw new Error("should set year before saving holiday");
+  to(month: number, day: number) {
+    if (
+      !this.dayDetails.year ||
+      !this.dayDetails.month ||
+      !this.dayDetails.day
+    ) {
+      throw new Error("should set year/month/day before saving holiday range");
+    }
+    const startDate = dayjs(
+      `${this.dayDetails.year}-${this.dayDetails.month}-${this.dayDetails.day}`
+    );
+    const endDate = dayjs(`${this.dayDetails.year}-${month}-${day}`);
+    if (endDate.isBefore(startDate) || endDate.isSame(startDate)) {
+      throw new Error("end date should be after start date");
+    }
+    const diffDays = endDate.diff(startDate, "day");
+    for (let i = 1; i <= diffDays; i++) {
+      const theDate = startDate.add(i, "day");
+      if (this.dayDetails.dayType === DayType.Holiday) {
+        this.holidays[theDate.format("YYYY-MM-DD")] = this.dayDetails
+          .holiday as Holiday;
+      } else if (this.dayDetails.dayType === DayType.Workday) {
+        this.workdays[theDate.format("YYYY-MM-DD")] = this.dayDetails
+          .holiday as Holiday;
+      } else if (this.dayDetails.dayType === DayType.InLieu) {
+        this.inLieuDays[theDate.format("YYYY-MM-DD")] = this.dayDetails
+          .holiday as Holiday;
+      }
+    }
+    return this;
   }
   }
-  if (!dayDetails.holiday) {
-    throw new Error("should set holiday before saving holiday");
+
+  work(month: number, day: number) {
+    return this.save(month, day, DayType.Workday);
   }
   }
-  dayDetails.dayType = dayType;
-  const date = dayjs(`${dayDetails.year}-${month}-${day}`);
-  if (dayType === DayType.Holiday) {
-    holidays[date.format('YYYY-MM-DD')] = dayDetails.holiday;
-  } else if (dayType === DayType.Workday) {
-    workdays[date.format('YYYY-MM-DD')] = dayDetails.holiday;
-  } else if (dayType === DayType.InLieu) {
-    inLieuDays[date.format('YYYY-MM-DD')] = dayDetails.holiday;
+  rest(month: number, day: number) {
+    return this.save(month, day, DayType.Holiday);
+  }
+  inLieu(month: number, day: number) {
+    return this.save(month, day, DayType.InLieu);
   }
   }
-  dayDetails.month = month;
-  dayDetails.day = day;
-  return arrangement;
-}
 
 
-/* 添加日期 */
-const to = (month: number, day: number) => {
-  if (!dayDetails.year || !dayDetails.month || !dayDetails.day) {
-    throw new Error("should set year/month/day before saving holiday range");
+  // Special holiday marker
+  nyd() {
+    return this.mark(Holiday.NewYearsDay);
   }
   }
-  const startDate = dayjs(`${dayDetails.year}-${dayDetails.month}-${dayDetails.day}`);
-  const endDate = dayjs(`${dayDetails.year}-${month}-${day}`);
-  if (endDate.isBefore(startDate) || endDate.isSame(startDate)) {
-    throw new Error("end date should be after start date");
+  sf() {
+    return this.mark(Holiday.SpringFestival);
   }
   }
-  const diffDays = endDate.diff(startDate, 'day');
-  for (let i = 1; i <= diffDays; i++) {
-    const theDate = startDate.add(i, 'day');
-    if (dayDetails.dayType === DayType.Holiday) {
-      holidays[theDate.format('YYYY-MM-DD')] = dayDetails.holiday as Holiday;
-    } else if (dayDetails.dayType === DayType.Workday) {
-      workdays[theDate.format('YYYY-MM-DD')] = dayDetails.holiday as Holiday;
-    } else if (dayDetails.dayType === DayType.InLieu) {
-      inLieuDays[theDate.format('YYYY-MM-DD')] = dayDetails.holiday as Holiday;
-    }
+  tsd() {
+    return this.mark(Holiday.TombSweepingDay);
+  }
+  ld() {
+    return this.mark(Holiday.LabourDay);
+  }
+  dbf() {
+    return this.mark(Holiday.DragonBoatFestival);
+  }
+  nd() {
+    return this.mark(Holiday.NationalDay);
+  }
+  maf() {
+    return this.mark(Holiday.MidAutumnFestival);
+  }
+  afd() {
+    return this.mark(Holiday.AntiFascist70thDay);
   }
   }
-  return arrangement;
 }
 }
 
 
-const arrangement = {
-  yearAt,
-  to,
-
-  work: (month: number, day: number) => save(month, day, DayType.Workday),
-  rest: (month: number, day: number) => save(month, day, DayType.Holiday),
-  inLieu: (month: number, day: number) => save(month, day, DayType.InLieu),
-  
-  // Special holiday markers
-  nyd: () => mark(Holiday.NewYearsDay),
-  sf: () => mark(Holiday.SpringFestival),
-  tsd: () => mark(Holiday.TombSweepingDay),
-  ld: () => mark(Holiday.LabourDay),
-  dbf: () => mark(Holiday.DragonBoatFestival),
-  nd: () => mark(Holiday.NationalDay),
-  maf: () => mark(Holiday.MidAutumnFestival),
-  afd: () => mark(Holiday.AntiFascist70thDay),
-};
-
-export {
-  arrangement,
-  holidays,
-  workdays,
-  inLieuDays
-}
+export default Arrangement;

+ 5 - 0
src/holidays/constants.ts

@@ -0,0 +1,5 @@
+import type { Holiday } from "./arrangement";
+
+export const holidays: Record<string, Holiday> = {};
+export const workdays: Record<string, Holiday> = {};
+export const inLieuDays: Record<string, Holiday> = {};

+ 8 - 30
src/holidays/index.ts

@@ -1,36 +1,12 @@
 import dayjs, { Dayjs } from 'dayjs';
 import dayjs, { Dayjs } from 'dayjs';
-import { holidays, workdays, inLieuDays } from './arrangement';
-import generate from './generate'
-
-generate()
-
-interface Holidays {
-  [key: string]: string;
-}
-
-interface DayDetails {
-  year: number | null;
-  month: number | null;
-  day: number | null;
-  holiday: string | null;
-  dayType: DayType | null;
-}
-
-enum DayType {
-  Holiday,
-  Workday,
-  InLieu
-}
-
-const _wrapDate = (date: dayjs.ConfigType): Dayjs => {
-  return dayjs(date);
-}
+import { wrapDate } from '../utils'
+import { holidays, workdays, inLieuDays } from './constants';
 
 
 const _validateDate = (...dates: dayjs.ConfigType[]): Dayjs | Dayjs[] => {
 const _validateDate = (...dates: dayjs.ConfigType[]): Dayjs | Dayjs[] => {
   if (dates.length !== 1) {
   if (dates.length !== 1) {
     return dates.map(date => _validateDate(date)) as Dayjs[];
     return dates.map(date => _validateDate(date)) as Dayjs[];
   }
   }
-  const date = _wrapDate(dates[0]);
+  const date = wrapDate(dates[0]);
   if (!date.isValid()) {
   if (!date.isValid()) {
     throw new Error(`unsupported type ${typeof date}, expected type is Date or Dayjs`);
     throw new Error(`unsupported type ${typeof date}, expected type is Date or Dayjs`);
   }
   }
@@ -86,8 +62,8 @@ const getDayDetail = (date: dayjs.ConfigType): { work: boolean, name: string } =
 }
 }
 
 
 const getDates = (start: dayjs.ConfigType, end: dayjs.ConfigType): Dayjs[] => {
 const getDates = (start: dayjs.ConfigType, end: dayjs.ConfigType): Dayjs[] => {
-  start = _wrapDate(start);
-  end = _wrapDate(end);
+  start = wrapDate(start);
+  end = wrapDate(end);
   const deltaDays = end.diff(start, 'day');
   const deltaDays = end.diff(start, 'day');
   return Array.from({ length: deltaDays + 1 }, (_, i) => start.add(i, 'day'));
   return Array.from({ length: deltaDays + 1 }, (_, i) => start.add(i, 'day'));
 }
 }
@@ -114,7 +90,7 @@ const getWorkdays = (start: dayjs.ConfigType, end: dayjs.ConfigType, includeWeek
 
 
 /* 查找从 date 开始 第 n 个工作日, 0 为当天 */
 /* 查找从 date 开始 第 n 个工作日, 0 为当天 */
 const findWorkday = (deltaDays: number = 0, date: dayjs.ConfigType = dayjs()): Dayjs => {
 const findWorkday = (deltaDays: number = 0, date: dayjs.ConfigType = dayjs()): Dayjs => {
-  date = _wrapDate(date);
+  date = wrapDate(date);
 
 
   if (deltaDays === 0) {
   if (deltaDays === 0) {
     if (isWorkday(date)) {
     if (isWorkday(date)) {
@@ -137,6 +113,8 @@ const findWorkday = (deltaDays: number = 0, date: dayjs.ConfigType = dayjs()): D
 }
 }
 
 
 export default {
 export default {
+  isHoliday,
+  isWorkday,
   isInLieu,
   isInLieu,
   getDayDetail,
   getDayDetail,
   getDates,
   getDates,

+ 1 - 0
src/index.ts

@@ -0,0 +1 @@
+export default {}

+ 1 - 1
src/solar_terms/constants.ts

@@ -58,7 +58,7 @@ export const SOLAR_TERMS_C_NUMS = {
 };
 };
 
 
 /** 月份和节气对应关系 */
 /** 月份和节气对应关系 */
-export const SOLAR_TERMS_MONTH = {
+export const SOLAR_TERMS_MONTH: { [key: number]: SolarTermKey[] } = {
   1: ["lesser_cold", "greater_cold"],
   1: ["lesser_cold", "greater_cold"],
   2: ["the_beginning_of_spring", "rain_water"],
   2: ["the_beginning_of_spring", "rain_water"],
   3: ["the_waking_of_insects", "the_spring_equinox"],
   3: ["the_waking_of_insects", "the_spring_equinox"],

+ 8 - 7
src/solar_terms/index.ts

@@ -1,4 +1,5 @@
 import dayjs from "dayjs";
 import dayjs from "dayjs";
+import { wrapDate } from '../utils'
 import {
 import {
   SOLAR_TERMS_C_NUMS,
   SOLAR_TERMS_C_NUMS,
   SOLAR_TERMS_DELTA,
   SOLAR_TERMS_DELTA,
@@ -7,11 +8,6 @@ import {
   type SolarTermKey,
   type SolarTermKey,
 } from "./constants";
 } from "./constants";
 
 
-// wrapDate to the start of the day
-const wrapDate = (date: dayjs.ConfigType): dayjs.Dayjs => {
-  return dayjs(date).startOf("day");
-};
-
 /* Get solar term date => 获取节气日期 */
 /* Get solar term date => 获取节气日期 */
 const getSolarTermDate = (
 const getSolarTermDate = (
   year: number,
   year: number,
@@ -36,7 +32,7 @@ const getSolarTermDate = (
   }
   }
 
 
   let day = Math.floor(Y * D + C) - L;
   let day = Math.floor(Y * D + C) - L;
-  const delta = SOLAR_TERMS_DELTA[`${year}_${term}`];
+  const delta = SOLAR_TERMS_DELTA[`${year}_${term}` as keyof typeof SOLAR_TERMS_DELTA];
   if (delta) {
   if (delta) {
     day += delta;
     day += delta;
   }
   }
@@ -56,7 +52,7 @@ export interface SolarTerm {
  * @param end 不传只查当天
  * @param end 不传只查当天
  * @returns Array of solar terms => 节气数组
  * @returns Array of solar terms => 节气数组
  */
  */
-export const getSolarTerms = (
+const getSolarTerms = (
   start: dayjs.ConfigType,
   start: dayjs.ConfigType,
   end?: dayjs.ConfigType
   end?: dayjs.ConfigType
 ): SolarTerm[] => {
 ): SolarTerm[] => {
@@ -90,3 +86,8 @@ export const getSolarTerms = (
 
 
   return result;
   return result;
 };
 };
+
+export default {
+  getSolarTermDate,
+  getSolarTerms,
+}

+ 6 - 0
src/utils/index.ts

@@ -0,0 +1,6 @@
+import dayjs from "dayjs";
+
+// wrapDate to the start of the day
+export const wrapDate = (date: dayjs.ConfigType): dayjs.Dayjs => {
+  return dayjs(date).startOf("day");
+};

+ 26 - 0
tsconfig.json

@@ -0,0 +1,26 @@
+{
+  "compilerOptions": {
+    "target": "esnext",
+    "lib": ["esnext"],
+    "module": "esnext",
+    "moduleResolution": "node",
+    "forceConsistentCasingInFileNames": true,
+    "strict": true,
+    "noImplicitReturns": true,
+    "allowSyntheticDefaultImports": true,
+    "esModuleInterop": true,
+    "baseUrl": "./",
+    "declaration": true,
+    "outDir": "./dist",
+    "inlineSources": true,
+    "sourceMap": true,
+    "rootDir": "src",
+    "allowJs": true,
+    "skipLibCheck": true,
+    "noEmit": true,
+    "resolveJsonModule": true,
+    "isolatedModules": true
+  },
+  "include": ["src/**/*"],
+  "exclude": ["node_modules"]
+}

Some files were not shown because too many files changed in this diff