chinese-lunar-date 使用手冊

版本:1.0.0 | 最後更新:2025-06 Copyright (c) 2025 北京鋒通科技有限公司 (郭玉峰, 吳瓊). MIT License.


目錄


1. 概述

chinese-lunar-date 是一個基於天文算法的高精度農曆曆法庫,提供以下核心能力:

能力 說明
公曆 ↔ 農曆轉換 基於 VSOP87 行星理論的天文級精度
天干地支 年柱、月柱、日柱,六十甲子序號與字串互轉
生肖 12 生肖多語言名稱 + Emoji
24 節氣 精確到天的節氣計算,6 種語言
傳統節日 13 個內建節日,按地區自動篩選
格式化 5 種內建格式 + 自訂模式字串(17 種 Token)
多曆法 中國 / 日本 / 韓國 / 越南四種農曆變體
多語言 簡體中文 / 繁體中文(臺灣/香港)/ 日本語 / 한국어 / Tiếng Việt

輸出格式: ESM / CJS / IIFE,IIFE 壓縮後僅 ~47 KB(gzip ~16 KB)。


2. 安裝與引入

2.1 安裝

npm install chinese-lunar-date

2.2 ESM 引入

import { ChineseDate, formatGanZhi, PATTERNS } from 'chinese-lunar-date'

2.3 CJS 引入

const { ChineseDate, formatGanZhi, PATTERNS } = require('chinese-lunar-date')

2.4 瀏覽器 IIFE 引入

<script src="dist/chinese-lunar-date.iife.js"></script>
<script>
  const date = ChineseDate.ChineseDate.fromGregorian(2024, 6, 21)
  console.log(date.formatFull('zh-TW'))  // "甲辰龍年 五月初六"

  const lunar = ChineseDate.gregorianToLunar(ChineseDate.CHINESE_CONFIG, 2024, 6, 21)
  console.log(lunar)  // { cycle: 78, year: 34, month: 5, leap: false, day: 6 }
</script>

2.5 TypeScript 支援

本函式庫使用原生 TypeScript 編寫,自帶完整型別定義,無需額外安裝 @types 套件。

import type { LunarDateValue, GanZhiPair, LocaleCode } from 'chinese-lunar-date'

3. 核心概念

3.1 六十甲子週期(cycle / year)

中國農曆使用連續的六十甲子週期(六十甲子)來標記年份:

公曆年份換算公式:

gregorianYear = epochYear + (cycle - 1) * 60 + (year - 1)
// 例:中國曆法 epoch = -2636,cycle=78, year=34 → 2024

提示:大多數場景下,直接使用 date.gregorianYear 屬性即可取得公曆年份,無需手動計算。

3.2 不可變值物件

所有日期實例(ChineseDateJapaneseDate 等)都是不可變的。任何修改操作都會回傳新實例,原實例保持不變:

const date = ChineseDate.fromGregorian(2024, 6, 21)
const tomorrow = date.addDays(1)  // 回傳新實例

date === tomorrow       // false
date.day                // 6(原實例未變)
tomorrow.day            // 7

3.3 曆法配置與地區差異

四種曆法變體使用不同的時區歷史和紀元:

曆法 時區 紀元 配置常量
中國 UTC+8 公元前 2636 年 CHINESE_CONFIG
日本 UTC+9 公元前 2636 年 JAPANESE_CONFIG
韓國 UTC+8:30 / UTC+9 公元前 2333 年(檀君) KOREAN_CONFIG
越南 UTC+7 / UTC+8 公元前 2636 年 VIETNAMESE_CONFIG

3.4 語言與地區代碼

代碼 語言 說明
zh-CN 簡體中文 中國大陸
zh-TW 繁體中文 臺灣
zh-HK 繁體中文 香港
ja-JP 日本語 日本
ko-KR 한국어 韓國
vi-VN Tiếng Việt 越南

4. 建立日期

4.1 從公曆建立

const date = ChineseDate.fromGregorian(2024, 6, 21)
// { cycle: 78, year: 34, month: 5, leap: false, day: 6 }
// 即:甲辰年 五月初六

4.2 從 JavaScript Date 建立

const jsDate = new Date(2024, 5, 21)  // 注意:JS Date 月份從 0 開始
const date = ChineseDate.fromDate(jsDate)

注意fromDate 使用本地時區提取日期分量。

