High-precision astronomical calculations for sun and moon events, available as both:
- A Rust library (
solunatus) - A CLI app (
solunatus)
Solunatus runs offline for core calculations and supports historical/future dates (from astronomical year -0999 through 3000).
- Sunrise, sunset, and solar noon
- Civil, nautical, and astronomical twilight
- Golden hour and blue hour times, plus dark-sky windows for astrophotography
- Moonrise, moonset, and transit
- Moon phase, illumination, altitude/azimuth, distance, perigee/apogee, supermoons
- Planet positions, magnitudes, and rise/set times (Mercury through Neptune), validated against JPL Horizons
- Equinox and solstice times
- Built-in city database (570+ cities)
- Interactive terminal UI (watch mode) with planets panel and altitude chart
- JSON output and calendar export (HTML/JSON/iCalendar)
- Scripting query mode (
--next sunrise) for cron and automation - Shell completions and man page generation
- Optional USNO validation reports
- Optional AI insights via local Ollama
Solunatus targets the latest stable Rust release for active development and is built on the Rust 2024 edition. The current release line supports stable Rust versions compatible with rust-version = "1.91", and that floor may rise in a minor release when security, dependency compatibility, or maintainability require it. If you need an older Rust toolchain, use an older Solunatus release that still supports it.
To upgrade an existing installation from crates.io:
cargo install solunatus --forcecargo install solunatusgit clone https://github.com/FunKite/solunatus.git
cd solunatus
cargo install --path .# Use a city from the built-in database
solunatus --city "New York"
# Or specify coordinates + timezone
solunatus --lat 40.7128 --lon -74.0060 --tz America/New_YorkBy default, Solunatus starts in interactive watch mode.
Press q to quit, s for settings, and r for reports.
solunatus --city "Tokyo" --no-promptsolunatus --city "Tokyo" --jsonsolunatus --city "Lisbon" --date 2026-01-15solunatus --city "Lisbon" \
--calendar \
--calendar-start 2026-01-01 \
--calendar-end 2026-01-31 \
--calendar-format html \
--calendar-output lisbon-jan-2026.htmlsolunatus --city "Denver" --next sunset --format isosolunatus --completions zsh > _solunatus
solunatus --manpage > solunatus.1solunatus --city "San Diego" --validatesolunatus --city "Seattle" --ai-insightsCore flags:
--city <CITY>--lat <LAT> --lon <LON> --tz <TIMEZONE>--date <YYYY-MM-DD>--json--calendar --calendar-start <DATE> --calendar-end <DATE>--calendar-format <html|json|ics>--calendar-output <PATH>--next <EVENT> --format <iso|unix|local|human>--completions <SHELL>--manpage--watch--no-prompt--no-save--strict
Optional flags (feature gated):
--validate(usno-validation)--ai-insights,--ai-server,--ai-model,--ai-refresh-minutes(ai-insights)
For full CLI docs, see docs/features/cli-reference.md.
Default features:
usno-validationai-insights
Examples:
# Minimal build (no USNO validation, no AI insights)
cargo install solunatus --no-default-features
# USNO validation only
cargo install solunatus --no-default-features --features usno-validation
# AI insights only
cargo install solunatus --no-default-features --features ai-insightsAdd dependency:
[dependencies]
solunatus = "0.6.1"
chrono = "0.4"
chrono-tz = "0.10"Basic example:
use chrono::Local;
use chrono_tz::America::New_York;
use solunatus::prelude::*;
fn main() {
let location = Location::new(40.7128, -74.0060).unwrap();
let now = Local::now().with_timezone(&New_York);
if let Some(sunrise) = calculate_sunrise(&location, &now) {
println!("Sunrise: {}", sunrise.format("%H:%M:%S"));
}
if let Some(sunset) = calculate_sunset(&location, &now) {
println!("Sunset: {}", sunset.format("%H:%M:%S"));
}
let (phase_name, phase_emoji) = get_current_moon_phase(&location, &now);
println!("Moon phase: {} {}", phase_emoji, phase_name);
}More examples: examples/
Solunatus uses NOAA-based solar methods and Meeus-based lunar methods, with validation tooling aligned to USNO-style conventions.
Planet positions use Keplerian mean elements with the major Jupiter, Saturn, and Uranus perturbation terms. They are validated against the JPL Horizons ephemeris: altitude/azimuth agree within 0.06° across 1990–2049 (a few seconds of rise/set time). Offline regression tests pin Horizons reference values on every build, and a scheduled CI workflow re-checks live Horizons data weekly.
This project is intended for educational, planning, and general-purpose astronomical use.
It is not certified for safety-critical navigation or legal timing decisions.
CLI settings are saved to:
~/.solunatus.json
Use --no-save to avoid writing configuration.
Crates.io is the supported distribution channel for published releases:
cargo install solunatusGitHub Releases are used for tags and release notes for each published version. They should not be treated as a guaranteed source of fresh binary artifacts unless a specific release explicitly says otherwise.
# Build
cargo build
# Test
cargo test
# Safer local test runner
./scripts/safe_local_test.shProject docs index: docs/README.md
Issue reports and feature requests are welcome:
MIT (LICENSE)