feat: 完善日月食与月掩几何链路并扩展历法接口

- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑
- 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口
- 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界
- 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名
- 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验
- 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口
- 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
This commit is contained in:
2026-09-17 12:27:40 +08:00
parent 9ee2163cc7
commit 2bf8478639
428 changed files with 85981 additions and 7998 deletions
+34 -3
View File
@@ -140,11 +140,12 @@ func LunarToSolarByYMDWithCalendar(year, month, day int, leap bool, system Ancie
return Time{}, fmt.Errorf("日期超出范围")
}
lmonth.day = day
date := ancientJDNToDate(lmonth.startJDN + day - 1)
jdn := lmonth.startJDN + day - 1
date := ancientJDNToDate(jdn)
if !ancientSolarYearInRange(date.Year()) {
return Time{}, fmt.Errorf("未找到对应日期")
}
return ancientTime(date, lmonth), nil
return markJulianOnlyJDN(ancientTime(date, lmonth), jdn), nil
}
func calendricalJieQiWithCalendar(year, term int, system AncientCalendarSystem) (time.Time, error) {
@@ -284,16 +285,46 @@ func lunarToSolarAncientDefault(year, month, day int, leap bool) (Time, bool) {
if !ok {
return Time{}, false
}
if result, ok := lunarToSolarAncientWithDefault(year, month, day, leap, system); ok {
return result, true
}
// 岁首跨公历年时正向按公历年选古历、反向只能按农历年选,两者会差一天;
// 这里换另一种默认古历再试,并要求与正向的选历一致。
if alternate, ok := ancientAlternateDefaultSystem(system); ok {
if result, ok := lunarToSolarAncientWithDefault(year, month, day, leap, alternate); ok {
return result, true
}
}
return Time{}, false
}
// lunarToSolarAncientWithDefault 用指定古历求农历日,并要求与正向的默认选历一致。
func lunarToSolarAncientWithDefault(year, month, day int, leap bool, system AncientCalendarSystem) (Time, bool) {
result, err := LunarToSolarByYMDWithCalendar(year, month, day, leap, system)
if err != nil {
return Time{}, false
}
if !ancientSolarYearInRange(result.Solar().In(getCst()).Year()) {
solarYear := result.Solar().In(getCst()).Year()
if !ancientSolarYearInRange(solarYear) {
return Time{}, false
}
if forwardSystem, ok := defaultAncientCalendarSystemForYear(solarYear); !ok || forwardSystem != system {
return Time{}, false
}
return result, true
}
// ancientAlternateDefaultSystem 返回另一种默认古历(春秋 ↔ 周),用于岁首跨界回退。
func ancientAlternateDefaultSystem(system AncientCalendarSystem) (AncientCalendarSystem, bool) {
switch system {
case AncientCalendarChunqiu:
return AncientCalendarZhou, true
case AncientCalendarZhou:
return AncientCalendarChunqiu, true
}
return AncientCalendarDefault, false
}
func innerSolarToLunarByYMDWithCalendar(year, month, day int, hmi time.Time, system AncientCalendarSystem) (Time, error) {
if system == AncientCalendarQinHan {
if err := validateQinHanCalendarSolarInput(year, month, day); err != nil {