4.3 從 LunarDateValue 建立

const date = ChineseDate.fromValue({ cycle: 78, year: 34, month: 5, leap: false, day: 6 })

4.4 從字串解析

const d1 = ChineseDate.fromISO('2024-06-21')
const d2 = ChineseDate.fromISO('2024/06/21')
const d3 = ChineseDate.fromISO('2024年6月21日')
const d4 = ChineseDate.fromISO('invalid')  // null
const d5 = ChineseDate.parse('2024-06-21')

4.5 從時間戳建立

const date = ChineseDate.fromTimestamp(Date.now())

4.6 從儒略日建立

const date = ChineseDate.fromJDE(2460482.5)

4.7 取得今天

const today = ChineseDate.today()

5. 讀取屬性

5.1 農曆日期屬性

const date = ChineseDate.fromGregorian(2024, 6, 21)

date.cycle           // 78      — 六十甲子週期序號
date.year            // 34      — 週期內年序(34 → 甲辰)
date.month           // 5       — 五月
date.leap            // false   — 非閏月
date.day             // 6       — 初六
date.calendarType    // 'chinese'
date.gregorianYear   // 2024

5.2 天干地支屬性

date.yearGanZhi        // "甲辰"
date.monthGanZhi       // "庚午"
date.dayGanZhi         // "甲寅"

date.yearGanZhiPair    // { gan: 0, zhi: 4 }
date.monthGanZhiPair   // { gan: 6, zhi: 6 }
date.dayGanZhiPair     // { gan: 0, zhi: 2 }

date.ganZhiInfo        // { year: {gan:0,zhi:4}, month: {gan:6,zhi:6}, day: {gan:0,zhi:2} }

干支索引說明:

5.3 生肖屬性

date.zodiac        // "龍"
date.zodiacEmoji   // "🐉"
date.zodiacIndex   // 4

date.getZodiac('zh-TW')  // "龍"
date.getZodiac('ja-JP')  // "辰"
date.getZodiac('ko-KR')  // "용"
date.getZodiac('vi-VN')  // "Thìn"

5.4 公曆與星期屬性

date.weekday           // 5
date.weekdayName       // "星期五"
date.weekdayShort      // "五"

date.getWeekdayName('ja-JP')   // "金曜日"
date.getWeekdayShort('ja-JP')  // "金"
date.getWeekdayName('ko-KR')   // "금요일"

date.gregorianYearCn      // "二〇二四"
date.gregorianYearCnLower // "二零二四"

6. 日期轉換

6.1 轉為公曆

date.toGregorian()  // { year: 2024, month: 6, day: 21 }

6.2 轉為 JavaScript Date

date.toDate()  // Date object(使用本地時區)

6.3 序列化與反序列化

const json = date.toJSON()
// { cycle: 78, year: 34, month: 5, leap: false, day: 6 }

const str = JSON.stringify(date)
// '{"cycle":78,"year":34,"month":5,"leap":false,"day":6}'

const restored = ChineseDate.fromValue(JSON.parse(str))

7. 日期運算

7.1 日期加減

所有日期運算方法都回傳新實例,原實例不變:

const date = ChineseDate.fromGregorian(2024, 6, 21)

const tomorrow = date.addDays(1)
const yesterday = date.addDays(-1)
const nextMonth = date.addMonths(1)
const lastYear = date.addYears(-1)

注意addMonthsaddYears 在公曆上運算。如果結果日期無效,會自動 clamp 到該月最後一天。

7.2 修改欄位

const date = ChineseDate.fromGregorian(2024, 6, 21)

const firstDay = date.with({ day: 1 })     // 五月初一
const prevMonth = date.with({ month: 4 })   // 四月初六
const leapMonth = date.with({ month: 4, leap: true })  // 閏四月初六

7.3 日期比較

const a = ChineseDate.fromGregorian(2024, 6, 21)
const b = ChineseDate.fromGregorian(2024, 6, 20)

a.equals(b)      // false
a.isAfter(b)     // true
a.isBefore(b)    // false

注意equals 同時比較 calendarType,不同曆法的實例即使日期相同也不相等。

7.4 日期差值

const a = ChineseDate.fromGregorian(2024, 6, 21)
const b = ChineseDate.fromGregorian(2024, 6, 18)

a.diffDays(b)  // 3
b.diffDays(a)  // -3

