SkillAgentSearch skills...

Astro

Astro: Go Astronomy Algorithms Library - Chinese Lunar Calendar, Solar/Lunar Eclipses, Sun/Moon/Planet Positions, Rise/Set, Planet Events, Stars, Coordinates, Orbits, Sundials and Lightweight Ephemerides (天文算法 Go 库:农历、日月食、日月行星位置、升落、行星天象、恒星、坐标、轨道、日晷与轻量星历)

Install / Use

npx skills add Starainrt/astro

Installs into whichever agent you are using.

README

Astro

English | 中文

Go Reference

自用多年的天文算法库,用于个人天文历法爱好、科普演示和轻量研究。

📚 本项目主要用于天文算法学习与验证,计算结果满足业余爱好级别需求。

基于《天文算法》(Astronomical Algorithms)一书实现,提供历法转换、太阳/月亮/行星位置、日月食、月掩、升落、中天、月相、恒星、坐标变换、物理星历、研究公式和通用小天体轨道传播等功能。太阳和行星部分使用内置 VSOP87 解析项,月球部分使用内置 ELP2000/82 解析级数,不依赖外部 JPL 星历文件。

没有特殊标注时,本程序所提供的坐标均为瞬时天球坐标;角度单位默认是度,视直径/视半径单位是角秒,距离单位按函数名使用 AU 或 km。

目录

安装

go get github.com/starainrt/astro

功能概览

  • 📅 历法转换:公历与农历互转(公元前721年-公元3000年或更久)、节气时刻
  • 🌞 太阳计算:天球位置、日出日落、日地距离、真太阳时、视高度角、视差角、日面物理参数(P/B0/L0)、视直径等
  • 🌙 月亮计算:天球位置、月出月落、地月距离、月相、朔望时间、视直径、亮边位置角、视差角、地心/站心天平动、近远地点、交点、最大赤纬等
  • 🪶 轻量链路lite/sunlite/moon 提供面向手表、前端、小程序和其它资源受限环境的轻量近似太阳/月亮算法,覆盖天球位置、升落和月相
  • 🌗 日月食:全局日食、站心日食、中心线/偏食足迹、月食、地方可见月食,以及局地示意图和全球见食图 SVG
  • 🌘 月掩:按指定赤经赤纬搜索恒星月掩,按有限圆盘计算行星月掩,支持指定地点接触时刻、全球掩带、几何掩甚点和 SVG
  • 🗺️ 地理输出:日食、月食和月掩结果可编码为带时间数据与可选时间标记的 GeoJSON;全球 SVG 使用无行政边界海岸线,并支持等经纬和南北极投影
  • 🪐 行星计算:七大行星天球位置、升落时间、合冲留、大距、水星/金星地心凌日等特殊天象时间、升交点/降交点、视直径/视半径、相位、视差角、节点、视星等与物理星历
  • 恒星计算:指定天球坐标所属星座;同时包含9100颗恒星数据库,可计算升降时间、视差角和视高度角,获取指定日期的恒星坐标信息
  • 🧭 坐标工具:黄道/赤道/地平坐标转换、站心坐标、恒星时、岁差、章动、角距离、大气折射、大气质量、视差角、银道坐标
  • 🔭 研究公式:黑体辐射、会合周期、星等距离换算、望远镜极限星等、恒星半径/温度/光度换算、大气质量模型
  • ☄️ 通用轨道:给定小行星、彗星或假想天体轨道根数,计算日心/地心位置和站心视位置,并提供距日/距地距离、日距角、相位角、照明比例、H-G 视星等和轻量视双星位置角/角距计算
  • 🕰️ 日晷:真/平太阳时换算、太阳时角、平太阳时/区时时角、平面日晷几何、赤道/水平/垂直日晷特例

包概览

