How Accurate Are Published Sunset Times?
We measured ours against the US Naval Observatory. We also measured everyone else's, and found a bug that has been quietly propagating for thirty years.
Every site that publishes sunset times claims to be accurate. Almost none of them show their working, and as far as we can find, none publishes a comparison against a reference.
So we did that, and the results are more interesting than expected.
What we measured against
The US Naval Observatory is the reference. It is the body that has computed rise and set times for the United States since the nineteenth century, and its published values are what everything else is ultimately checked against.
We took fifteen locations spanning latitude 54.8°S to 78.2°N, on dates covering both solstices, both equinoxes, a daylight-saving changeover and a half-hour time zone, and compared every sunrise, sunset and civil twilight boundary.
| Location | Date | USNO | This site | Difference |
|---|---|---|---|---|
| New York | 2026-08-24 | sunrise 06:15 | 06:15:13 | +13 s |
| New York | 2026-08-24 | sunset 19:41 | 19:40:47 | -13 s |
| London | 2026-08-25 | sunrise 06:02 | 06:01:44 | -16 s |
| London | 2026-08-25 | sunset 20:02 | 20:02:24 | +24 s |
| Sydney | 2026-06-21 | sunrise 07:00 | 07:00:00 | +0 s |
| Sydney | 2026-06-21 | sunset 16:54 | 16:53:47 | -13 s |
| Quito | 2026-03-20 | sunrise 06:18 | 06:17:54 | -6 s |
| Quito | 2026-03-20 | sunset 18:24 | 18:24:34 | +34 s |
| Reykjavik | 2026-06-21 | sunrise 02:55 | 02:55:15 | +15 s |
| Reykjavik | 2026-06-21 | sunset 00:04 | 00:03:56 | -4 s |
| Tromso | 2026-06-21 | midnight sun | midnight sun | match |
| Tromso | 2026-12-21 | polar night | polar night | match |
| Longyearbyen | 2026-12-21 | polar night | polar night | match |
| Longyearbyen | 2026-06-21 | midnight sun | midnight sun | match |
| Singapore | 2026-09-23 | sunrise 06:54 | 06:53:53 | -7 s |
| Singapore | 2026-09-23 | sunset 19:00 | 19:00:32 | +32 s |
| Cape Town | 2026-12-21 | sunrise 05:32 | 05:31:58 | -2 s |
| Cape Town | 2026-12-21 | sunset 19:57 | 19:56:45 | -15 s |
| Anchorage | 2026-01-15 | sunrise 09:56 | 09:56:29 | +29 s |
| Anchorage | 2026-01-15 | sunset 16:22 | 16:22:24 | +24 s |
| Ushuaia | 2026-06-21 | sunrise 09:59 | 09:58:53 | -7 s |
| Ushuaia | 2026-06-21 | sunset 17:11 | 17:11:16 | +16 s |
| Nairobi | 2026-11-05 | sunrise 06:11 | 06:11:20 | +20 s |
| Nairobi | 2026-11-05 | sunset 18:21 | 18:21:11 | +11 s |
| Kathmandu | 2026-04-10 | sunrise 05:45 | 05:44:35 | -25 s |
| Kathmandu | 2026-04-10 | sunset 18:26 | 18:25:57 | -3 s |
USNO publishes to the minute, so up to 30 seconds of each difference above is its own rounding rather than ours. The true error is smaller than the figures shown.
What we found in other implementations
While setting this up, something did not add up.
The reference values named in our own project specification came from sunrise-sunset.org, one of the most widely used sunset sites. For New York on 24 August 2026 it gives sunrise at 6:14:07 and sunset at 7:42:33 pm. USNO gives 6:15 and 19:41. Open-Meteo gives 6:15 and 19:40.
So sunrise-sunset.org is about a minute early on sunrise and a minute and a half late on sunset — but its solar noon and its civil twilight times match USNO exactly, to the second.
That asymmetry is a fingerprint. If a solar position model were simply inaccurate, everything would drift together. Noon and twilight being exact while sunrise and sunset are symmetrically wrong means the model is fine and the threshold for sunrise and sunset is wrong.
Tracing it
PHP's deprecated date_sunrise() function, at its default zenith of 90.8333 degrees, returns 6:14:07 and 7:42:33 pm for the same inputs. Not close to sunrise-sunset.org — identical, to the second.
Both descend from sunriset.c, Paul Schlyter's widely copied C implementation from the 1990s. That code takes an upper_limb flag, and when it is set it subtracts the sun's apparent radius from the altitude threshold:
if (upper_limb) altit -= sradius;
The problem is what it subtracts it from. The standard sunrise altitude of −0.833 degrees is already the upper-limb value: it is 34 arcminutes of atmospheric refraction plus 16 arcminutes of solar semi-diameter, added together. Subtracting the semi-diameter again gives roughly −1.1 degrees, and the sun takes about 86 extra seconds to reach it.
The day comes out about 172 seconds too long, split evenly either side of a correct solar noon. Which is exactly the pattern in the measurements.
This is not a criticism of Schlyter's code, which is clear about what the flag does. It is what happens when a flag with a specific meaning gets enabled by downstream users who assume it is required, on top of a constant that already includes the correction. Thirty years of copying later, it is in a great deal of software.
What actually limits accuracy
Even with the arithmetic right, there is a floor, and it is not in the astronomy.
Refraction is weather. The −0.833 degree figure assumes a standard atmosphere: 1013 hPa, 10°C, an ordinary temperature profile. Real refraction near the horizon varies with pressure, temperature and especially the temperature gradient in the lowest few metres of air. Over cold water with warm air above, the sun can appear minutes after it has geometrically set. Tens of seconds of variation is normal; minutes are possible.
No published table can account for this, because it depends on conditions at your location at that moment. It is the reason we do not chase precision beyond the second: the number would be false precision.
The horizon is rarely at sea level. Published times assume a flat horizon at your altitude. A mountain to the west takes the sun away early; standing on a hill gives you extra. We compute for a sea-level horizon, which is what USNO publishes and what makes our figures comparable to everyone else's — and we show elevation separately on each city page, with the amount it would add if you had a clear horizon. In La Paz at 3,782 m that is about nine minutes.
Coordinates matter more than people expect. A city is not a point. At mid-latitudes, one degree of longitude is four minutes of solar time, and a large city can span a tenth of that. We use the GeoNames coordinate for the city centre and state it on every page.
What we do
- NOAA solar position algorithm, following Meeus, with the full equation of centre and the corrected obliquity rather than a truncated series.
- Sunrise and sunset at −0.833 degrees, applied once.
- Twilight at −6, −12 and −18 degrees, and golden and blue hour at +6 and −4, all as pure altitude thresholds.
- Moon phase instants from Meeus chapter 49, which match USNO to the minute. The low-order lunar model we started with was up to two hours out on quarter instants, enough to put a "next full moon" on the wrong date.
- Polar cases reported as what they are. Where the sun does not set, the page says so and gives the date it will, rather than printing a time that does not exist.
Checking us
Everything above is reproducible. tests/test_sun.php runs the comparison against fixtures fetched from the USNO API, and the fixture file records what USNO returned. If you find a disagreement we have not accounted for, tell us — the city, the date, the value you expected and the source. That is enough to reproduce it.
The honest summary: our times agree with the US Naval Observatory to within about half a minute, most of which is USNO's own rounding. The atmosphere will move the real event by more than that on any given evening, and no published time can fix it.