7.5 月天數查詢

const date = ChineseDate.fromGregorian(2024, 6, 21)
date.daysInMonth()  // 29 或 30

8. 格式化

8.1 內建格式方法

const date = ChineseDate.fromGregorian(2024, 6, 21)

date.formatFull('zh-TW')   // "甲辰龍年 五月初六"
date.formatGanZhi()        // "甲辰年 庚午月 甲寅日"
date.formatCompact()       // "78/34/5/0/6"
date.formatISO()           // "78-34-5-0-6"
date.toString()            // "甲辰龍年 五月初六"

緊湊格式說明cycle/year/month/leap/day,其中 leap 編碼為 0(非閏月)或 1(閏月)。

8.2 自訂模式

const date = ChineseDate.fromGregorian(2024, 6, 21)

date.format('{Ygz}{Z}年 {Mname}{Dname}', 'zh-TW')   // "甲辰龍年 五月初六"
date.format('{GY}年{GM}月{GD}日', 'zh-TW')           // "2024年6月21日"
date.format('{GYcn}年{GMcn}月{GDcn}日', 'zh-TW')     // "二〇二四年六月二十一日"
date.format('{Ygz}年 {Mname}{Dname} {GY}年{GM}月{GD}日', 'zh-TW')
// "甲辰年 五月初六 2024年6月21日"

8.3 預設格式常量 PATTERNS

import { PATTERNS } from 'chinese-lunar-date'

const date = ChineseDate.fromGregorian(2025, 10, 11)

date.format(PATTERNS.LUNAR_FULL)               // "甲辰龍年 九月初九"
date.format(PATTERNS.GREGORIAN_CN_FULL)        // "二〇二五年十月十一日"
date.format(PATTERNS.FULL_WITH_WEEKDAY)        // "二〇二五年十月十一日 星期六"
常量 格式模式 輸出範例
GREGORIAN_CN_FULL {GYcn}年{GMcn}月{GDcn}日 二〇二五年十月十一日
GREGORIAN_CN_FULL_LOWER {GYcn2}年{GMcn}月{GDcn}日 二零二五年十月十一日
GREGORIAN_CN_NUMERIC {GY}年{GM}月{GD}日 2025年10月11日
GREGORIAN_ISO {GY}-{GM0}-{GD0} 2025-10-11
GREGORIAN_SLASH {GY}/{GM}/{GD} 2025/10/11
LUNAR_FULL {Ygz}{Z}年 {Mname}{Dname} 甲辰龍年 九月初九
LUNAR_GANZHI {Ygz}年 {Mname}{Dname} 甲辰年 九月初九
FULL_WITH_WEEKDAY {GYcn}年{GMcn}月{GDcn}日 {Wname} 二〇二五年十月十一日 星期六
NUMERIC_WITH_WEEKDAY {GY}年{GM}月{GD}日 {Wname} 2025年10月11日 星期六
LUNAR_WITH_WEEKDAY {Ygz}{Z}年 {Mname}{Dname} {Wname} 甲辰龍年 九月初九 星期六

8.4 格式化 Token 完整參考

農曆相關

Token 輸出 範例
{CY} 週期序號 78
{Y} 週期內年序 34
{Ygz} 年干支 甲辰
{Z} 生肖
{M} 月份數字 5
{Mname} 月份名稱 五月 / 閏四月
{L} 閏月標記 (非閏月時為空)
{D} 日期數字 6
{Dname} 日期名稱 初六 / 廿一 / 三十

公曆相關

Token 輸出 範例
{GY} 公曆年 2024
{GYcn} 公曆年中文(〇版) 二〇二四
{GYcn2} 公曆年中文(零版) 二零二四
{GM} 公曆月 6
{GM0} 公曆月補零 06
{GMcn} 公曆月中文
{GD} 公曆日 21
{GD0} 公曆日補零 21
{GDcn} 公曆日中文 二十一

星期相關

Token 輸出 範例
{W} 星期幾數字 (0-6) 5
{Wname} 星期全稱 星期五 / 金曜日
{Wshort} 星期簡稱 /

8.5 解析

import { parseCompact, parseISO, parseGregorian } from 'chinese-lunar-date'

