feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑 - 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口 - 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界 - 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名 - 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验 - 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口 - 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user