版本:1.0.0 | 最後更新:2025-06 Copyright (c) 2025 北京鋒通科技有限公司 (郭玉峰, 吳瓊). MIT License.
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)。
npm install chinese-lunar-date
import { ChineseDate, formatGanZhi, PATTERNS } from 'chinese-lunar-date'
const { ChineseDate, formatGanZhi, PATTERNS } = require('chinese-lunar-date')
<script src="dist/chinese-lunar-date.iife.js"></script>
<script>
const date = ChineseDate.ChineseDate.fromGregorian(2024, 6, 21)
console.log(date.formatFull('zh-HK')) // "甲辰龍年 五月初六"
</script>
本函式庫使用原生 TypeScript 編寫,自帶完整型別定義。
import type { LunarDateValue, GanZhiPair, LocaleCode } from 'chinese-lunar-date'
cycle — 週期序號(1 起始),表示當前是第幾個 60 年週期year — 週期內年序(1-60),直接對應干支gregorianYear = epochYear + (cycle - 1) * 60 + (year - 1)
所有日期實例都是不可變的。任何修改操作都會回傳新實例。
| 曆法 | 時區 | 紀元 | 配置常量 |
|---|---|---|---|
| 中國 | 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 |
| 代碼 | 語言 | 說明 |
|---|---|---|
zh-CN |
簡體中文 | 中國大陸 |
zh-TW |
繁體中文 | 臺灣 |
zh-HK |
繁體中文 | 香港 |
ja-JP |
日本語 | 日本 |
ko-KR |
한국어 | 韓國 |
vi-VN |
Tiếng Việt | 越南 |
const date = ChineseDate.fromGregorian(2024, 6, 21)
const date2 = ChineseDate.fromDate(new Date(2024, 5, 21))
const today = ChineseDate.today()
const date3 = ChineseDate.fromValue({ cycle: 78, year: 34, month: 5, leap: false, day: 6 })
const d1 = ChineseDate.fromISO('2024-06-21')
const date4 = ChineseDate.fromTimestamp(Date.now())
const date5 = ChineseDate.fromJDE(2460482.5)
date.cycle // 78
date.year // 34
date.month // 5
date.leap // false
date.day // 6
date.calendarType // 'chinese'
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.getZodiac('zh-HK') // "龍"
date.weekday // 5
date.weekdayName // "星期五"
date.gregorianYearCn // "二〇二四"
date.toGregorian() // { year: 2024, month: 6, day: 21 }
date.toDate() // Date object
date.toJSON() // { cycle: 78, year: 34, month: 5, leap: false, day: 6 }
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 })
a.equals(b) // false
a.isAfter(b) // true
a.diffDays(b) // 3
date.daysInMonth() // 29 或 30
date.formatFull('zh-HK') // "甲辰龍年 五月初六"
date.formatGanZhi() // "甲辰年 庚午月 甲寅日"
date.formatCompact() // "78/34/5/0/6"
date.formatISO() // "78-34-5-0-6"
date.format('{Ygz}{Z}年 {Mname}{Dname}', 'zh-HK') // "甲辰龍年 五月初六"
date.format('{GY}年{GM}月{GD}日', 'zh-HK') // "2024年6月21日"
import { PATTERNS } from 'chinese-lunar-date'
date.format(PATTERNS.LUNAR_FULL) // "甲辰龍年 九月初九"
date.format(PATTERNS.GREGORIAN_CN_FULL) // "二〇二五年十月十一日"
| Token | 輸出 | 範例 |
|---|---|---|
{CY} |
週期序號 | 78 |
{Y} |
週期內年序 | 34 |
{Ygz} |
年干支 | 甲辰 |
{Z} |
生肖 | 龍 |
{M} |
月份數字 | 5 |
{Mname} |
月份名稱 | 五月 |
{L} |
閏月標記 | 閏 |
{D} |
日期數字 | 6 |
{Dname} |
日期名稱 | 初六 |
| Token | 輸出 | 範例 |
|---|---|---|
{GY} |
公曆年 | 2024 |
{GYcn} |
公曆年中文(〇版) | 二〇二四 |
{GM} |
公曆月 | 6 |
{GD} |
公曆日 | 21 |
| Token | 輸出 | 範例 |
|---|---|---|
{W} |
星期幾數字 (0-6) | 5 |
{Wname} |
星期全稱 | 星期五 |
{Wshort} |
星期簡稱 | 五 |
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 }
import { yearGanZhi, formatGanZhi, parseGanZhi, allGanZhi, ganZhiToCycleIndex } from 'chinese-lunar-date'
yearGanZhi(value) // { gan: 3, zhi: 9 } → 丁酉
formatGanZhi({ gan: 3, zhi: 9 }) // "丁酉"
parseGanZhi('甲子') // { gan: 0, zhi: 0 }
allGanZhi() // ["甲子", "乙丑", ..., "癸亥"]
import { zodiac, zodiacEmoji, zodiacFromGregorianYear, zodiacList } from 'chinese-lunar-date'
zodiac(value, 'zh-HK') // "雞"
zodiacEmoji(value) // "🐔"
zodiacFromGregorianYear(2024, 'zh-HK') // "龍"
zodiacList('zh-HK') // ["鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬"]
ChineseDate.solarTerm(5, 2024) // 清明
ChineseDate.qingming(2024) // 同上
solarTermName(3, 'zh-HK') // "驚蟄"
solarTermNames('zh-HK') // ["立春", "雨水", "驚蟄", ...]
date.getSolarTermName('zh-HK') // "清明" 或 null
ChineseDate.solarTermsInYear(2024, 'zh-HK')
ChineseDate.festivalDate('spring', 2024) // 農曆新年
ChineseDate.festivalDate('mid-autumn', 2024) // 中秋節
date.getFestivals('zh-HK') // [{ name: "農曆新年", key: "spring", ... }]
ChineseDate.festivalsInYear(2024, 'zh-HK')
// [{ name: "農曆新年", key: "spring", date: {...} }, ...]
| Key | 農曆日期 | zh-HK |
|---|---|---|
spring |
正月初一 | 農曆新年 |
lantern |
正月十五 | 元宵節 |
dragon-head |
二月初二 | 龍抬頭 |
shangsi |
三月初三 | 上巳節 |
dragon-boat |
五月初五 | 端午節 |
qixi |
七月初七 | 七夕 |
ghost |
七月十五 | 中元節 |
mid-autumn |
八月十五 | 中秋節 |
double-ninth |
九月初九 | 重陽節 |
laba |
臘月初八 | 臘八節 |
little-new-year-south |
臘月廿四 | 小年 |
new-year-eve |
臘月三十 | 除夕 |
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
注意:由於時區差異,同一公曆日期在不同曆法中可能對應不同的農曆日期。
import { availableLocales, getLocale } from 'chinese-lunar-date'
availableLocales() // ["zh-CN", "zh-TW", "zh-HK", "ja-JP", "ko-KR", "vi-VN"]
const loc = getLocale('zh-HK')
loc.zodiac // ["鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬"]
loc.solarTerms // ["立春", "雨水", "驚蟄", ...]
| 項目 | zh-TW | zh-HK |
|---|---|---|
| 春節名稱 | 春節 | 農曆新年 |
| 小年 | 統一(廿四) | 統一(廿四) |
import {
gregorianToLunar, lunarToGregorian,
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)
import { toChineseYear, toChineseNumber, getWeekdayName } from 'chinese-lunar-date'
toChineseYear(2025, 'upper') // "二〇二五"
toChineseNumber(21, 'upper') // "二十一"
getWeekdayName(6, 'zh-HK') // "星期六"
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
}
type LocaleCode = 'zh-CN' | 'zh-TW' | 'zh-HK' | 'ja-JP' | 'ko-KR' | 'vi-VN'
cycle 標識第幾個 60 年週期,year 標識週期內的第幾年(1-60)。大多數場景下,直接使用 date.gregorianYear 即可。
這是因為時區差異。
<script src="dist/chinese-lunar-date.iife.js"></script>
<script>
const date = ChineseDate.ChineseDate.fromGregorian(2024, 6, 21)
</script>
如果您在使用過程中遇到問題,或有功能建議、商務合作等需求,歡迎透過電子郵件聯繫我們:
CalendarConfig 區分