parseCompact('78/34/5/0/6')    // { cycle: 78, year: 34, month: 5, leap: false, day: 6 }
parseISO('78-34-5-0-6')        // { cycle: 78, year: 34, month: 5, leap: false, day: 6 }
parseGregorian('2025-10-11')   // { year: 2025, month: 10, day: 11 }

9. 天干地支

9.1 值物件上的干支屬性

const date = ChineseDate.fromGregorian(2024, 6, 21)

date.yearGanZhi    // "甲辰"
date.monthGanZhi   // "庚午"
date.dayGanZhi     // "甲寅"

date.ganZhiInfo
// { year: {gan:0,zhi:4}, month: {gan:6,zhi:6}, day: {gan:0,zhi:2} }

9.2 獨立干支函式

import {
  yearGanZhi, monthGanZhi, dayGanZhi,
  formatGanZhi, parseGanZhi, allGanZhi,
  ganZhiToCycleIndex, ganChar, zhiChar, GAN, ZHI
} from 'chinese-lunar-date'

const value = { cycle: 78, year: 34, month: 7, leap: false, day: 28 }

yearGanZhi(value)   // { gan: 3, zhi: 9 }  → 丁酉
formatGanZhi({ gan: 3, zhi: 9 })  // "丁酉"
parseGanZhi('甲子')  // { gan: 0, zhi: 0 }
ganZhiToCycleIndex({ gan: 0, zhi: 0 })   // 1
ganZhiToCycleIndex({ gan: 9, zhi: 11 })  // 60
allGanZhi()  // ["甲子", "乙丑", ..., "癸亥"]

9.3 六十甲子表

allGanZhi()
// ["甲子", "乙丑", "丙寅", ..., "壬戌", "癸亥"] — 共 60 項

10. 生肖

10.1 值物件上的生肖屬性

const date = ChineseDate.fromGregorian(2024, 6, 21)

date.zodiac        // "龍"
date.zodiacEmoji   // "🐉"
date.zodiacIndex   // 4

date.getZodiac('zh-TW')  // "龍"
date.getZodiac('ja-JP')  // "辰"
date.getZodiac('ko-KR')  // "용"
date.getZodiac('vi-VN')  // "Thìn"

10.2 獨立生肖函式

import { zodiac, zodiacEmoji, zodiacFromGregorianYear, zodiacList, zodiacIndex } from 'chinese-lunar-date'

const value = { cycle: 78, year: 34, month: 7, leap: false, day: 28 }

zodiac(value, 'zh-TW')  // "雞"
zodiacEmoji(value)  // "🐔"
zodiacFromGregorianYear(2024, 'zh-TW')  // "龍"
zodiacList('zh-TW')  // ["鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬"]

11. 24 節氣

11.1 取得節氣日期

ChineseDate.solarTerm(1, 2024)   // { year: 2024, month: 2, day: 4 }   — 立春
ChineseDate.solarTerm(5, 2024)   // { year: 2024, month: 4, day: 4 }   — 清明
ChineseDate.qingming(2024)       // { year: 2024, month: 4, day: 4 }

節氣編號對照表:

編號 名稱 編號 名稱 編號 名稱 編號 名稱
1 立春 7 立夏 13 立秋 19 立冬
2 雨水 8 小滿 14 處暑 20 小雪
3 驚蟄 9 芒種 15 白露 21 大雪
4 春分 10 夏至 16 秋分 22 冬至
5 清明 11 小暑 17 寒露 23 小寒
6 穀雨 12 大暑 18 霜降 24 大寒

奇數編號為節氣(節),偶數編號為中氣(氣)。

11.2 節氣名稱

import { solarTermName, solarTermNames } from 'chinese-lunar-date'

solarTermName(3, 'zh-TW')  // "驚蟄"
solarTermName(3, 'ja-JP')  // "啓蟄"
solarTermName(3, 'ko-KR')  // "경칩"
solarTermNames('zh-TW')  // ["立春", "雨水", "驚蟄", ..., "小寒", "大寒"]

11.3 查詢某日是否為節氣

const date = ChineseDate.fromGregorian(2024, 4, 4)
date.getSolarTermName('zh-TW')  // "清明"

11.4 全年節氣

const terms = ChineseDate.solarTermsInYear(2024, 'zh-TW')
// [{ index: 1, name: "立春", date: {...}, jde: ... }, ...]

12. 傳統節日

12.1 取得節日日期