| 包 | 主要能力 | | --- | --- | | calendar | 公历/农历互转、节气、历史朝代年号、古代历法信息 | | coord | 黄道/赤道/地平互转、恒星时、岁差、章动、站心坐标、大气折射、大气质量、视差角、银道坐标、手动黄赤交角和手动时角的研究接口 | | sun | 太阳位置、日出日落、晨昏朦影、均时差、真太阳时、视高度角、视差角、视直径、日面 P/B0/L0 | | moon | 月亮位置、月出月落、月相、朔望弦、视高度角、视差角、视直径、亮边位置角、地心/站心天平动、近远地点、交点、最大赤纬,以及恒星/行星月掩和全球掩带 | | lite/sun / lite/moon | 轻量太阳/月亮近似链路,面向分钟级升落、轻量天球位置和月相计算 | | eclipse / eclipse/svg | 全局/局地日月食、日食中心线与偏食足迹、局地可见性筛选、局地示意图与全球见食图 SVG | | moon/svg | 指定地点恒星/行星月掩视圆图,以及带掩带、中心线和时间标记的全球投影 SVG | | geojson | 将日食、月食和月掩的既有地理结果编码为 RFC 7946 GeoJSON,投影与样式由应用负责 | | mercury / venus | 水星、金星位置、升落、合日、留、大距、地心凌日、相位、视差角、视星等、视直径、节点和物理星历 | | mars / jupiter / saturn / uranus / neptune | 外行星位置、升落、合冲、留、方照、相位、视差角、视星等、视直径、节点和物理星历 | | earth | 地球轨道偏心率、近日点、远日点 | | star | 星座判定、恒星数据库、恒星自行/岁差/章动修正、恒星升落、视差角、视高度角 | | formula | 与具体日期无关的常用研究公式和天文奥赛公式,含大气质量模型 | | orbit | 通用日心二体圆锥曲线轨道传播,支持椭圆、近抛物、抛物和双曲轨道;另含相位/测光辅助和轻量视双星计算 | | sundial | 真/平太阳时换算、太阳时角、平太阳时/区时时角、平面日晷几何、时间线/赤纬曲线采样、赤道/水平/垂直日晷特例 |

很多接口额外提供 ...N 截断版本:

  • n < 0:使用本仓库当前内置的全部解析项
  • n >= 0:截断解析项,适合性能对比、粗算或算法研究

这里的“全部解析项”指package中已经内置的表项,不等同于外部发行版 VSOP/ELP 长表的全部原始数据。

大气质量接口的补充:

  • coord.Airmass... 面向观测场景,既可以直接传入视高度角,也可以从真高度角先做折射修正再计算
  • formula.Airmass... 只提供纯公式本身,不负责折射修正,适合已经在别处拿到视高度角或天顶距时直接调用

适用范围与精度

太阳与行星

太阳和行星使用内置 VSOP87 解析项,当前表项覆盖 J2000 前后约 4000 年。精度量级如下:

| 目标 | 黄经/黄纬 | 距离 | | --- | --- | --- | | 太阳/地球 | 约 0.1" | 约 0.1 × 10^-6 AU | | 水星、金星 | 约 0.2" | 约 0.2 × 10^-6 AU | | 火星 | 约 0.5" | 约 1 × 10^-6 AU | | 木星 | 约 0.5" | 约 3 × 10^-6 AU | | 土星 | 约 0.5" | 约 5 × 10^-6 AU | | 天王星 | 约 1" | 约 20 × 10^-6 AU | | 海王星 | 约 1" | 约 40 × 10^-6 AU |

这类精度适合常规天文历法、观测辅助、科普展示和个人研究。如果需要航天导航、掩星预报或严格动力学积分,应使用 JPL DE 等专业星历。

月球

月球使用内置的 ELP/MPP02 DE405 解析级数(截断版,保留主要周期项),库体积轻,不需要外部星历文件。它适合农历定朔、月相、升落、月食、业余月掩预报和常规位置计算;若需要极高精度月球测距、长期物理天平动或专业掩星,请以 JPL 星历或专门月球星历为准。

Lite 轻量链路

