ephemeris answers where everything is, for any observer and
any date. It carries sidereal time — time kept by the turning of the
stars rather than the sun. It carries the transform from a sky position to
an altitude and a compass azimuth. It carries the sun and the moon as sky
positions, the moon's phase, age, distance, rise and set, and the five
naked-eye planets from Keplerian elements — the handful of numbers
that describe an orbit. It is the machine geo's
out-of-scope promised — geo kept the sun as experienced at a place; this is
the rest of the sky.
Pure throughout, and no clock anywhere near it: every
word takes a Julian day number and a UTC hour as arguments.
julian's JulDayNumber makes one from
a calendar date (geo's GeoJulian is the same word by another
name), and clock's ClockDate()
supplies “today” at the caller's edge.
An ephemeris — a table of where the sky's bodies will be, date by date — is one of the oldest products of organised computation. The Nautical Almanac, established by Astronomer Royal Nevil Maskelyne in 1767, printed the moon's position precisely so that a navigator could read longitude off the sky. It was produced by a cottage industry of freelance human computers who worked at home by post, in pairs whose answers were checked against each other — distributed, redundant computation, two centuries before the words meant machinery. The tables in that tradition were built from series: sums of periodic terms, each term a cycle the moon or a planet is known to follow, truncated at whatever accuracy the page could justify. That is still the shape of the thing. The definitive modern ephemerides are numerically integrated at JPL. But the compact printed forms — the Almanac's low-precision moon, Keplerian elements fitted over a few centuries — are exactly what this machine carries: the almanac tradition with the page removed, each word honest about the accuracy at which its series was cut.
“What's that bright thing over the rooftops” is a question a
latitude, a longitude and a clock reading can answer, and this machine is
the arithmetic between them. EphSun, EphMoon and
EphPlanet answer where a body is on the celestial
sphere; EphAltAz turns that into where it stands in
your sky — an altitude and a bearing you can point a compass at.
The boundary with geo is stated so it cannot drift. geo
answers the sun as experienced at a place: rise, set, noon, day length,
twilight — and stays the canonical machine for all of those. ephemeris
answers the sky as observed from a place. EphSun exists here
because the moon's phase and every planet's elongation — its angular
distance from the sun — are measured from it. The two machines' suns are
two small models of one star, and the test suite asserts they agree rather
than trusting it.
A sky position is EphSky and not
GeoPt, though both live on a sphere. Declination is
latitude-shaped and right ascension longitude-shaped. But geo folds
longitudes into (−180, 180], which would mangle a right ascension,
and a word accepting either record would someday be handed the wrong one
silently. Two meanings, two types.
Accuracy is a number, per body. The sun is good to about a minute of arc. The moon is the Astronomical Almanac's low-precision series — about a third of a degree, geocentric, meaning measured from the Earth's centre. The observer's parallax is deliberately unmodelled; its average is folded into the rise altitude instead, which is the almanac's own convention for rise times. The planets are the JPL approximate Keplerian elements, valid 1800..2050 and well under a degree there. Ample for pointing and planning; an observatory wants a different class of library, and would be right to.
Option is the design for rise and set,
exactly as in geo: a circumpolar moon has no rise because it never set. The
scan is the UTC day, 0..24. Roughly once a month a calendar day genuinely
has no moonrise, because the moon rises about fifty minutes later each day
and one rise falls the far side of midnight. That day answers
None honestly rather than borrowing tomorrow's.
Tonight's moon, from anywhere — the date arrives through julian or clock, and everything after that is arithmetic:
Include "julian.shoddy"
Include "geo.shoddy"
Include "ephemeris.shoddy"
Def Main()
Let here = GeoAt(53.72, -1.86)
Let jd = JulDayNumber(JulOf(2026, 8, 12)) ' or ClockDate() via clock
Let moon = EphMoon(jd, 21) ' 21:00 UTC
Let seen = EphAltAz(here, moon, jd, 21)
Print(EphAlt(seen)) ' degrees above the horizon
Print(EphAzim(seen)) ' compass bearing to face
Print(EphMoonPhase(jd, 21)) ' 0 new .. 1 full
Select Case EphMoonRise(here, jd)
Case Some(h)
Print(h) ' UTC hours of moonrise
Case None
Print("no moonrise today") ' an ordinary answer
A planet is the same shape — name it, place it, look at it:
Let mars = EphPlanet(EphMars(), jd, 21)
Print(EphSeparation(mars, EphSun(jd, 21))) ' its elongation from the sun
Print(EphAlt(EphAltAz(here, mars, jd, 21))) ' is it even up?
Things worth remembering:
EphMoonDistance answers metres, as everything in geo does;
eng converts at the edge.EphMoonAge — days since
new, 0..29.53 — is what tells waxing from waning.EphMercury() through EphSaturn() — and the
numbering keeps the Earth's seat: Mars is 4. Asking for planet 3 aborts
with the truth: it is where you are standing, and geo answers for it.Time and frames, the bodies, the observer
| Word | Description |
|---|---|
| Type EphSky | A position on the celestial sphere:
EphRa 0..360 and EphDec −90..90, both
degrees, equinox of date. |
| Type EphView | What an observer sees: EphAlt
above the horizon and EphAzim as a compass bearing, both
degrees. |
| EphSidereal(jd, hours) | Greenwich mean sidereal time at that UTC hour, degrees 0..360 — the one formula that turns a clock time into a direction in the sky. Add an east longitude for the local form. |
| EphAltAz(p, sky, jd, hours) | A sky position as seen from a
GeoPt at an instant, as an EphView. The azimuth
convention is geo's bearing convention, so you can point a compass at
it. |
| EphSeparation(a, b) | The angle between two sky positions, degrees — by haversine, so a moon two degrees from the sun keeps its digits. |
| Word | Description |
|---|---|
| EphSun(jd, hours) | The sun as a sky position. For rise and set at a place, geo remains the machine; this word is for the sky, and it is what phase and elongation are measured from. |
| EphMoon(jd, hours) | The moon as a sky position, geocentric, to about a third of a degree. |
| EphMoonDistance(jd, hours) | The distance to the moon in metres, from its parallax. |
| EphMoonPhase(jd, hours) | The illuminated fraction, 0 at new through 1 at full — from the full angular separation of sun and moon, which is what makes it honest during an eclipse. |
| EphMoonAge(jd, hours) | Days since new moon, 0 up to a synodic month of 29.53. |
| EphMoonAltitude() | The altitude of the moon's centre at the
moment we call moonrise, +0.125° — the almanac's convention, folding
average parallax against refraction and semi-diameter. A word so it can be
seen and substituted, exactly as GeoSunAltitude is. |
| EphMoonRise(p, jd) | UTC hours of moonrise on that day, or
None — a day with no moonrise is roughly monthly and a
circumpolar moon near a pole has none for weeks. Walked hourly and
bisected, because unlike the sun the moon has no closed form. |
| EphMoonSet(p, jd) | Moonset, on the same terms. |
| Word | Description |
|---|---|
| EphMercury() … EphSaturn() | The five choosers, as words rather than numbers to remember. Mercury 1, Venus 2, Mars 4, Jupiter 5, Saturn 6 — slot 3 is the Earth-Moon barycentre, which the geocentric subtraction uses and a caller cannot ask for. |
| EphPlanet(which, jd, hours) | A planet as a geocentric sky position, from the JPL approximate Keplerian elements: Kepler's equation by Newton, the standard rotation through perihelion, inclination and node, the Earth subtracted, and one frame change into right ascension and declination. Light-time and aberration are below the stated accuracy and deliberately absent. |
No machine and no mill includes it yet — the sky is already at the reckoner's prompt through its seed, and a mill that puts it to work will appear here.
| Machine | Why | |
|---|---|---|
| geo | The
observer is a GeoPt, read through its radian accessors, and
the azimuth answer goes through GeoWrapBrg — one compass
convention for the whole tree. | |
| math | Rad,
Deg, Clamp and Hypot, exactly as geo
uses them. |