Sun

Meeus, Astronomical Algorithms · checked against USNO

Preview

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

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

What it is

Sunrise and sunset are when the top of the sun touches the horizon. The air bends its light, so the sun’s centre is then 0.833° below it. Twilight is the light after sunset and before sunrise, in three steps by how far the sun is below the horizon. Soldiers and sailors plan around them: nautical twilight is when the horizon is still visible.

Bands below the horizon: civil twilight to 6 degrees, nautical to 12, astronomical to 18, then night

Operations

OperationGives
events Rise, set, transit and twilight in a windowIn: latitudeInDegrees, longitudeInDegrees, startUtc, windowInHours
Out: riseUtc, setUtc, transitUtc, civilDawnUtc, civilDuskUtc, nauticalDawnUtc, nauticalDuskUtc, astronomicalDawnUtc, astronomicalDuskUtc, isAlwaysUp, isAlwaysDown
position The sun's azimuth and altitude from a placeIn: latitudeInDegrees, longitudeInDegrees, instantUtc
Out: azimuthInDegrees, altitudeInDegrees

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 sun reaches the horizon; its centre at −0.833°. null if it doesn't happen in the window
setUtcAs rise, going down
transitUtcHighest in the sky
civilDawnUtcCentre at −6°, rising
civilDuskUtcCentre at −6°, setting
nauticalDawnUtcCentre at −12°, rising
nauticalDuskUtcCentre at −12°, setting
astronomicalDawnUtcCentre at −18°, rising
astronomicalDuskUtcCentre at −18°, setting
azimuthInDegrees0 to 360, clockwise from north
altitudeInDegrees−90 to 90, up from the horizon

Edge cases

CaseWhat's right
Alert, Nunavut, in JuneriseUtc and setUtc null, isAlwaysUp true
McMurdo Station in JuneriseUtc and setUtc null, isAlwaysDown true
Twilight that never endsIn high-latitude summer, nauticalDuskUtc and nauticalDawnUtc can be null
A window crossing midnight UTCEvents on both sides

For agents

Follow Meeus, Astronomical Algorithms, chapters 25 and 15. Find events in the window from startUtc for windowInHours, never in a local calendar day. Use −0.833° for rise and set, and −6°, −12° and −18° for twilight. When the sun doesn’t cross an altitude in the window, return null for that time, and set isAlwaysUp or isAlwaysDown. 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± 60 s
setUtc± 60 s
transitUtc± 60 s
civilDawnUtc± 60 s
civilDuskUtc± 60 s
nauticalDawnUtc± 60 s
nauticalDuskUtc± 60 s
astronomicalDawnUtc± 60 s
astronomicalDuskUtc± 60 s
azimuthInDegrees± 0.01
altitudeInDegrees± 0.01

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-01T01:23:00Z"
setUtc "2026-01-01T12:34:00Z"
nauticalDawnUtc "2026-01-01T00:12:00Z"
placeholder-2events · edge, polar latitudeInDegrees 82.5
longitudeInDegrees -62.3
startUtc "2026-06-21T00:00:00Z"
windowInHours 24
riseUtc null
setUtc null
isAlwaysUp true
placeholder-3position · reference latitudeInDegrees 11.11
longitudeInDegrees 22.22
instantUtc "2026-01-01T00:00:00Z"
azimuthInDegrees 123.45
altitudeInDegrees 12.34

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