lite/sunlite/moon 是独立于 sun / moon 的近似实现。不依赖 VSOP87 或 ELP2000/82,适合 CPU / 内存受限环境。

  • lite/sun:简化太阳真黄经 / 视黄经公式 + 轻量赤道坐标转换
  • lite/moon:Schlyter 风格月球近似(约 15 个摄动项)+ 轻量站心修正
  • 升落搜索:固定步长扫描 + 二分,不走主链的高精度章动迭代
  • 计算链路零堆分配(0 allocs/op),月球位置约 1µs,比主链快 20–60 倍

能力边界:

| 包 | 位置模型 | 升落搜索 | 主要用途 | | --- | --- | --- | --- | | lite/sun | 简化太阳真/视黄经 + 轻量赤道坐标转换 | 30 分钟步长扫描 + 二分 | 日出日落、太阳高度角、表盘/前端周期刷新 | | lite/moon | Schlyter / vFPS 月球近似 + 轻量站心修正 | 15 分钟步长扫描 + 二分 | 月出月落、月相、月龄、轻量月球观测辅助 |

与主链 sun / moon 的误差(2026 全年,8 个站点;升落每 7 或 15 天取样,月相月龄每 6 小时):

| 能力 | 平均绝对误差 | P95 | 最大绝对误差 | 备注 | | --- | --- | --- | --- | --- | | lite/sun 日出 | 0.02 min | 0.04 min | 0.31 min | 样本中无事件存在性分歧 | | lite/sun 日落 | 0.02 min | 0.06 min | 0.35 min | 2 个高纬样本在跨午夜“归属哪一天”上有语义差异 | | lite/moon 月出 | 0.28 min | 0.57 min | 1.44 min | 样本中无事件存在性分歧 | | lite/moon 月落 | 0.36 min | 0.86 min | 1.24 min | 1 个高纬样本在“当天是否有月落”上与主链判断不同 | | lite/moon Phase() | 0.00089 | 0.00185 | 0.00243 | 和 moon.Phase 对比 | | lite/moon PhaseAge() | 0.003 d | 0.010 d | 0.014 d | 约平均 4.3 分钟、P95 14.4 分钟、最大 20.2 分钟 | | lite/moon 地心黄经 | 2.41' | 6.82' | 9.91' | 相对主链月球位置 | | lite/moon 地心黄纬 | 0.87' | 1.83' | 2.92' | 相对主链月球位置 |

本地 Go testing.Benchmark 参考值(绝对值因机器而异,相对趋势稳定):

| 接口 | 主链 | lite | 加速倍数 | 主链分配 | lite 分配 | | --- | --- | --- | --- | --- | --- | | Sun ApparentRaDec | 13.392 µs/op | 231.0 ns/op | 57.97x | 0 B/op, 0 allocs/op | 0 B/op, 0 allocs/op | | Sun Altitude | 16.405 µs/op | 681.5 ns/op | 24.09x | 0 B/op, 0 allocs/op | 0 B/op, 0 allocs/op | | Sun RiseTime | 202.994 µs/op | 18.823 µs/op | 10.78x | 0 B/op, 0 allocs/op | 0 B/op, 0 allocs/op | | Moon ApparentRaDec | 65.273 µs/op | 1.035 µs/op | 63.06x | 297202 B/op, 70 allocs/op | 0 B/op, 0 allocs/op | | Moon Phase | 40.264 µs/op | 940.6 ns/op | 42.83x | 178321 B/op, 42 allocs/op | 0 B/op, 0 allocs/op | | Moon Altitude | 44.883 µs/op | 2.275 µs/op | 19.73x | 178321 B/op, 42 allocs/op | 0 B/op, 0 allocs/op | | Moon RiseTime | 659.886 µs/op | 77.600 µs/op | 8.50x | 2377613 B/op, 560 allocs/op | 0 B/op, 0 allocs/op |

需要日月食、物理天平动或高纬边界判定时,仍用主链 sun / moon

精度校验参考