ChineseDate.festivalDate('spring', 2024)       // { year: 2024, month: 2, day: 10 }
ChineseDate.festivalDate('mid-autumn', 2024)   // { year: 2024, month: 9, day: 17 }

12.2 查詢某日的節日

const date = ChineseDate.fromGregorian(2024, 2, 10)

date.getFestivals('zh-TW')  // [{ name: "春節", key: "spring", ... }]
date.getFestivals('zh-HK')  // [{ name: "農曆新年", key: "spring", ... }]

12.3 全年節日

ChineseDate.festivalsInYear(2024, 'zh-TW')
// [{ name: "春節", key: "spring", date: {...} }, ...]

12.4 內建節日一覽

Key 農曆日期 zh-TW zh-HK
spring 正月初一 春節 農曆新年
lantern 正月十五 元宵節 元宵節
dragon-head 二月初二 龍抬頭 龍抬頭
shangsi 三月初三 上巳節 上巳節
dragon-boat 五月初五 端午節 端午節
qixi 七月初七 七夕 七夕
ghost 七月十五 中元節 中元節
mid-autumn 八月十五 中秋節 中秋節
double-ninth 九月初九 重陽節 重陽節
laba 臘月初八 臘八節 臘八節
little-new-year-south 臘月廿四 小年 小年
new-year-eve 臘月三十 除夕 除夕

13. 多曆法

13.1 四種曆法變體

import { ChineseDate, JapaneseDate, KoreanDate, VietnameseDate } from 'chinese-lunar-date'

const cn = ChineseDate.fromGregorian(2024, 6, 21)    // UTC+8
const jp = JapaneseDate.fromGregorian(2024, 6, 21)   // UTC+9
const kr = KoreanDate.fromGregorian(2024, 6, 21)     // UTC+8:30/9
const vn = VietnameseDate.fromGregorian(2024, 6, 21) // UTC+7/8

13.2 時區差異的影響

由於時區不同,同一公曆日期在不同曆法中可能對應不同的農曆日期。

13.3 韓國曆法的特殊紀元

韓國曆法使用檀君紀元(公元前 2333 年),因此 cycleyear 與中國曆法不同,但 gregorianYear 相同。


14. 多語言 / 多地區

14.1 支援的語言

import { availableLocales, isLocaleSupported } from 'chinese-lunar-date'

availableLocales()  // ["zh-CN", "zh-TW", "zh-HK", "ja-JP", "ko-KR", "vi-VN"]

14.2 取得地區資料

import { getLocale } from 'chinese-lunar-date'

const loc = getLocale('zh-TW')
loc.gan           // ["甲", "乙", "丙", ...]
loc.zodiac        // ["鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬"]
loc.monthNames(12, false)  // "十二月"
loc.solarTerms    // ["立春", "雨水", "驚蟄", ...]

14.3 繁體中文地區差異

項目 zh-CN zh-TW zh-HK
生肖 龙 马 鸡 猪 龍 馬 雞 豬 龍 馬 雞 豬
閏月標記
臘月 腊月 臘月 臘月
春節名稱 春节 春節 農曆新年
節氣用字 惊蛰 谷雨 处暑 小满 芒种 驚蟄 穀雨 處暑 小滿 芒種 驚蟄 穀雨 處暑 小滿 芒種
小年 分南北方 統一(廿四) 統一(廿四)

15. 低階 API

15.1 核心轉換函式

import {
  gregorianToLunar, lunarToGregorian, lunarToJDE, fromJDE,
  newYear, yearFromEpochCycle,
  inMajorSolarTerm, isLeapMonth,
  CHINESE_CONFIG, JAPANESE_CONFIG, KOREAN_CONFIG, VIETNAMESE_CONFIG
} from 'chinese-lunar-date'

const lunar = gregorianToLunar(CHINESE_CONFIG, 2024, 6, 21)
const greg = lunarToGregorian(CHINESE_CONFIG, lunar)

15.2 天文計算函式

import {
  solarTermJDE, majorSolarTermJDE, minorSolarTermJDE,
  nextNewMoon, previousNewMoon, midnight
} from 'chinese-lunar-date'

solarTermJDE(CHINESE_CONFIG, 5, 2024)    // 清明的 JDE
nextNewMoon(2460482)      // 下一個新月的 JDE
midnight(2024, 6, 21)     // 午夜的 JDE

