Browse Source

docs: complete zh documentation

Yaavi 8 months ago
parent
commit
af8e9d028c

+ 1 - 1
.github/workflows/deploy-docs.yml

@@ -40,4 +40,4 @@ jobs:
         uses: peaceiris/actions-gh-pages@v4
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
-          publish_dir: ./docs/dist
+          publish_dir: ./docs/.vitepress/dist

+ 5 - 4
docs/.vitepress/en.ts

@@ -10,8 +10,8 @@ export const en = defineConfig({
   themeConfig: {
     // https://vitepress.dev/reference/default-theme-config
     nav: [
-      { text: 'Guide', link: '/en/guide/getting-started' },
-      { text: 'Calendar', link: '/en/demo/calendar' },
+      { text: 'Guide', link: '/en/guide/what-is-chinese-days' },
+      { text: 'Demo', link: '/en/demo/calendar' },
       {
         text: pkg.version,
         link: 'https://github.com/vsme/chinese-days/blob/main/CHANGELOG.md'
@@ -68,10 +68,11 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
         { text: 'Lunar to Solar', link: 'from-lunar' }
       ]
     },
-    { text: 'Contributing',
+    { text: 'Else',
       collapsed: false,
       items: [
-        { text: 'Improve together', link: 'contributing' }
+        { text: 'Contributing', link: 'contributing' },
+        { text: 'Thank', link: 'thank' }
       ]
     }
   ]

+ 18 - 0
docs/.vitepress/theme/custom.css

@@ -3,4 +3,22 @@
   --vp-c-brand-2: #e75c5c;
   --vp-c-brand-3: #dd3e3e;
   --vp-c-brand-soft: rgba(255, 100, 100, 0.16);
+
+  --vp-home-hero-name-color: transparent;
+  --vp-home-hero-name-background: linear-gradient(120deg, #fe3480 30%, #ffd941);
+
+  --vp-home-hero-image-background-image: linear-gradient(-45deg, #fe3480 50%, #ffd941 50%);
+  --vp-home-hero-image-filter: blur(44px);
+}
+
+@media (min-width: 640px) {
+  :root {
+    --vp-home-hero-image-filter: blur(56px);
+  }
+}
+
+@media (min-width: 960px) {
+  :root {
+    --vp-home-hero-image-filter: blur(68px);
+  }
 }

+ 5 - 4
docs/.vitepress/zh.ts

@@ -10,8 +10,8 @@ export const zh = defineConfig({
   themeConfig: {
     // https://vitepress.dev/reference/default-theme-config
     nav: [
-      { text: '指南', link: '/guide/getting-started' },
-      { text: '日历', link: '/demo/calendar' },
+      { text: '指南', link: '/guide/what-is-chinese-days' },
+      { text: '示例', link: '/demo/calendar' },
       {
         text: pkg.version,
         link: 'https://github.com/vsme/chinese-days/blob/main/CHANGELOG.md'
@@ -92,10 +92,11 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
         { text: '农历转阳历', link: 'from-lunar' }
       ]
     },
-    { text: '贡献指南',
+    { text: '其他',
       collapsed: false,
       items: [
-        { text: '一起来完善', link: 'contributing' }
+        { text: '贡献指南', link: 'contributing' },
+        { text: '致谢', link: 'thank' }
       ]
     }
   ]

+ 532 - 0
docs/components/calendar-comp.vue

@@ -0,0 +1,532 @@
+<script lang="ts" setup>
+import { computed, ref } from 'vue'
+import chineseDays from "chinese-days"
+
+const { getDayDetail, getLunarDate, getSolarTermsInRange, isInLieu } = chineseDays
+
+const props = withDefaults(
+  defineProps<{
+    lang: 'zh' | 'en'
+    startOfWeek?: 1 | 2 | 3 | 4 | 5 | 6 | 0
+  }>(),
+  {
+    lang: 'zh',
+    startOfWeek: 1,
+  },
+)
+
+const currentDate = ref(new Date())
+const currentMonth = ref(currentDate.value.getMonth())
+const currentYear = ref(currentDate.value.getFullYear())
+const daysOfWeek = computed(() =>
+  props.lang === 'zh'
+    ? ['日', '一', '二', '三', '四', '五', '六']
+    : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+)
+const monthNames = [
+  'January',
+  'February',
+  'March',
+  'April',
+  'May',
+  'June',
+  'July',
+  'August',
+  'September',
+  'October',
+  'November',
+  'December',
+]
+
+const daysInMonth = computed(() => {
+  const year = currentYear.value
+  const month = currentMonth.value
+  const firstDay = new Date(year, month, 1)
+  const lastDay = new Date(year, month + 1, 0)
+  const days: Date[] = []
+
+  let firstDayIndex = firstDay.getDay() - props.startOfWeek
+  if (firstDayIndex < 0) {
+    firstDayIndex += 7
+  }
+
+  for (let i = firstDayIndex; i > 0; i--) {
+    days.push(new Date(year, month, -i + 1))
+  }
+
+  for (let day = 1; day <= lastDay.getDate(); day++) {
+    days.push(new Date(year, month, day))
+  }
+
+  let lastDayIndex = lastDay.getDay() - props.startOfWeek
+  if (lastDayIndex < 0) {
+    lastDayIndex += 7
+  }
+  for (let i = 1; i < 7 - lastDayIndex; i++) {
+    days.push(new Date(year, month + 1, i))
+  }
+
+  return days
+})
+
+function prevMonth() {
+  if (currentMonth.value === 0) {
+    currentMonth.value = 11
+    currentYear.value--
+  }
+  else {
+    currentMonth.value--
+  }
+}
+
+function nextMonth() {
+  if (currentMonth.value === 11) {
+    currentMonth.value = 0
+    currentYear.value++
+  }
+  else {
+    currentMonth.value++
+  }
+}
+
+function isToday(date: Date) {
+  const today = new Date()
+  return (
+    date.getDate() === today.getDate()
+    && date.getMonth() === today.getMonth()
+    && date.getFullYear() === today.getFullYear()
+  )
+}
+
+function getDayInfo(date: Date) {
+  const dayDetail = getDayDetail(date)
+  const holidayName = dayDetail.name.split(',')[1]
+  return {
+    disable: currentMonth.value !== date.getMonth(),
+    isToday: isToday(date),
+    isInLieu: isInLieu(date),
+    solarTerm: getSolarTermsInRange(date)[0],
+    ...getLunarDate(date),
+    ...dayDetail,
+    holidayName,
+    date,
+  }
+}
+
+const selectedDate = ref(getDayInfo(new Date()))
+function selectDate(date: any) {
+  selectedDate.value = date
+}
+
+function isSelected(date: Date) {
+  return (
+    date.getDate() === selectedDate.value?.date.getDate()
+    && date.getMonth() === selectedDate.value?.date.getMonth()
+    && date.getFullYear() === selectedDate.value?.date.getFullYear()
+  )
+}
+
+const daysInfo = computed(() => daysInMonth.value.map((date: Date) => getDayInfo(date)))
+</script>
+
+<template>
+  <div class="calendar">
+    <header class="calendar-header">
+      <button @click="prevMonth">
+        <svg
+          viewBox="0 0 1024 1024"
+          version="1.1"
+          xmlns="http://www.w3.org/2000/svg"
+          width="200"
+          height="200"
+        >
+          <path
+            d="M684.29 799.276L393.929 513.019 684.29 226.762c37.685-37.153 38.003-97.625 0.707-134.384-37.297-36.758-98.646-36.435-136.331 0.718l-357.43 352.378c-0.155 0.153-0.297 0.314-0.451 0.468-0.084 0.082-0.172 0.157-0.256 0.239-18.357 18.092-27.581 41.929-27.743 65.902-0.004 0.311-0.017 0.623-0.018 0.934 0.001 0.316 0.014 0.632 0.018 0.948 0.165 23.97 9.389 47.803 27.743 65.892 0.083 0.082 0.171 0.157 0.255 0.239 0.154 0.154 0.296 0.315 0.452 0.468l357.43 352.378c37.685 37.153 99.034 37.476 136.331 0.718 37.297-36.758 36.979-97.231-0.707-134.384z"
+            fill="currentColor"
+          />
+        </svg>
+      </button>
+      <h2 v-if="lang === 'zh'">
+        <select v-model="currentYear" style="width: 130px;">
+          <option v-for="(y, index) in 201" :key="index" :value="1900 + index">
+            {{ 1900 + index }}
+          </option>
+        </select>
+        年
+        <select v-model="currentMonth">
+          <option v-for="(month, index) in 12" :key="index" :value="index">
+            {{ month < 10 ? `0${month}` : month }}
+          </option>
+        </select>
+        月
+      </h2>
+      <h2 v-else>        
+        <select v-model="currentMonth" style="width: 160px;">
+          <option v-for="(month, index) in 12" :key="index" :value="index">
+            {{ monthNames[month - 1] }}
+          </option>
+        </select>
+        
+        <select v-model="currentYear">
+          <option v-for="(y, index) in 201" :key="index" :value="1900 + index">
+            {{ 1900 + index }}
+          </option>
+        </select>
+      </h2>
+      <button @click="nextMonth">
+        <svg
+          class="r"
+          viewBox="0 0 1024 1024"
+          version="1.1"
+          xmlns="http://www.w3.org/2000/svg"
+          width="200"
+          height="200"
+        >
+          <path
+            d="M684.29 799.276L393.929 513.019 684.29 226.762c37.685-37.153 38.003-97.625 0.707-134.384-37.297-36.758-98.646-36.435-136.331 0.718l-357.43 352.378c-0.155 0.153-0.297 0.314-0.451 0.468-0.084 0.082-0.172 0.157-0.256 0.239-18.357 18.092-27.581 41.929-27.743 65.902-0.004 0.311-0.017 0.623-0.018 0.934 0.001 0.316 0.014 0.632 0.018 0.948 0.165 23.97 9.389 47.803 27.743 65.892 0.083 0.082 0.171 0.157 0.255 0.239 0.154 0.154 0.296 0.315 0.452 0.468l357.43 352.378c37.685 37.153 99.034 37.476 136.331 0.718 37.297-36.758 36.979-97.231-0.707-134.384z"
+            fill="currentColor"
+          />
+        </svg>
+      </button>
+    </header>
+    <div class="calendar-grid">
+      <div v-for="(day, i) in 7" :key="day" class="calendar-day">
+        {{ daysOfWeek[daysInfo[i].date.getDay()] }}
+      </div>
+      <div
+        v-for="(day, index) in daysInfo"
+        :key="index"
+        class="calendar-cell"
+        :class="{
+          today: day.isToday,
+          disable: day.disable,
+          holiday: day.holidayName,
+          inlieu: day.isInLieu,
+          work: day.holidayName && day.work,
+          solar: day.solarTerm?.index === 1,
+          selected: isSelected(day.date),
+        }"
+        @click="selectDate(day)"
+      >
+        <span v-if="day.isToday" class="today-dot">{{ lang === 'en' ? 'Today' : '今' }}</span>
+        <span v-if="day.holidayName" class="holiday-dot">{{
+          day.work ? '班' : day.isInLieu ? '调' : '休'
+        }}</span>
+        <span class="day">{{ day.date.getDate() }}</span>
+        <span class="desc">{{
+          day.solarTerm?.index === 1 ? day.solarTerm?.name : day.holidayName || day.lunarDayCN
+        }}</span>
+      </div>
+    </div>
+  </div>
+
+  <div class="calendar-day-info">
+    <div class="left">
+      <p>
+        {{ selectedDate.lunarYearCN }}
+        {{ selectedDate.lunarMonCN }}{{ selectedDate.lunarDayCN }}
+      </p>
+      <p>
+        {{ selectedDate.yearCyl }}{{ selectedDate.zodiac }}年 {{ selectedDate.monCyl }}月
+        {{ selectedDate.dayCyl }}日
+      </p>
+    </div>
+    <div class="right">
+      <p>
+        {{ selectedDate.isToday ? '今天是' : '此日是' }}
+        <span>{{ selectedDate.solarTerm?.name }}</span> 节气的第
+        <span>{{ selectedDate.solarTerm?.index }}</span> 天。
+      </p>
+      <p>
+        {{
+          selectedDate.work
+            ? '又是需要工作的一天!😥'
+            : selectedDate.isInLieu
+              ? '虽然调休,但要补班还回来的!🤬'
+              : '休息啦~😃'
+        }}
+      </p>
+    </div>
+  </div>
+</template>
+
+<style lang="postcss">
+body {
+  --calendar-max-width: 660px;
+  --calendar-padding: 30px;
+  --calendar-border-width: 1px;
+  --calendar-grid-gap: 18px 12px;
+  --calendar-border-radius: 10px;
+}
+
+@media screen and (max-width: 560px) {
+  body {
+    --calendar-padding: 10px;
+    --calendar-border-width: 0;
+    --calendar-grid-gap: 12px 6px;
+    --calendar-border-radius: 0;
+  }
+}
+</style>
+
+<style lang="postcss" scoped>
+.calendar {
+  max-width: var(--calendar-max-width);
+  margin: 0 auto;
+  padding: var(--calendar-padding);
+  border: var(--calendar-border-width) solid var(--vp-c-gray-2);
+  border-radius: var(--calendar-border-radius);
+  position: relative;
+  background: var(--vp-c-bg);
+  z-index: 1;
+
+  h2, p {
+    margin: 0;
+    padding: 0;
+    border: 0;
+  }
+
+  select {
+    font-size: 24px;
+    width: 100px;
+    margin: 0 15px;
+    font-weight: bold;
+    text-align: center;
+    border: 1px solid var(--vp-c-default-3);
+    border-radius: 6px;
+  }
+
+  .calendar-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: calc(20px + var(--calendar-padding));
+
+    button {
+      display: flex;
+      flex-flow: column nowrap;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      width: 40px;
+      height: 40px;
+      opacity: 0.5;
+      transition: all 0.2s ease;
+      &:hover {
+        opacity: 0.8;
+      }
+      svg {
+        width: 22px;
+        height: 22px;
+        &.r {
+          transform: rotate(180deg);
+        }
+      }
+    }
+    h2 {
+      font-size: 24px;
+      font-weight: bold;
+    }
+  }
+
+  @media screen and (max-width: 560px) {
+    .calendar-header {
+      button {
+        width: 30px;
+        height: 30px;
+        svg {
+          width: 18px;
+          height: 18px;
+        }
+      }
+      h2 {
+        font-size: 18px;
+      }
+    }
+  }
+
+  .calendar-grid {
+    display: grid;
+    grid-template-columns: repeat(7, 1fr);
+    gap: var(--calendar-grid-gap);
+
+    .calendar-day {
+      font-weight: bold;
+      text-align: center;
+      line-height: 3;
+    }
+
+    .calendar-cell {
+      min-height: 70px;
+      display: flex;
+      flex-flow: column nowrap;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      border-radius: var(--calendar-border-radius);
+      position: relative;
+      transition: all 0.2s ease;
+      color: var(--vp-c-text-1);
+
+      &:nth-child(7n + 6),
+      &:nth-child(7n + 7) {
+        .day {
+          color: #eb3333;
+        }
+      }
+
+      .day {
+        font-size: 24px;
+        font-weight: bold;
+      }
+      .desc {
+        font-size: 12px;
+      }
+
+      .today-dot,
+      .holiday-dot {
+        position: absolute;
+        right: -6px;
+        top: -6px;
+        font-size: 12px;
+        padding: 0 4px;
+        border-radius: 4px;
+        min-width: 20px;
+        line-height: 20px;
+        transform: scale(0.9);
+      }
+
+      &.work {
+        background: transparent;
+      }
+
+      &.holiday {
+        &:not(&.work) {
+          background: rgba(235, 51, 51, 0.05);
+          color: #eb3333;
+        }
+        /** background: #f28c28; */
+        .holiday-dot {
+          background: #eb3333;
+          color: #fff;
+        }
+        &.work {
+          .day {
+            color: #4e5877;
+          }
+          .holiday-dot {
+            background: #4e5877;
+            color: #fff;
+          }
+        }
+      }
+
+      &:hover {
+        background: rgba(118, 142, 240, 0.2);
+        color: var(--vp-c-text-1);
+      }
+
+      &.solar {
+        .desc {
+          color: #f28c28;
+          border: 1px solid #f28c28;
+          border-radius: 4px;
+          padding: 0 4px;
+        }
+      }
+
+      &.today {
+        color: #4e6ef2;
+        .today-dot {
+          background: #6b88ff;
+          color: #fff;
+        }
+
+        &.selected {
+          background: #4e6ef2;
+          color: #fff;
+        }
+      }
+
+      &.selected {
+        background: #4e6ef2 !important;
+        color: #fff !important;
+        .day {
+          color: #fff !important;
+        }
+        &.solar {
+          .desc {
+            color: #fff;
+            border: 1px solid #fff;
+          }
+        }
+      }
+
+      &.disable {
+        opacity: 0.2;
+        pointer-events: none;
+      }
+    }
+  }
+}
+
+.calendar-day-info {
+  max-width: var(--calendar-max-width);
+  margin: 0 auto;
+  padding: 50px 20px 30px;
+  background: var(--vp-c-gray-3);
+  border: var(--calendar-border-width) solid var(--vp-c-gray-3);
+  border-radius: var(--calendar-border-radius);
+  position: relative;
+  top: -20px;
+  z-index: 0;
+  font-size: 16px;
+  display: flex;
+  align-items: center;
+
+  .left {
+    display: flex;
+    flex-flow: column nowrap;
+    align-items: flex-start;
+    margin-right: var(--calendar-padding);
+    p {
+      font-weight: bold;
+      font-size: 14px;
+      margin: 0;
+      &:first-child {
+        font-size: 22px;
+      }
+    }
+  }
+
+  .right {
+    display: flex;
+    flex-flow: column nowrap;
+    align-items: flex-start;
+    padding-left: var(--calendar-padding);
+    border-left: 1px solid var(--vp-c-gray-2);
+    p {
+      font-size: 14px;
+      margin: 0;
+      span {
+        font-weight: bold;
+      }
+      &:first-child {
+        font-size: 18px;
+      }
+    }
+  }
+
+  @media screen and (max-width: 560px) {
+    .left,
+    .right {
+      p {
+        font-size: 12px;
+        &:first-child {
+          font-size: 14px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 5 - 0
docs/en/demo/calendar.md

@@ -0,0 +1,5 @@
+<script setup>
+  import Calendar from '../../components/calendar-comp.vue'
+</script>
+
+<Calendar lang="en" />

+ 0 - 0
docs/en/guide/thank.md


File diff suppressed because it is too large
+ 0 - 0
docs/en/index.md


+ 1 - 0
docs/public/CNAME

@@ -0,0 +1 @@
+chinese-days.yaavi.me

+ 5 - 0
docs/zh/demo/calendar.md

@@ -0,0 +1,5 @@
+<script setup>
+  import Calendar from '../../components/calendar-comp.vue'
+</script>
+
+<Calendar lang="zh" />

+ 58 - 0
docs/zh/guide/24-solar-terms.md

@@ -0,0 +1,58 @@
+# 节气模块
+
+中国的二十四节气是传统的农业历法,它们标志着一年中不同的**时间段**。每个节气通常有特定的(开始)日期,但这个日期并不代表整个节气的持续时间。事实上,每个节气大约持续15天。
+
+以“小满”为例,它的日期通常在公历5月20日左右开始,但并不止于这一天,而是持续到下一个节气开始。具体来说,小满大约持续到6月5日(芒种)前后。因此,“小满”节气的时间段是从5月20日左右到6月5日左右。
+
+## 获取 24 节气的日期
+
+### 获取范围内节气日期数组
+
+```js
+import { getSolarTermsInRange } from "chinese-days";
+
+// 不传,查询当天
+console.log(getSolarTermsInRange())
+// [{date: '2024-05-29', term: 'lesser_fullness_of_grain', name: '小满', index: 10}]
+// index: 代表处于当前节气的第几天,从 1 开始
+
+// 不传end,查询指定日期
+console.log(getSolarTermsInRange('2024-05-01'))
+// [{date: '2024-05-01', term: 'grain_rain', name: '谷雨', index: 13}]
+
+// 查询范围内的节气
+console.log(getSolarTermsInRange('2024-05-01', '2024-05-06'))
+/**
+ * =>
+ * [
+ *   {"date":"2024-05-01","term":"grain_rain","name":"谷雨","index":13},
+ *   {"date":"2024-05-02","term":"grain_rain","name":"谷雨","index":14},
+ *   {"date":"2024-05-03","term":"grain_rain","name":"谷雨","index":15},
+ *   {"date":"2024-05-04","term":"grain_rain","name":"谷雨","index":16},
+ *   {"date":"2024-05-05","term":"the_beginning_of_summer","name":"立夏","index":1},
+ *   {"date":"2024-05-06","term":"the_beginning_of_summer","name":"立夏","index":2}
+ * ]
+ **/
+```
+
+### 如果你仅想获取节气**开始日期**数组
+
+```js
+import { getSolarTerms } from "chinese-days";
+
+/** 获取范围内 节气的开始日期数组 */
+const solarTerms = getSolarTerms("2024-05-01", "2024-05-20");
+solarTerms.forEach(({ date, term, name }) => {
+  console.log(`${name}: ${date}, ${term}`);
+});
+// 立夏: 2024-05-05, the_beginning_of_summer
+// 小满: 2024-05-20, lesser_fullness_of_grain
+
+// 没有节气 返回 []
+getSolarTerms("2024-05-21", "2024-05-25");
+// return []
+
+/* 不传 end 参数, 获取某天 节气 */
+getSolarTerms("2024-05-20");
+// return: [{date: '2024-05-20', term: 'lesser_fullness_of_grain', name: '小满'}]
+```

+ 7 - 0
docs/zh/guide/contributing.md

@@ -0,0 +1,7 @@
+# 贡献代码
+
+1. Fork + Clone 项目到本地;
+2. 节假日: 修改 [节假日定义](https://github.com/vsme/chinese-days/blob/main/src/holidays/generate.ts);
+3. 农历定义: 修改 [农历定义](https://github.com/vsme/chinese-days/blob/main/src/solar_lunar/constants.ts);
+4. 其他修改...;
+5. 提交PR。

+ 11 - 0
docs/zh/guide/from-lunar.md

@@ -0,0 +1,11 @@
+# 农历转换阳历
+
+当为阴历闰月的时候,会出现一个农历日期对应两个阳历日期的情况,所以返回对象形式。
+
+```js
+console.log(getSolarDateFromLunar('2001-03-05'));
+// {date: '2001-03-29', leapMonthDate: undefined}
+
+console.log(getSolarDateFromLunar('2001-04-05'));
+// {date: '2001-04-27', leapMonthDate: '2001-05-27'}
+```

+ 59 - 0
docs/zh/guide/getting-started.md

@@ -0,0 +1,59 @@
+# 快速开始
+
+本文档内容主要针对 `JS` 和 `TS` 开发用户,使用其他语言请参考 [开发](/guide/what-is-chinese-days#非-js-语言)。
+
+## 推荐方式
+
+直接浏览器引入,更新较为及时:
+
+```html
+<!-- 引入 -->
+<script src="https://cdn.jsdelivr.net/npm/chinese-days"></script>
+
+<!-- 使用 -->
+<script>
+  chineseDays.isHoliday('2024-01-01');
+  // 或者解构使用
+  const { isHoliday } = chineseDays;
+</script>
+```
+
+或者指定 `type="module"`,使用 ESM:
+
+```html
+<script type="module">
+  import chineseDays from 'https://esm.run/chinese-days'
+  // 导入后使用
+  chineseDays.isHoliday('2024-01-01')
+</script>
+```
+
+## 安装方式
+
+```sh
+npm i chinese-days
+```
+
+使用 ESM 导入
+
+```ts
+import chineseDays from 'chinese-days';
+console.log(chineseDays);
+```
+
+在 Node 中使用
+
+```js
+const { isWorkday, isHoliday } = require('chinese-days');
+console.log(isWorkday('2020-01-01'));
+console.log(isHoliday('2020-01-01'));
+```
+
+## 指定版本
+
+一般不建议指定版本使用,因为节假日会随国务院发布进行更新;如一定要指定版本,具体使用方式可以参考 [jsdelivr](https://www.jsdelivr.com/),比如:
+
+```
+https://cdn.jsdelivr.net/npm/chinese-days@1.4.0
+https://esm.run/chinese-days@1.4.0
+```

+ 27 - 0
docs/zh/guide/holidays.md

@@ -0,0 +1,27 @@
+# 节假日
+
+## `isHoliday` 检查某个日期是否为节假日
+
+```js
+console.log(isHoliday('2023-01-01')); // true
+```
+
+## `getHolidaysInRange` 获取指定日期范围内的所有节假日
+
+接收起始日期和结束日期,并可选地决定是否包括周末。如果包括周末,则函数会返回包括周末在内的所有节假日;否则,只返回工作日的节假日。
+
+> tip: 即使不包括周末,周末的节假日仍然会被返回
+
+```js
+// 示例用法
+const start = '2024-04-26';
+const end = '2024-05-06';
+
+// 获取从 2024-05-01 到 2024-05-10 的所有节假日,包括周末
+const holidaysIncludingWeekends = getHolidaysInRange(start, end, true);
+console.log('Holidays including weekends:', holidaysIncludingWeekends.map(d => getDayDetail(d)));
+
+// 获取从 2024-05-01 到 2024-05-10 的节假日,不包括周末
+const holidaysExcludingWeekends = getHolidaysInRange(start, end, false);
+console.log('Holidays excluding weekends:', holidaysExcludingWeekends.map(d => getDayDetail(d)));
+```

+ 13 - 0
docs/zh/guide/lieu-days.md

@@ -0,0 +1,13 @@
+# 调休日
+
+## `isInLieu` 检查某个日期是否为调休日(in lieu day)
+
+在中国的节假日安排中,调休日是为了连休假期或补班而调整的工作日或休息日。例如,当某个法定假日与周末相连时,可能会将某个周末调整为工作日,或者将某个工作日调整为休息日,以便连休更多天。
+
+```js
+// 检查 2024-05-02 返回 `true` 则表示是一个调休日。
+console.log(isInLieu('2024-05-02')); // true
+
+// 检查 2024-05-01 返回 `false` 则表示不是一个调休日。
+console.log(isInLieu('2024-05-01')); // false
+```

+ 4 - 0
docs/zh/guide/thank.md

@@ -0,0 +1,4 @@
+# 致谢
+
+1. 农历数据来自于 [Bigkoo/Android-PickerView](https://github.com/Bigkoo/Android-PickerView) 项目。
+2. 中国节假日数据生成参考了 `Python` 版本的 [LKI/chinese-calendar](https://github.com/LKI/chinese-calendar) 项目。

+ 39 - 0
docs/zh/guide/to-lunar.md

@@ -0,0 +1,39 @@
+# 阳历农历互转
+
+特别说明,此库中:
+1. `2057-09-28` 为:农历丁丑(牛)年八月三十;
+2. `2097-08-07` 为:农历丁巳(蛇)年七月初一。
+
+## 阳历转换农历
+
+```js
+// 2097-8-7
+console.log(getLunarDate('2097-08-07'));
+
+// 2057-9-28
+console.log(getLunarDate('2057-09-28'));
+// {
+//   date: "2057-09-28",
+//   lunarYear: 2057,
+//   lunarMon: 8,
+//   lunarDay: 30,
+//   isLeap: false,
+//   lunarDayCN: "三十",
+//   lunarMonCN: "八月",
+//   lunarYearCN: "二零五七",
+//   yearCyl: "丁丑",
+//   monCyl: "己酉",
+//   dayCyl: "戊子",
+//   zodiac: "牛"
+// }
+
+// 非闰月 和 闰月例子
+console.log(getLunarDate('2001-04-27'));
+console.log(getLunarDate('2001-05-27'));
+```
+
+## 根据阳历日期区间,批量获取农历日期
+
+```js
+console.log(getLunarDatesInRange('2001-05-21', '2001-05-26'));
+```

+ 31 - 0
docs/zh/guide/what-is-chinese-days.md

@@ -0,0 +1,31 @@
+# 中国节假日
+
+## 介绍
+
+本项目提供了一系列用于查询中国节假日、调休日、工作日、24节气、以及农历阳历互转的函数,此外还支持 `iCal` 文件订阅节假日,可供 Google Calendar、Apple Calendar、Microsoft Outlook 等客户端订阅。
+
+每日会定时执行 `Github Action` 自动抓取数据,节假日变化时发送邮件提醒,信息会跟随国务院发布进行更新。
+
++ **节假日**:支持 2004年 至 2025年,包括 2020年 的春节延长
++ **24节气**:支持 1900年 至 2100年。
++ **农历日**:支持 1900年 至 2100年。
+
+项目主要针对 `JS` 或 `TS` 用户,使用方法可以看后续的文档。
+
+## 非 `JS` 语言
+
+如果你不使用 `JS` 或 `TS` 开发项目,本项目提供了中国节假日的 `JSON` 文件,通过链接 [chinese-days.json](https://cdn.jsdelivr.net/npm/chinese-days/dist/chinese-days.json) 可以直接引用。
+
+比如在 `Java` 中使用,可以参考 [Warnier-zhang/java-chinese-days](https://github.com/Warnier-zhang/java-chinese-days),仅用于查询中国节假日、调休日、工作日;
+
+## 日历订阅
+
+在 Google Calendar、Apple Calendar、Microsoft Outlook 等客户端中,可以设置订阅地址:[https://cdn.jsdelivr.net/npm/chinese-days/dist/holidays.ics](https://cdn.jsdelivr.net/npm/chinese-days/dist/holidays.ics) 来获取日历订阅。
+
+For English: [https://cdn.jsdelivr.net/npm/chinese-days/dist/holidays.en.ics](https://cdn.jsdelivr.net/npm/chinese-days/dist/holidays.en.ics)
+
+订阅的日历包含近三年(2023-2025年)的节假日和调休日。
+
+## 许可信息
+
+项目基于 MIT 许可发布。

+ 70 - 0
docs/zh/guide/working-days.md

@@ -0,0 +1,70 @@
+# 工作日
+
+## `isWorkday` 检查某个日期是否为工作日
+
+```js
+console.log(isWorkday('2023-01-01')); // false
+```
+
+## `getWorkdaysInRange` 取指定日期范围内的工作日列表
+
+接收起始日期和结束日期,并可选地决定是否包括周末。如果包括周末,则函数会返回包括周末在内的所有工作日;否则,只返回周一到周五的工作日。
+
+```js
+// 示例用法
+const start = '2024-04-26';
+const end = '2024-05-06';
+
+// 获取从 2024-05-01 到 2024-05-10 的所有工作日,包括周末
+const workdaysIncludingWeekends = getWorkdaysInRange(start, end, true);
+console.log('Workdays including weekends:', workdaysIncludingWeekends);
+
+// 获取从 2024-05-01 到 2024-05-10 的工作日,不包括周末
+const workdaysExcludingWeekends = getWorkdaysInRange(start, end, false);
+console.log('Workdays excluding weekends:', workdaysExcludingWeekends);
+```
+
+## `findWorkday` 查找工作日
+
+查找从今天开始 未来的第 {deltaDays} 个工作日。
+
+```js
+// 查找从今天开始 未来的第 {deltaDays} 个工作日
+// 如果 deltaDays 为 0,首先检查当前日期是否为工作日。如果是,则直接返回当前日期。
+// 如果当前日期不是工作日,会查找下一个工作日。
+const currentWorkday = findWorkday(0);
+console.log(currentWorkday);
+
+// 查找从今天开始未来的第一个工作日
+const nextWorkday = findWorkday(1);
+console.log(nextWorkday);
+
+// 查找从今天开始之前的前一个工作日
+const previousWorkday = findWorkday(-1);
+console.log(previousWorkday);
+
+// 可以传第二个参数 查找具体日期的上下工作日
+// 查找从 2024-05-18 开始,未来的第二个工作日
+const secondNextWorkday = findWorkday(2, '2024-05-18');
+console.log(secondNextWorkday);
+```
+
+## `getDayDetail` 获取日期信息
+
+函数用于检查指定日期是否是工作日,并返回一个是否工作日的布尔值和日期的详情。
+
+1. 如果指定日期是工作日,则返回 true 和工作日名称,如果是被调休的工作日,返回 true 和节假日详情。
+2. 如果是节假日,则返回 false 和节假日详情。
+
+```js
+// 示例用法
+
+// 正常工作日 周五
+console.log(getDayDetail('2024-02-02')); // { "date": "2024-02-02", "work":true,"name":"Friday"}
+// 节假日 周末
+console.log(getDayDetail('2024-02-03')); // { "date": "2024-02-03", "work":false,"name":"Saturday"}
+// 调休需要上班
+console.log(getDayDetail('2024-02-04')); // { "date": "2024-02-04", "work":true,"name":"Spring Festival,春节,3"}
+// 节假日 春节
+console.log(getDayDetail('2024-02-17')); // { "date": "2024-02-17", "work":false,"name":"Spring Festival,春节,3"}
+```

File diff suppressed because it is too large
+ 0 - 0
docs/zh/index.md


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