下面这些函数曾与 JPL Horizons、NASA GSFC 等资料对照,可作为使用时判断结果量级的参考:

  • 太阳/行星/月亮视直径:与外部基线最大差异从 0.000002"0.194598" 不等,月亮因视差和距离变化更敏感
  • 太阳物理星历 P/B0/L0:最大差异约 0.003349° / 0.003986° / 0.047394°
  • 行星升/中天/落:已用 JPL Horizons 电视事件(TVH, Time-Varying Hourly)做对比校验;该基线按 1 分钟步长生成,当前结果与 Horizons 事件时间在分钟级上对齐
  • 月出/月落:aero=true 按动态标准折射和实时月球视半径计算上缘过地平线。7 个地点、14 个海平面事件相对 JPL Horizons DE441 的平均/最大差异约 0.30s / 0.75s
  • 月出/月落的其他口径:相对固定 -0.8333° 的 MET Norway(Skyfield 1.53 + DE440s)约 38.77s / 76.22s;相对未公开地平线口径的 IMCCE Miriade 平均约 2m13.46s61°N 低仰角样本最大约 6m41.82s
  • 月掩恒星全球路径:2025-06-05 月掩进贤增九(HR 4799)样例相对项目记录的参考值,掩始/掩甚/掩终差异约 +2.30s / -1.37s / -3.12s;掩甚经纬度差异约 +0.0122° / +0.0105°,掩带宽为 3582.4 km,与参考 3571.9 km 相差约 10.5 km
  • 地球近日点/远日点:时刻最大差异约 1m28.84s,距离最大差异约 0.000000039837 AU
  • 月球主链位置:当前算法为 ELP/MPP02 DE405 解析级数截断版;在 -2000 年四个 JPL/Horizons JDTT 样本上,相对 JPL/Horizons 的最大差异约为黄经 219.6"、黄纬 25.8"、距离 34.3 km
  • 月球近地点/远地点:时刻最大差异约 15m53.45s,距离最大差异约 39.758 km
  • 月球最大赤纬:时刻最大差异约 2.43s,赤纬最大差异约 0.00006431°

站心时角修复后的影响边界:月出/月落、指定地点月掩、月球站心坐标,以及地方月食结果中的食甚月高和可见性判断使用修复后的 UT 时角链。日食和月食的全球接触时刻、食甚、食分等主体结果来自各自的地心/贝塞尔几何,不经过该站心转换,因此现有 NASA 精度数据无需随之改写。

快速开始

历法转换与节气

本 package 支持公历与中国传统农历日期之间的相互转换,并提供节气信息。支持年份范围为公元前721年至公元3000年(部分现代算法可更久)。 农历本质上是阴阳合历(Lunisolar Calendar),但为兼顾大众习惯与代码简洁性,相关函数命名采用 Lunar 而非更学术的 Lunisolar

历法说明

  • 默认路由:按年份自动选择,先秦段使用春秋/古六历重建,-220..-104 使用秦汉颛顼历,-103..1912 使用历表,1913 年后使用现代算法。
  • 显式古历:如果需要指定某一古历系统,请使用 SolarToLunarWithCalendar / LunarToSolarWithCalendar 这类 API。
  • 数据来源:古历部分主要参考《寿星天文历》;使用 ytliu0教授的网站数据做验证;现代段依据GB/T 33661-2017编排,通过 VSOP87、ELP定气定朔 。
  • 节气JieQi 返回现代天文计算的节气时刻;CalendricalJieQi 返回历法相符节气日期。

使用须知

1. 同一公历日期可能对应多个农历日期

在多个政权并存的历史时期(如三国时期),不同政权可能使用不同历法,造成同一公历日期对应多个农历日期。本程序尽可能提供所有可能的转换结果。

2. 同一农历日期可能对应多个公历日期

不仅因多个政权历法不同,同一政权在历法改革中也可能出现此类情况。例如,武则天改历后,圣历三年出现了两个腊月。

3. 公历历法处理规则

本程序基于儒略日进行计算,公历部分处理规则如下:

  • 1582年10月15日之后:使用格里高利历
  • 1582年10月4日之前:使用儒略历
  • 公元8年之前:使用逆推儒略历
  • 1582年10月4日的下一天为1582年10月15日
  • 1582年10月5日到10月14日这10个公历日期不存在,相关接口会直接拒绝
  • 年份表示:0年表示公元前1年,-1年表示公元前2年,以此类推
