chinese-lunar-date

高精度農曆曆法庫 — 干支 · 生肖 · 節氣 · 節日 · 格式化 · 多語言

基於天文算法的農曆計算,支援中國、日本、韓國、越南四種農曆變體,以及簡體中文、繁體中文(臺灣/香港)、日本語、한국어、Tiếng Việt 六種語言。

Copyright (c) 2025 北京鋒通科技有限公司 (郭玉峰, 吳瓊). MIT License.

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

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

date.yearGanZhi    // "甲辰"
date.zodiac        // "龍"
date.zodiacEmoji   // "🐉"
date.formatFull()  // "甲辰龍年 五月初六"

本專案獨創

為什麼選擇 chinese-lunar-date?

chinese-lunar-date date-chinese lunar-javascript
精度 天文算法(VSOP87) 天文算法 查表法
TypeScript 原生 TS,完整型別 JSDoc 標註 社群 @types
API 風格 不可變值物件 函式式 + 內部類別 可變物件
干支 年月日三柱 僅年柱 年月日三柱
生肖 6 種語言 + Emoji 僅中文
節氣 24 節氣,6 種語言 僅中文
節日 13 個,按地區篩選 僅中文
多曆法 中 / 日 / 韓 / 越 僅中國 僅中國
繁體中文 zh-TW / zh-HK 分別適配
格式化 5 種內建 + 自訂模式 有限
體積 (gzip) ~16 KB ~15 KB ~20 KB

特性

安裝

npm install chinese-lunar-date

快速開始

建立日期

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

// 從公曆建立
const date = ChineseDate.fromGregorian(2024, 6, 21)

// 從 JavaScript Date 建立
const date2 = ChineseDate.fromDate(new Date(2024, 5, 21))

// 今天的農曆
const today = ChineseDate.today()

// 從 LunarDateValue 建立
const date3 = ChineseDate.fromValue({ cycle: 78, year: 34, month: 5, leap: false, day: 6 })

讀取屬性

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

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

// 天干地支
date.yearGanZhi      // "甲辰"
date.monthGanZhi     // "庚午"
date.dayGanZhi       // "甲寅"
date.ganZhiInfo      // { year: {gan:0,zhi:4}, month: {gan:6,zhi:6}, day: {gan:0,zhi:2} }

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

// 節日 & 節氣
date.festivals       // []  — 這天沒有節日
date.getSolarTermName('zh-TW')  // null  — 這天不是節氣

格式化

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

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

// 自訂模式
date.format('{Ygz}{Z}年 {Mname}{Dname}', 'zh-TW')   // "甲辰龍年 五月初六"
date.format('{GY}年{GM}月{GD}日', 'zh-TW')           // "2024年6月21日"

日期運算

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)

// 修改部分欄位
const firstDay = date.with({ day: 1 })  // 五月初一

// 比較
tomorrow.isAfter(date)     // true
yesterday.isBefore(date)   // true
date.equals(tomorrow)      // false

轉換

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

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

// 轉為 JavaScript Date
date.toDate()       // Date object

// 序列化
date.toJSON()       // { cycle: 78, year: 34, month: 5, leap: false, day: 6 }
JSON.stringify(date)  // '{"cycle":78,"year":34,"month":5,"leap":false,"day":6}'

多曆法

四種農曆變體,各有不同的紀元和時區歷史:

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

// 中國農曆 (UTC+8)
const cn = ChineseDate.fromGregorian(2024, 6, 21)
cn.yearGanZhi  // "甲辰"

// 日本舊曆 (UTC+9)
const jp = JapaneseDate.fromGregorian(2024, 6, 21)
jp.yearGanZhi  // "甲辰"  — 同一天可能因時區差異而不同

// 韓國農曆 (UTC+8:30/9,檀君紀元)
const kr = KoreanDate.fromGregorian(2024, 6, 21)

// 越南農曆 (UTC+7/8)
const vn = VietnameseDate.fromGregorian(2024, 6, 21)

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

24 節氣

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

// 取得指定節氣的公曆日期
ChineseDate.solarTerm(5, 2024)   // { year: 2024, month: 4, day: 4 } — 清明
ChineseDate.qingming(2024)        // 同上

