- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
Astro
English | 中文
An astronomy library I have used for years for my own interest in astronomy and calendars.
⚠️ Time-scale change: UTC switches to leap hours on 2027-05-20
On 15 October 2026 the 28th General Conference on Weights and Measures (CGPM) adopted Resolution 5, "On the technical actions needed to ensure the continuity of UTC" (
Resolution-CGPM-28-5, DOI10.59161/CGPM2026RES5E): continuous UTC becomes effective on 20 May 2027 and the maximum value of|UT1−UTC|is widened from 0.9 seconds to 3600 seconds (1 hour) — a leap hour in place of a leap second.IERS Bulletin C 72 (2026-07-06) confirms that no leap second will be introduced at the end of December 2026; the leap-second mechanism ends on 2027-05-20, so the possible insertion point at the end of June 2027 will not carry one either.
From this release the library keeps 1972–2026 on the definitive leap-second table (those historical values are unchanged) and changes the default policy beyond the built-in window (which ends 2026-10-01) from
TimeScaleLeapSecondtoTimeScaleLeapHour; past the window TT−UTC stays at 69.184 seconds. The numeric values of theSetTimeScaleFuturePolicyconstants changed accordingly (TimeScaleLeapHouris now the zero value), so callers passing raw integers must update. See Time scales.
The library ships two ephemerides, selectable in one process or used side by side:
- Semianalytic model (
ModelSemianalytic, default): the argument structure and initial amplitudes of VSOP2013/TOP2013 (planets) and ELP/MPP02 (Moon), refitted to the DE ephemerides — DE441 for the planetary long range, DE440 for the modern segment and DE441 for the Moon — and folded into a single compact series table. The planetary table is about 452 KiB and the lunar table about 42 KiB, with no external ephemeris files. Its geocentric apparent direction error (RMS) in the modern range is about 0.007″ (Sun) and 0.076″ (Moon). - Legacy model (
ModelLegacy): the VSOP87/ELP2000-82 series with added long-term and per-body corrections. Switch to it to reproduce old values; its geocentric apparent direction error (RMS) in the modern range is about 0.04″ (Sun) and 0.75″ (Moon). See Accuracy and Performance.
External ephemerides can also be supplied through SPK or a custom engine.
Install
go get b612.me/astro
Highlights
- Civil and Chinese calendar conversion from 721 BCE to 3000 CE, solar terms, sexagenary dates, era names and historical calendars.
- Positions, rise/set, transit, distance, apparent diameter and physical ephemerides for the Sun, Moon and seven planets; lightweight Sun and Moon algorithms are also included.
- Solar and lunar eclipses, stellar and planetary lunar occultations, event searches, local contact times and global paths.
- Generic sky-event searches: ecliptic-longitude crossings, stationary points, phases, closest approach, rise/set at any altitude, perihelion/aphelion and heliacal visibility.
- Switchable ephemeris models, multiple instances used in parallel in one process, SPK multi-source stacking and optional perturbed propagation.
- SVG sky-event charts, GeoJSON geographic data and KML for viewing and time playback in Google Earth.
- A built-in catalog of 9100 stars with constellation lookup, coordinate corrections and rise/set calculations; CSV, Hipparcos, BSC5 and Stellarium external catalogs are also available.
- Celestial coordinate transformations, sidereal time, precession and nutation, refraction, astronomical formulas, sundial geometry and an optional lunar-limb terrain correction.
Example
Calculate the sunrise time, lunar phase and Chinese calendar date for a day in Xi'an:
package main
import (
"fmt"
"log"
"time"
"b612.me/astro/calendar"
"b612.me/astro/moon"
"b612.me/astro/sun"
)
func main() {
cst := time.FixedZone("CST", 8*3600)
date := time.Date(2026, 2, 17, 12, 0, 0, 0, cst)
rise, err := sun.RiseTime(date, 108.93, 34.27, 0, true)
if err != nil {
log.Fatal(err)
}
fmt.Println("Sunrise:", rise.Format("15:04:05"))
fmt.Println("Lunar phase:", moon.PhaseDesc(date))
day, err := calendar.SolarToLunar(date)
if err != nil {
log.Fatal(err)
}
fmt.Println("Chinese calendar:", day.Lunar().MonthDay())
}
Longitude and latitude are in degrees, positive east and north; the example uses a height of 0 metres and true makes the rise/set calculation account for atmospheric refraction. Rise/set functions return an error during polar day, polar night or when no event occurs on that date.
Package-level functions use the process-wide ephemeris model (semianalytic in default builds). To pin a model for a calculation, use astro.NewContext; multiple contexts can be used in parallel in one process:
func compareModels(date time.Time) {
legacy, err := astro.NewContext(astro.ModelLegacy)
if err != nil {
panic(err)
}
modern, err := astro.NewContext(astro.ModelSemianalytic)
if err != nil {
panic(err)
}
fmt.Println(legacy.Moon().PhaseDesc(date), modern.Moon().PhaseDesc(date))
riseLegacy, _ := legacy.Sun().RiseTime(date, 108.93, 34.27, 0, true)
riseModern, _ := modern.Sun().RiseTime(date, 108.93, 34.27, 0, true)
fmt.Println(riseLegacy.Format("15:04:05"), riseModern.Format("15:04:05"))
}
A context exposes per-module entry points such as Sun(), Moon(), Mars(), Eclipse() and Phenomena(), with the same signatures as their package-level counterparts. Models isolate the ephemeris only; ΔT, TT−UTC and civil time-scale policy remain process-wide settings. See Explicit ephemeris instances for custom engines, SPK and multi-source stacking.
Package Overview
basic contains the underlying algorithms, planet holds the built-in models and series, planet/spk reads external kernels, and tools provides numerical helpers. See Accuracy and performance for model composition, measured errors and performance; full signatures are also available in the Go API documentation.
Time Scale Conventions
Most observing APIs accept a civil instant as time.Time and handle UTC, UT1 and TT conversions internally. Before 1972 the library treats civil time as UT1, and as UTC thereafter; orbital epochs and some low-level APIs have separate time-scale requirements.
Angles default to degrees, apparent diameters to arcseconds, sidereal time to hours, and distances to AU or km as specified by the API. SVG and GeoJSON time labels default to UTC, with an explicit UT1 option. See Time scales for the exact conventions.
Beyond the monthly ΔT table, DUT1 and TT−UTC default to leap-hour extrapolation (TimeScaleLeapHour, matching the continuous UTC effective 2027-05-20); SetTimeScaleFuturePolicy switches between TimeScaleLeapHour (default), TimeScaleLeapSecond, TimeScaleAssumeUT1Tracking, TimeScaleFreezeUTCOffset and TimeScaleUT1Civil.
Observer Height Convention
Observer height is ellipsoidal height in metres. If only orthometric height H is available, convert it with the local geoid undulation N: height = H + N. See Observer height.
Scope And Accuracy
Accuracy varies with model, epoch, body and calculated quantity. The default model has changed from VSOP87/ELP2000-82 to the semianalytic tables: signatures are unchanged but values may differ. lite/sun and lite/moon use independent approximation chains and do not follow model switches.
See Accuracy and performance for model composition, error conventions and measured results. Professional occultation prediction, spacecraft navigation and similar uses also need ephemerides, time scales and physical models of matching accuracy; loading an SPK alone does not make every high-level result as accurate as the kernel.
License
The code and documentation are licensed under Apache-2.0. The third-party data embedded in this repository is not covered by Apache-2.0 and follows the terms of its own source; see NOTICE for the item-by-item statement:
- SELENE (KAGUYA) LALT lunar limb profile (
moon/limb/kaguya_lalt.bin): ISAS/JAXA, distributed under the ISAS Data Policy, which states that its rules are compatible with CC BY 4.0. - This project's own refits of VSOP2013/TOP2013 and ELP/MPP02 (
planet/internal/semianalytic/): the underlying theories are IMCCE / SYRTE. This project can neither grant nor restrict rights in those theories; Apache-2.0 applies only to this project's own code and compilation. - JPL DE440/DE441 and Horizons data (
*/testdata/,planet/spk/testdata/): NASA/JPL. - Astrometry in the built-in star catalogue (
basic/star_catalog.dat): derived from the Yale Bright Star Catalogue (VizieR V/50). - Natural Earth 1:50m physical land (
internal/svgmap/land_*.path): public domain.