Correct the example output for era conversion to match actual command results. Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
261 lines
5.8 KiB
Markdown
261 lines
5.8 KiB
Markdown
# Lunar Converter (農曆轉換器)
|
||
|
||
A comprehensive Chinese lunar calendar converter with support for historical era names, age calculation, and REST API services.
|
||
|
||
## 功能 (Features)
|
||
|
||
- **西曆 ↔ 農曆轉換**: 精確的公曆與農曆日期互轉,支援閏月處理
|
||
- **歷代年號轉換**: 支援明清年號、太平天國、民國、日本元號等
|
||
- **年齡計算**: 計算實歲(足歲)與虛歲
|
||
- **REST API**: 提供 HTTP API 服務
|
||
- **天文計算**: 使用 Skyfield 與 JPL 星曆資料進行精確計算
|
||
|
||
## 專案結構
|
||
|
||
```
|
||
lunar-converter/
|
||
├── lunar_calendar.py # 農曆天文計算引擎
|
||
├── converter.py # 西曆↔農曆轉換核心類別
|
||
├── chrono_converter.py # 歷史年號轉換
|
||
├── converter_with_eras.py # 整合型 CLI 工具
|
||
├── api.py # FastAPI REST API 伺服器
|
||
├── age_calculator.py # 年齡計算器
|
||
├── generate_lunar_calendar_json.py # 批量生成農曆資料
|
||
├── download_ephemeris.sh # JPL 星曆檔案下載腳本
|
||
├── de421.bsp / de422.bsp # JPL 星曆檔案
|
||
└── lunar_json/ # 生成的農曆資料 JSON 檔案
|
||
```
|
||
|
||
## 安裝 (Installation)
|
||
|
||
### 1. 複製儲存庫
|
||
|
||
```bash
|
||
git clone http://192.168.42.124:31337/timmy/lunar-converter.git
|
||
cd lunar-converter
|
||
```
|
||
|
||
### 2. 安裝依賴
|
||
|
||
```bash
|
||
# 使用 uv(推薦)
|
||
uv sync
|
||
|
||
# 或使用 pip
|
||
pip install skyfield jplephem numpy fastapi uvicorn loguru
|
||
```
|
||
|
||
### 3. 下載 JPL 星曆檔案
|
||
|
||
使用提供的下載腳本自動下載:
|
||
|
||
```bash
|
||
# 下載預設的 de421 (推薦,涵蓋 1900-2050,約 15MB)
|
||
./download_ephemeris.sh
|
||
|
||
# 或下載其他版本
|
||
./download_ephemeris.sh de422 # 涵蓋更長時間範圍,約 500MB
|
||
./download_ephemeris.sh de440s # 精簡版,1900-2150,約 30MB
|
||
./download_ephemeris.sh all # 下載全部版本
|
||
```
|
||
|
||
或從 [JPL 星曆官網](https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/) 手動下載,將檔案放在專案根目錄。
|
||
|
||
**各版本說明:**
|
||
- `de421.bsp` - 預設推薦,涵蓋 1900-2050,約 15MB
|
||
- `de422.bsp` - 涵蓋更長時間範圍(-13000+17000),約 500MB
|
||
- `de440s.bsp` - 精簡版,涵蓋 1900-2150,約 30MB
|
||
|
||
### 4. 生成農曆資料
|
||
|
||
```bash
|
||
# 生成單一年份
|
||
python lunar_calendar.py 2025
|
||
|
||
# 或批量生成所有年份(使用多處理加速)
|
||
python generate_lunar_calendar_json.py
|
||
```
|
||
|
||
生成的 JSON 檔案會儲存在 `lunar_json/` 目錄下。
|
||
|
||
## 使用方法 (Usage)
|
||
|
||
### 命令列工具
|
||
|
||
#### 西曆轉農曆
|
||
|
||
```bash
|
||
python converter_with_eras.py solar2lunar 2025-01-01
|
||
```
|
||
|
||
#### 農曆轉西曆
|
||
|
||
```bash
|
||
python converter_with_eras.py lunar2solar 2025-01-01
|
||
python converter_with_eras.py lunar2solar 2025-01-01 --leap # 閏月
|
||
```
|
||
|
||
#### 查詢歷史年號
|
||
|
||
```bash
|
||
python converter_with_eras.py era 1900-01-01
|
||
```
|
||
|
||
輸出示例:
|
||
```json
|
||
{
|
||
"光緒": "光緒 26 年",
|
||
"明治": "明治 33 年",
|
||
"星期": "Monday"
|
||
}
|
||
```
|
||
|
||
### Python API
|
||
|
||
```python
|
||
from converter import Converter
|
||
from chrono_converter import ChronoConverter
|
||
|
||
# 西曆轉農曆
|
||
converter = Converter()
|
||
result = converter.solar_to_lunar("2025-01-01")
|
||
print(result)
|
||
# {'西曆': '2025-01-01', '農曆': '12月2日', '干支': '甲辰', '生肖': '龍', '節氣': ''}
|
||
|
||
# 農曆轉西曆
|
||
solar_date = converter.lunar_to_solar(2025, 1, 1)
|
||
print(solar_date) # '2025-01-29'
|
||
|
||
# 查詢閏月
|
||
leap_month = converter.get_leap_month(2025)
|
||
print(leap_month) # 6 (表示閏六月)
|
||
|
||
# 歷史年號轉換
|
||
era_info = ChronoConverter.to_era(1900, 1, 1)
|
||
print(era_info)
|
||
```
|
||
|
||
### 年齡計算
|
||
|
||
```python
|
||
from datetime import date
|
||
from age_calculator import AgeCalculator
|
||
from converter import Converter
|
||
|
||
converter = Converter()
|
||
age_calc = AgeCalculator(converter)
|
||
|
||
solar_birth = date(1985, 6, 15)
|
||
lunar_birth = {"month": 5, "day": 28, "leap": False}
|
||
today = date(2025, 3, 9)
|
||
|
||
result = age_calc.calculate(solar_birth, lunar_birth, today)
|
||
print(f"實歲: {result.real_age}, 虛歲: {result.east_asian_age}")
|
||
```
|
||
|
||
## REST API
|
||
|
||
### 啟動伺服器
|
||
|
||
```bash
|
||
python api.py
|
||
```
|
||
|
||
伺服器會自動選擇可用端口並啟動。
|
||
|
||
### API 端點
|
||
|
||
#### 1. 西曆轉農曆
|
||
|
||
```bash
|
||
curl "http://localhost:PORT/solar2lunar?date=2025-01-01"
|
||
```
|
||
|
||
回應:
|
||
```json
|
||
{
|
||
"gregorian": "2025-01-01",
|
||
"lunar": "12月2日",
|
||
"ganzhi": "甲辰",
|
||
"zodiac": "龍",
|
||
"solar_term": ""
|
||
}
|
||
```
|
||
|
||
#### 2. 農曆轉西曆
|
||
|
||
```bash
|
||
curl "http://localhost:PORT/lunar2solar?date=2025-1-1"
|
||
```
|
||
|
||
#### 3. 查詢閏月資訊
|
||
|
||
```bash
|
||
curl "http://localhost:PORT/leap-info?year=2025"
|
||
```
|
||
|
||
回應:
|
||
```json
|
||
{
|
||
"year": 2025,
|
||
"leap_month": 6
|
||
}
|
||
```
|
||
|
||
## 支援的年號範圍
|
||
|
||
### 中國年號
|
||
|
||
- **明朝**: 萬曆、天啟、崇禎
|
||
- **清朝**: 天命、順治、康熙、雍正、乾隆、嘉慶、道光、咸豐、同治、光緒、宣統
|
||
- **太平天國**: 1851-1872
|
||
- **民國**: 1912 年起
|
||
|
||
### 日本元號
|
||
|
||
- 慶應、明治、大正、昭和、平成、令和
|
||
|
||
## 技術說明
|
||
|
||
### 農曆計算原理
|
||
|
||
本專案使用 [Skyfield](https://skyfield.readthedocs.io/) 天文計算庫,基於 JPL 發布的星曆檔案計算:
|
||
|
||
1. **朔望月**: 計算每次新月時間,確定農曆月份起始
|
||
2. **二十四節氣**: 計算太陽黃經每 15° 的節氣時間點
|
||
3. **閏月判定**: 根據「冬至後無中氣之月為閏月」規則判定閏月
|
||
4. **干支生肖**: 依據農曆年計算天干地支與生肖
|
||
|
||
### 時區
|
||
|
||
所有計算使用 UTC+8(台北時區)。
|
||
|
||
## 開發 (Development)
|
||
|
||
### 執行測試
|
||
|
||
```bash
|
||
pytest
|
||
```
|
||
|
||
### 程式碼格式化
|
||
|
||
```bash
|
||
ruff check .
|
||
ruff format .
|
||
```
|
||
|
||
## 授權 (License)
|
||
|
||
MIT License
|
||
|
||
## 貢獻 (Contributing)
|
||
|
||
歡迎提交 Issue 和 Pull Request!
|
||
|
||
## 相關資源
|
||
|
||
- [Skyfield 文檔](https://skyfield.readthedocs.io/)
|
||
- [JPL 星曆下載](https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/)
|
||
- [農曆計算原理](https://en.wikipedia.org/wiki/Chinese_calendar)
|