4. 时区说明

本 package 主要面向中国历法,因此定气和定朔的计算默认采用北京时间(UTC+8)。对于使用其他时区的地区,若直接套用中国农历的编排规则,可能会产生日期偏差。

为方便探索与研究,本 package 提供了底层方法 SolarLunar,它们支持在自定义时区下,按照**现行中国农历算法(GB/T 33661-2017)**进行公历与农历的相互转换。 如果只需北京时间下的标准转换,请直接使用封装好的 SolarToLunarLunarToSolar 方法。

示例:农历规则要求冬至必须落在农历十一月。以1984年冬至为例,计算可得:

ws := calendar.JieQi(1984, 270)
fmt.Println(ws)
fmt.Println(moon.ClosestShuoYue(ws))

| 节令 | 东八区 (UTC+8) | 东七区 (UTC+7) | |------|----------------|----------------| | 冬至 | 1984-12-22 | 1984-12-21 | | 朔日 | 1984-12-22 | 1984-12-22 |

可见,对于东八区(中国),1984年12月22日既是冬至又是朔日,因此该日为农历十一月初一;而在东七区,冬至提前至12月21日,导致12月22日已成为腊月初一。

类似地,春节的日期也会相差一天。1985年正月初一对应的公历日期,在东八区为2月20日,在东七区则为1月21日:

fmt.Println(calendar.Solar(1985, 1, 1, false, 8.0))
fmt.Println(calendar.Solar(1985, 1, 1, false, 7.0))
5. Go 语言特别注意

⚠️ Go 标准库 time.Time 在历法处理上与本程序存在差异:

  • Go 语言在1582年10月15日之前使用逆推格里高利历,而非儒略历。若不使用 Add 方法,一般可正常使用。
  • 因此,在1582年10月15日之前,time.Time.Weekday() 返回结果与本程序计算结果不一致。 例如:1582年10月4日,本程序为星期四,Go 语言判断为星期一。

建议解决方案:

如需获得与本程序一致的星期数,可使用如下方法:

// date 应为当日0时的 time.Time
weekday := int(calendar.Date2JDE(date)+1.5) % 7
// 0表示星期日,1表示星期一,……,6表示星期六

若在1582年之前使用 time.Time 的 Add 或 AddDate 方法,请注意其在某些年份可能不准确。 例如:700年儒略历为闰年,而 Go 使用的逆推格里高利历中700年不是闰年。

历法转换

公历转农历
  • 输入:公历日期 (time.Time)
  • 输出calendar.Time 对象,可能包含多个对应的农历日期
  • 功能:可从返回对象中获取:
    • 农历日期的详细描述
    • 年、月、日的天干地支
    • 所属朝代、皇帝、年号等信息
    • 完整的结构化农历信息
农历转公历

支持两种调用方式:

方式一:传入农历字符串

支持以下格式(示例):

  1. 年号+年+月+日:如 "元丰六年十月十二"(闰月前加"闰",日期格式为"初一"、"二十"等)
  2. 年号+年+月+干支日:如 "元嘉二十七年七月庚午"
  3. 年份+月+日:如 "二零二五年正月初一"(闰月前加"闰",适用于现代日期)
  4. 年份+月+干支日:如 "二零二五年正月戊戌日"
  5. 阿拉伯数字+月+日:可以将中文数字替换为阿拉伯数字,如 "2025年1月1日",代表二零二五年正月初一
  6. 注意历史场景:历史上月份名称可能与现代不同(如武则天时期“正月”与“一月”代表不同月份),请使用汉字数字确保准确性

⚠️ 特别提醒: 农历年份与公历年份并非完全重合。例如:公历2025年1月28日(除夕)对应农历2024年

Related Skills

View on GitHub
GitHub Stars155
CategoryDevelopment
Updated2d ago
Forks30

Languages

Go

Security Score

100/100

Audited on Aug 6, 2026

No findings