CJK日历转换器
SQLite支持的历史日历转换系统 中文、日文、韩文和越南文 日期。在传统的东亚阴阳历和公历/儒略历之间转换,使用 朱利安日数(JDN) 作为全球支点。
为人类用户(通过REST API)和LLM(通过MCP服务器或API)设计。
免责声明: 该项目尚未对所有历史资料进行彻底测试。东亚历史日期的日历转换本质上是复杂的——不同的来源有时在闰月位置、时代边界和日历改革日期上存在分歧。可能会出现错误,尤其是: - 王朝过渡时期或竞争日历期间的日期 - 时代边界附近的越南时代年份计数(可能存在±1年的偏移) - DILA数据集中未完全涵盖的外围或短命王朝 - Prolifetic日期范围(一个时代实际使用之前/之后的假设扩展) 始终与权威来源进行交叉引用,以供学术或批判性使用。
______________________________________________________________________
运作原理
每个日历日期,无论是公历、儒略历、中国的阴阳历、日本帝国、韩国还是越南,都可以映射到一个独特的 儒略日数 (一个从公元前4713年1月1日开始计算天数的整数)。这使得JDN成为完美的中间表示:
崇禎三年四月初三 → JDN 2316539 → 1630-05-14 (Gregorian)
→ 寛永七年四月三日 (Japanese)
→ 天聰四年四月三日 (Later Jin/清前身)
→ 朝鮮七年四月三日 (Korean)
→ 後黎朝德隆元年四月三日 (Vietnamese)该数据库存储了约131000条JDN范围的阴历月记录,包括:
| 国家 | 覆盖范围 | 来源 |
|---|---|---|
| 中国 | ~公元前220年-公元1912年 | DILA权威数据库 |
| 日本 | 公元593-1872年 | DILA权威数据库 |
| 韩国 | 公元前56年–公元1885年 | DILA权威数据库 |
| 越南 | 公元544-1945年 | 来源于中国农历月+越南时代的数据 |
______________________________________________________________________
快速开始
先决条件
- 紫外线 (Python包管理器)
- Python 3.12+(uv会自动安装)
设置
git clone https://github.com/kltng/calendar_converter.git
cd calendar_converter
# Install dependencies
uv sync --extra dev
# Download the DILA source data
mkdir -p data/raw
curl -L -o data/raw/authority_time.zip \
"https://authority.dila.edu.tw/downloads/authority_time.2012-02.zip"
cd data/raw && unzip authority_time.zip && cd ../..
# Build the SQLite database
uv run python -m data.scripts.build_db
uv run python -m data.scripts.add_vietnamese
# Run tests to verify
uv run pytest运行API服务器
uv run uvicorn src.calendar_converter.api:app --reload --port 8000打开http://localhost:8000/docs用于交互式Swagger UI。
码头工人
docker build -t calendar-converter .
docker compose upSQLite数据库嵌入在容器映像中,不需要外部数据库。
______________________________________________________________________
用法
1.REST API
转换CJK日期
curl "http://localhost:8000/convert?date=崇禎三年四月初三"答复:
{
"jdn": 2316539,
"gregorian": "1630-05-14",
"julian": null,
"ganzhi": {
"year": "庚午",
"month": "辛巳",
"day": "壬子"
},
"cjk_dates": [
{
"era_name": "崇禎",
"dynasty_name": "明",
"country": "chinese",
"year_in_era": 3,
"month": 4,
"month_name": "四",
"is_leap_month": false,
"day": 3
},
{
"era_name": "天聰",
"dynasty_name": "後金",
"country": "chinese",
"year_in_era": 4,
"month": 4,
"day": 3
},
{
"era_name": "寛永",
"dynasty_name": "江戸時代",
"country": "japanese",
"year_in_era": 7,
"month": 4,
"day": 3
}
]
}按朱利安日数转换
curl "http://localhost:8000/convert?jdn=2316539"按公历日期转换
curl "http://localhost:8000/convert?gregorian=1630-05-14"用国家暗示消除分歧
当一个时代名称在各国共享时,请使用 country 参数:
curl "http://localhost:8000/convert?date=天保三年閏九月十五日&country=japanese"消除时代名称的歧义
许多时代的名字在各个朝代都被重复使用。当转换器找到多个匹配的时代时,响应包括 ambiguous: true 和一个 other_candidates 显示所有替代解释的列表:
curl "http://localhost:8000/convert?date=乾德二年正月初一"{
"jdn": 2057111,
"gregorian": "0920-01-29",
"ambiguous": true,
"other_candidates": [
{
"jdn": 2073191,
"gregorian": "0964-02-21",
"era_name": "乾德",
"dynasty_name": "吳越",
"emperor_name": "忠懿王",
"country": "chinese",
"year_in_era": 2,
"month": 1,
"day": 1
},
{
"jdn": 2073191,
"gregorian": "0964-02-21",
"era_name": "乾德",
"dynasty_name": "北宋",
"emperor_name": "太祖",
"country": "chinese",
"year_in_era": 2,
"month": 1,
"day": 1
}
],
"cjk_dates": [ ... ]
}使用 dynasty 或 emperor 提示缩小到特定时代:
# Narrow to Northern Song dynasty
curl "http://localhost:8000/convert?date=乾德二年正月初一&dynasty=北宋"
# Narrow by emperor name
curl "http://localhost:8000/convert?date=上元二年正月初一&emperor=肅宗"
# Combine hints
curl "http://localhost:8000/convert?date=至元三年正月初一&dynasty=元&emperor=順帝"当提示解决歧义时, ambiguous 将是 false 和 other_candidates 将是空的。
搜索时代
# By era name
curl "http://localhost:8000/eras?name=崇禎"
# By dynasty
curl "http://localhost:8000/eras?dynasty=明"
# By country
curl "http://localhost:8000/eras?country=vietnamese"批量转换
curl -X POST http://localhost:8000/convert/batch \
-H "Content-Type: application/json" \
-d '["崇禎三年四月初三", "康熙元年正月初一", "嘉隆元年正月初一"]'下载数据库
curl -o calendar.db http://localhost:8000/db/download2.直接使用SQLite数据库
下载 calendar.db 并使用任何SQLite客户端进行查询:
-- Find all eras named 崇禎
SELECT * FROM era_summary WHERE era_name = '崇禎';
-- Find the lunar month containing a specific JDN
SELECT m.*, es.era_name, es.dynasty_name, es.country
FROM month m
JOIN era_summary es ON es.era_id = m.era_id
WHERE m.first_jdn = 2316539;
-- List all Vietnamese eras
SELECT era_name, dynasty_name, start_jdn, end_jdn
FROM era_summary WHERE country = 'vietnamese'
ORDER BY start_jdn;
-- Find concurrent eras for a given year (JDN range)
SELECT es.era_name, es.dynasty_name, es.country
FROM era_summary es
WHERE es.start_jdn = 2316539;3.MCP服务器(LLM集成)
MCP服务器允许LLM通过 模型上下文协议支持三种传输方式:
选项A:流式HTTP(远程)
部署的API包括位于的MCP端点 /mcp/。将其用于支持Streamable HTTP传输的任何MCP客户端,无需本地安装。
{
"mcpServers": {
"calendar": {
"type": "streamable-http",
"url": "https://calendar-converter.098484.xyz/mcp/"
}
}
}选项B:SSE(远程)
对于使用SSE传输的MCP客户端(例如LM Studio),请连接到 /sse/ 端点:
{
"mcpServers": {
"calendar": {
"type": "sse",
"url": "https://calendar-converter.098484.xyz/sse/"
}
}
}选项C:stdio(本地)
对于本地使用,请直接运行基于stdio的MCP服务器:
{
"mcpServers": {
"calendar": {
"command": "uv",
"args": ["run", "python", "-m", "src.calendar_converter.mcp_server"],
"cwd": "/absolute/path/to/calendar_converter"
}
}
}stdio服务器还支持SSE传输,供LM Studio等客户端本地使用:
uv run python -m src.calendar_converter.mcp_server --transport sse --port 8001可用的MCP工具
| 工具 | 说明 | 必需参数 |
|---|---|---|
convert_cjk_date | 将CJK日期字符串转换为JDN+所有等效值 | date (字符串) |
convert_jdn | 将儒略历日数转换为所有日历 | jdn (整数) |
convert_gregorian_date | 将YYYY-MM-DD转换为所有日历 | date (字符串) |
search_era | 搜索时代元数据 | name, dynasty,或 country |
所有转换工具都接受可选的消歧参数: country ("chinese", "japanese", "korean", "vietnamese"), dynasty (例如。, "唐", "北宋"),以及 emperor (例如。, "肅宗").当一个时代名称与多个时代匹配时,响应包括 ambiguous: true 随着 other_candidates 列出所有备选方案——然后LLM可以使用提示重新查询。
______________________________________________________________________
支持的输入格式
CJK日期字符串
| 格式 | 示例 | 解析方式 |
|---|---|---|
| 标准中文 | 崇禎三年四月初三 | 崇禎 时代,第3年,第4个月,第3天 |
| 与日 后缀 | 康熙六十一年十二月二十九日 | 康熙 纪元61年12月29日 |
| 闰月(长) | 天保三年閏九月十五日 | 天保 纪元,第3年,闰月9日,第15天 |
| Yuan year (元年) | 崇禎元年正月初一 | 崇禎 时代,第1年,第1个月,第1天 |
| 正月 | 嘉隆元年正月初一 | 嘉隆 时代,第1年,第1个月,第1天 |
| 廿/卅 shorthands | 康熙三年臘月廿九 | 康熙 时代,第3年,第12个月,第29天 |
| 仅年份 | 崇禎三年 | 那年的第一个月 |
| 仅限年+月 | 崇禎三年四月 | 当月第一天 |
| 甘孜年 | 嘉慶甲子年 | 嘉庆era,year with ganzhi甲子 |
| 全甘孜 | 崇禎庚午年辛巳月壬子日 | 通过六年周期查找解决 |
| 混合灵芝+数字 | 崇禎庚午年四月初三 | 甘孜年+数字月/日 |
日语速记
| 格式 | 示例 | 解析方式 |
|---|---|---|
| 明治 | M45.7.30 | 明治45年7月30日 |
| 大正 | T15.12.25 | 大正15年12月25日 |
| 昭和 | S64.1.7 | 昭和64年1月7日 |
| 平成 | H26.6.8 | 平成26年6月8日 |
| Reiwa | R1.5.1 | 令和1年5月1日 |
______________________________________________________________________
数据库模式
dynasty (id, type) -- 'chinese'|'japanese'|'korean'|'vietnamese'
dynasty_name (dynasty_id, name, ranking, language_id)
└─ emperor (id, dynasty_id)
emperor_name (emperor_id, name, ranking, language_id)
└─ era (id, emperor_id)
era_name (era_id, name, ranking, language_id)
└─ month (id, era_id, year, month, month_name, leap_month,
first_jdn, last_jdn, ganzhi, start_from, status, eclipse)
era_summary (VIEW) -- denormalized join for queries: era + emperor + dynasty + JDN range
period -- historical period spans
day_comment -- annotations for specific JDNs (historical events, eclipses)这 month 表格是核心:每一行代表一个阴历月及其JDN范围。个别天数来源于 first_jdn + (day - start_from).
______________________________________________________________________
关键概念
朱利安日数(JDN): 从公元前4713年1月1日格林尼治标准时间中午开始的连续整数天计数(儒略历)。每个日历日期都映射到一个JDN。这避免了在日历系统之间需要成对转换公式。
日月历: 东亚历法同时追踪阴历月(29-30天)和太阳年。当一个阴历月不包含“主节气”时,它就变成了闰月。这是天文决定的,而不是公式决定的——必须查阅历史数据。
Era Names(年号): 重新设置年份计数的统治时期名称。一个皇帝可以使用多个时代的名字。同一个名字可以出现在不同的朝代和国家(例如。,太平 使用10+次)。始终使用王朝或国家来消除歧义。
Sexagenary Cycle (干支): 由10个天干×12个地支组成的60单位循环。适用于年、月、日和小时。年份ganzhi存储在数据库中;ganzhi月份是通过以下公式计算的五虎遁 公式;根据JDN计算甘孜日。
防腐剂日期: 标记的日期 status='P' 将日历系统扩展到其实际历史用途之外(例如,在那个时代结束后使用一个时代名称来表示日期,因为历史来源是这样引用它们的)。
______________________________________________________________________
代理技能(克劳德代码/LLM工具使用)
这 skill/ 目录包含 独立代理技能 -一个自包含的、零依赖的Python脚本,带有自己的SQLite数据库,任何LLM代理(Claude Code等)都可以用于日历转换,而不需要完整的API服务器。
包含内容
skill/
├── SKILL.md # Skill manifest and documentation
├── scripts/
│ ├── calendar_converter.py # Standalone converter (Python 3.10+, stdlib only)
│ └── .gitignore # Ignores downloaded calendar.db
└── references/
└── database_schema.md # SQLite schema and query patterns设置
# Download the SQLite database (~14 MB) on first use
python3 skill/scripts/calendar_converter.py setupCLI使用情况
# CJK date → Gregorian
python3 skill/scripts/calendar_converter.py convert "崇禎三年四月初三"
# Gregorian → all CJK calendars
python3 skill/scripts/calendar_converter.py gregorian 1644 3 19
# Julian Day Number → all calendars
python3 skill/scripts/calendar_converter.py jdn 2299161
# Search eras
python3 skill/scripts/calendar_converter.py eras --name 康熙
python3 skill/scripts/calendar_converter.py eras --dynasty 明 --country chinese添加到技能中心
复制 skill/ 将目录(或符号链接)添加到技能中心:
cp -r skill/ /path/to/your-skill-hub/cjk-calendar该技能完全自包含:零外部依赖,下载自己的数据库,仅使用Python 3.10+stdlib运行。
______________________________________________________________________
发展
# Run all tests (1416 tests)
uv run pytest
# Run a single test file
uv run pytest tests/test_parser.py
# Run a specific test
uv run pytest tests/test_converter.py::TestGanzhi::test_full_ganzhi_in_conversion -v
# Run CBDB verification tests only
uv run pytest tests/test_cbdb_verification.py -v
# Rebuild the database from scratch
uv run python -m data.scripts.build_db
uv run python -m data.scripts.add_vietnamese测试套件
| 文件 | 测试 | 描述 |
|---|---|---|
test_parser.py | 23 | CJK日期字符串解析 |
test_converter.py | 39 | JDN转换、ganzhi、消歧 |
test_api.py | 19 | FastAPI端点集成 |
test_mcp.py | 10 | MCP stdio服务器工具 |
test_dila_verification.py | 5 | DILA参考日期验证 |
test_cbdb_verification.py | 1310 | 根据外部数据集进行时代名称交叉验证 |
______________________________________________________________________
数据来源和确认
该项目建立在几个机构和个人的工作之上:
DILA权威数据库(主要来源)
核心日历数据(中文、日文、韩文)来自 法鼓文科学院(DILA) 时间权威数据库,由大法学院图书馆和信息中心于2008年至2010年收集。
- 网站: https://authority.dila.edu.tw/
- 下载: https://authority.dila.edu.tw/docs/open_content/download.php
- github: https://github.com/DILA-edu/Authority-Databases
- 作者 西蒙·怀尔斯,DDBC
- 许可证: 知识共享署名-相同方式共享3.0未翻译
- 日本数据 基于Takashi SUGA提供的数据
DILA数据库使用儒略历日数作为日期指定的基本单位,阴历月是最小的存储实体。这个优雅的设计激发了这个项目的建筑灵感。
CeJS(无色回声JavaScript)
这 CeJS kanasimi的图书馆为越南历法时代和转换结果的验证提供了参考数据。
- 存储库: https://github.com/kanasimi/CeJS
- Era Converter演示: https://kanasimi.github.io/CeJS/\_test%20suite/era.htm
- 新闻报道: 公元前246年至公元2100年,跨越多个日历系统
中国传记数据库
这 CBDB 哈佛大学的项目提供了用于交叉验证测试的nianhao(时代名称)验证数据。
- 网站: https://projects.iq.harvard.edu/cbdb
- NIAN_HAO表: https://input.cbdb.fas.harvard.edu/codes/NIAN_HAO
- 相关NPM包(cn时代): https://www.npmjs.com/package/cn-era
Julian Day数算法
联合数据网↔ Gregorian/Julian转换算法基于:
- Jean Meeus, *天文算法* (威尔曼·贝尔,1991)
- E.G.理查兹,《日历》 *天文年鉴解释性补充* (2013)
- 朱利安日-维基百科
越南历史数据
越南王朝和时代信息来源于:
- *《大越史记全书》* (大越史记全书)—Complete Annals ofĐại Việt
- 越南时代名称年表——维基百科
- CeJS越南时代数据(见上文)
Sexagenary Cycle (干支) Computation
月份甘孜使用传统五虎遁 (五只老虎)公式。根据JDN,使用根据已知历史日期校准的mod-60循环计算甘孜日。
______________________________________________________________________
许可证
DILA权威数据库数据的许可证如下 CC BY SA 3.0。此存储库中的代码在MIT许可证下可用。如果您使用日历数据,请根据DILA授权数据库的许可证要求对其进行属性设置。
