Hevelius

Documentation

Getting started

Hevelius Ephemeris computes where the Sun, Moon, planets and stars are – and when things happen in the sky. It reads NASA JPL ephemerides and applies the astronomical reductions (light-time, aberration, precession, nutation) written from scratch in pure Dart.

The package is not yet on pub.dev. This documentation describes version 0.1.0, which will be the first release.

Install

dart pub add hevelius_ephemeris

It is pure Dart – no Flutter dependency and no native libraries – so it works in Flutter apps, command-line tools and on servers.

Download the JPL data

The ephemerides are published by NASA JPL and are not bundled with the package. A small program downloads them and checks their SHA-256 sums:

dart run hevelius_ephemeris:download_jpl                  # de440s – 32 MB, 1849–2150
dart run hevelius_ephemeris:download_jpl de442            # 115 MB, 1550–2650
dart run hevelius_ephemeris:download_jpl de441            # 3.3 GB, −13200 … +17191
dart run hevelius_ephemeris:download_jpl --dir eph de442  # into another folder

Files are saved to data/jpl/ by default. Start with de440s; use de442 for 1550–2650 and de441 for historical dates.

First program

Positions for a horoscope: Albert Einstein, born in Ulm on 14 March 1879 at 11:30 local mean time (10:50 UT).

example/example.dart
import 'package:hevelius_ephemeris/hevelius_ephemeris.dart';
import 'package:hevelius_ephemeris/spk_io.dart';

void main() {
  final ephemeris = SpkEphemeris([openSpkFile('data/jpl/de440s.bsp')]);

  final jdUt = julianDay(1879, 3, 14, hour: 10, minute: 50);
  final jdTT = julianDayTT(jdUt);

  final sun = geocentricEcliptic(ephemeris, Naif.sun, jdTT);
  print(sun.longitude); // 353.508° – 23°30′28″ Pisces

  final node = lunarPoint(ephemeris, LunarPoint.trueNode, jdTT);
  final a = angles(jdUt, 48.4, 10.0);
  print(a.ascendant); // 101.646° – 11°38′47″ Cancer
}
Sun      23° Psc 30′ 28″
Moon     14° Sgr 31′ 33″
Mercury   3° Ari 08′ 38″
Venus    16° Ari 59′ 06″
Node      2° Aqr 43′ 53″
ASC      11° Can 38′ 47″
MC       12° Psc 50′ 24″

The full program, with the formatting of degrees, is example/example.dart in the package. The results agree with astro.com to a fraction of an arcsecond.

Time

Every moment is a Julian day – a day count with a fraction. Two time scales matter:

The difference is ΔT = TT − UT: about 69 s today, minutes in antiquity and hours thousands of years ago, when it is also uncertain.

final jdUt = julianDay(2027, 6, 21, hour: 12);  // calendar → Julian day (UT)
final jdTT = julianDayTT(jdUt);                      // adds ΔT
final back = calendarDateTime(julianDayUT(jdTT));    // and back to a date

Dates before 15 October 1582 are taken in the Julian calendar and later ones in the Gregorian, unless you pass calendar:. The ΔT model can be replaced with your own value through deltaTSeconds:.

Bodies

Bodies are identified by NAIF codes, as in the JPL files. The class Naif names them:

BodyCode
Sun, Moon, EarthNaif.sun, Naif.moon, Naif.earth
Mercury, VenusNaif.mercury, Naif.venus
Mars … Pluto (system barycentres)Naif.marsBarycenter … Naif.plutoBarycenter
Chiron, asteroids2 000 000 + number (Chiron 2002060)

Outer planets are the barycentres of their systems with moons – the convention of almanacs and astrology software. Chiron and asteroids need an extra SPK file from JPL Horizons.

Coordinates and units

Ephemeris files

openSpkFile reads a file from disk on demand, without loading it into memory; SpkFile.fromBytes works with bytes you already have (e.g. a Flutter asset). Several files can be combined:

final ephemeris = SpkEphemeris([
  openSpkFile('data/jpl/de441.bsp'),   // −13200 … +17191
  openSpkFile('data/jpl/de442.bsp'),   // 1550–2650, takes precedence
]);

All calculations accept any Ephemeris, so other data sources can be plugged in. Next: the guides.