15.3 曆法配置物件

import { CHINESE_CONFIG, getConfig } from 'chinese-lunar-date'

CHINESE_CONFIG.type       // 'chinese'
CHINESE_CONFIG.epochYear  // -2636
getConfig('korean')       // KOREAN_CONFIG

16. 中文數字

import { toChineseYear, toChineseNumber, getWeekdayName, getWeekdayShort } from 'chinese-lunar-date'

toChineseYear(2025, 'upper')  // "二〇二五"
toChineseNumber(21, 'upper')  // "二十一"
getWeekdayName(6, 'zh-TW')    // "星期六"
getWeekdayShort(6, 'ja-JP')   // "土"

17. 型別參考

interface LunarDateValue {
  cycle: number
  year: number
  month: number
  leap: boolean
  day: number
}

interface GregorianDate {
  year: number
  month: number
  day: number
}

type CalendarType = 'chinese' | 'korean' | 'japanese' | 'vietnamese'

interface GanZhiPair {
  gan: number
  zhi: number
}

interface GanZhiInfo {
  year: GanZhiPair
  month: GanZhiPair
  day: GanZhiPair
}

interface SolarTermInfo {
  index: number
  name: string
  date: GregorianDate
  jde: number
}

interface FestivalInfo {
  name: string
  key: string
  month: number
  day: number
  leap: boolean
}

type LocaleCode = 'zh-CN' | 'zh-TW' | 'zh-HK' | 'ja-JP' | 'ko-KR' | 'vi-VN'

interface LocaleData {
  code: LocaleCode
  gan: string[]
  zhi: string[]
  zodiac: string[]
  solarTerms: string[]
  monthNames(month: number, leap: boolean): string
  dayNames(day: number): string
  yearFormat(ganzhi: string, zodiac: string): string
}

18. 常見問題(FAQ)

Q: `cycle` 和 `year` 有什麼區別?

中國農曆使用六十甲子週期系統。cycle 標識第幾個 60 年週期,year 標識週期內的第幾年(1-60)。大多數場景下,直接使用 date.gregorianYear 即可。

Q: 為什麼同一公曆日期,`ChineseDate` 和 `JapaneseDate` 的農曆日期不同?

這是因為時區差異。當新月發生在 UTC+8 的午夜附近時,日本(UTC+9)可能已經進入下一天。

Q: 韓國農曆的 `cycle` 為什麼和中國不同?

韓國曆法使用檀君紀元(公元前 2333 年),比中國紀元晚 297 年,因此週期序號不同。但 gregorianYear 相同。

Q: 如何判斷某年是否有閏月?

import { isLeapMonth, CHINESE_CONFIG } from 'chinese-lunar-date'
isLeapMonth(CHINESE_CONFIG, 2023, 8)  // false

Q: 如何取得某月的天數?

const date = ChineseDate.fromGregorian(2024, 6, 21)
date.daysInMonth()  // 29 或 30

Q: IIFE 格式如何使用?

<script src="dist/chinese-lunar-date.iife.js"></script>
<script>
  const date = ChineseDate.ChineseDate.fromGregorian(2024, 6, 21)
  const lunar = ChineseDate.gregorianToLunar(ChineseDate.CHINESE_CONFIG, 2024, 6, 21)
</script>

Q: 精度如何?

本函式庫基於 VSOP87 行星理論的天文算法,與天文臺發布的曆表精度一致(誤差在秒級)。


意見回饋與合作

如果您在使用過程中遇到問題,或有功能建議、商務合作等需求,歡迎透過電子郵件聯繫我們:

📧 gyfinjava@163.com


19. 架構與設計原則

src/
├── types.ts                # 核心型別定義
├── core/
│   ├── astronomy-lite.ts   # 自研輕量天文模組
│   ├── config.ts           # 四種曆法配置
│   └── algorithm.ts        # 核心算法
├── ganzhi.ts               # 天干地支
├── zodiac.ts               # 生肖
├── solar-term.ts           # 24 節氣
├── festival.ts             # 傳統節日
├── locale.ts               # 多語言 / 多地區
├── format.ts               # 格式化 + 解析
├── chinese-numerals.ts     # 中文數字
├── lunar-date.ts           # 不可變值物件 API
└── index.ts                # 主入口

設計原則:


20. 更新日誌

1.0.0