// 全年 24 節氣
ChineseDate.solarTermsInYear(2024, 'zh-TW')
// [
//   { index: 1, name: "立春", date: { year: 2024, month: 2, day: 4 }, jde: ... },
//   ...
// ]

// 節氣名稱 — 6 種語言
solarTermName(3, 'zh-CN')  // "惊蛰"
solarTermName(3, 'zh-TW')  // "驚蟄"
solarTermName(3, 'ja-JP')  // "啓蟄"
solarTermName(3, 'ko-KR')  // "경칩"
solarTermName(3, 'vi-VN')  // "Kinh trập"

// 查詢某日是否為節氣
const date = ChineseDate.fromGregorian(2024, 4, 4)
date.getSolarTermName('zh-TW')  // "清明"

傳統節日

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

// 取得指定節日的公曆日期
ChineseDate.festivalDate('spring', 2024)      // { year: 2024, month: 2, day: 10 }
ChineseDate.festivalDate('mid-autumn', 2024)  // { year: 2024, month: 9, day: 17 }

// 全年節日 — 按地區自動篩選
ChineseDate.festivalsInYear(2024, 'zh-TW')
// [{ name: "春節", key: "spring", date: {...} }, ...]

ChineseDate.festivalsInYear(2024, 'zh-HK')
// [{ name: "農曆新年", key: "spring", date: {...} }, ...]

// 檢視某日是否為節日
const date = ChineseDate.fromGregorian(2024, 2, 10)
date.getFestivals('zh-TW')  // [{ name: "春節", key: "spring", ... }]
date.getFestivals('zh-HK')  // [{ name: "農曆新年", key: "spring", ... }]

內建節日列表

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 臘月三十 除夕 除夕

多語言 / 多地區

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

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

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

天干地支

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

const pair = yearGanZhi({ cycle: 78, year: 34, month: 7, leap: false, day: 28 })
formatGanZhi(pair)  // "丁酉"
parseGanZhi('甲子')  // { gan: 0, zhi: 0 }
allGanZhi()  // ["甲子", "乙丑", ..., "癸亥"]

生肖

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

zodiac({ cycle: 78, year: 34, month: 7, leap: false, day: 28 }, 'zh-TW')  // "雞"
zodiacEmoji({ cycle: 78, year: 34, month: 7, leap: false, day: 28 })  // "🐔"
zodiacFromGregorianYear(2024, 'zh-TW')  // "龍"
zodiacList('zh-TW')  // ["鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬"]

格式化

const date = ChineseDate.fromGregorian(2024, 7, 3)

date.format('{Ygz}{Z}年 {Mname}{Dname}', 'zh-TW')
// "甲辰龍年 五月廿八"
Token 輸出 範例
{CY} 週期序號 78
{Y} 週期內年序 34
{Ygz} 年干支 甲辰
{Z} 生肖
{M} 月份數字 5
{Mname} 月份名稱 五月
{L} 閏月標記 (非閏月時為空)
{D} 日期數字 28
{Dname} 日期名稱 廿八
{GY} 公曆年 2024
{GM} 公曆月 7
{GD} 公曆日 3
{W} 星期幾 (0-6) 3
{Wname} 星期幾全稱 星期三
{Wshort} 星期幾簡稱

解析

import { parseCompact, parseISO } 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 }

低階 API

如需更細緻的控制,可直接使用核心演算法函式:

import {
  gregorianToLunar, lunarToGregorian, lunarToJDE, fromJDE,
  newYear, yearFromEpochCycle, solarTermJDE,
  nextNewMoon, previousNewMoon, midnight,
  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)

瀏覽器使用(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'))  // "甲辰龍年 五月初六"
  console.log(date.zodiac)               // "龍"
</script>

安裝與建置

npm install chinese-lunar-date
npm run build        # 編譯 ESM + CJS + IIFE
npm run build:types  # 產生 .d.ts 型別宣告
npm run test         # 執行測試
npm run clean        # 清除 dist

意見回饋與合作

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

📧 gyfinjava@163.com

License

MIT License

Copyright (c) 2025 北京鋒通科技有限公司 (郭玉峰, 吳瓊)