Moon

Meeus, Astronomical Algorithms · checked against USNO

Preview

The test data isn't published yet; the work is in issue #6. The case count, the expiry date and everything under Test data are made up to show how the finished page will look.

Planned · 4 cases · valid until 2027-12-31

What it is

The moon goes around the Earth about every 29.5 days, lit by the sun from a different angle each night. Illumination is the fraction of its face that’s lit, and the phase names where it is in the cycle. It’s close enough that where you stand shifts where you see it, so its rise and set need a correction the sun doesn’t.

Eight moons from new to waning crescent, each with its name and how much of it is lit

Operations

OperationGives
events Rise, set and transit in a windowIn: latitudeInDegrees, longitudeInDegrees, startUtc, windowInHours
Out: riseUtc, setUtc, transitUtc, isAlwaysUp, isAlwaysDown
phase How much is lit, and the phase's name, at an instantIn: instantUtc
Out: illuminationFraction, phaseAngleInDegrees, phaseName
nextPhases The next of each of the four main phases after an instantIn: startUtc
Out: newMoonUtc, firstQuarterUtc, fullMoonUtc, lastQuarterUtc

Fields

FieldMeaning
latitudeInDegrees−90 to 90, WGS84, north positive
longitudeInDegrees−180 to 180, WGS84, east positive
startUtcThe window's start, ISO 8601 in UTC
windowInHoursThe window's length, 24 unless a case says otherwise
isAlwaysUptrue when it's above the horizon for the whole window
isAlwaysDowntrue when it's below the horizon for the whole window
instantUtcAn instant, ISO 8601 in UTC
riseUtcThe top of the moon reaches the horizon, with parallax. null if it doesn't happen in the window
setUtcAs rise, going down
transitUtcHighest in the sky
illuminationFraction0 to 1, the part of the face that's lit
phaseAngleInDegrees0 at full to 180 at new
phaseNamenew, waxingCrescent, firstQuarter, waxingGibbous, full, waningGibbous, lastQuarter or waningCrescent
newMoonUtcThe next new moon
firstQuarterUtcThe next first quarter
fullMoonUtcThe next full moon
lastQuarterUtcThe next last quarter

Edge cases

CaseWhat's right
A day with no moonriseriseUtc null, not the next day’s
Above the Arctic CircleDays when the moon never crosses the horizon: isAlwaysUp or isAlwaysDown
Exactly at a phasephaseName is that phase, not its neighbour

For agents

Follow Meeus, Astronomical Algorithms: chapter 47 for position, 48 for illumination and 49 for the phase dates. Correct for the moon’s parallax and semi-diameter when finding rise and set; its altitude at rise changes with its distance. Find events in the window from startUtc. Pass every case in vectors.json within its tolerance.

Test data

In vectors.json, published 2026-01-01. Earth model: WGS84. How to read it: Test data format.

FieldTolerance
riseUtc± 120 s
setUtc± 120 s
transitUtc± 120 s
newMoonUtc± 120 s
firstQuarterUtc± 120 s
fullMoonUtc± 120 s
lastQuarterUtc± 120 s
illuminationFraction± 0.01
phaseAngleInDegrees± 0.5

Every other field is compared exactly.

CaseInputExpected
placeholder-1events · reference latitudeInDegrees 11.11
longitudeInDegrees 22.22
startUtc "2026-01-01T00:00:00Z"
windowInHours 24
riseUtc "2026-01-01T03:21:00Z"
setUtc "2026-01-01T15:43:00Z"
placeholder-2events · edge latitudeInDegrees 11.11
longitudeInDegrees 22.22
startUtc "2026-01-02T00:00:00Z"
windowInHours 24
riseUtc null
setUtc "2026-01-02T16:30:00Z"
placeholder-3phase · reference instantUtc "2026-01-01T00:00:00Z" illuminationFraction 0.12
phaseName "waxingCrescent"
placeholder-4nextPhases · reference startUtc "2026-01-01T00:00:00Z" firstQuarterUtc "2026-01-02T12:34:00Z"
fullMoonUtc "2026-01-09T12:34:00Z"

Implementations

RepoStatus
gshaw/algorithms-swiftSwift Incomplete

Each is a public repo that runs this page's test data with mise run test. See how implementations work.

Source

MethodAstronomical Algorithms, 2nd edition, 1998Jean Meeus
ReferenceAstronomical Applications APIUS Naval Observatory · Public domain