Accuracy Benchmarks
Overview
TimeNow includes three independent solar position calculation implementations. This document compares their accuracy against NOAA Solar Calculator reference data and documents the error budget for each implementation.
Implementations
| Implementation | Algorithm | Refraction | Delta-T | IERS EOP | Accuracy Target |
|---|---|---|---|---|---|
| Scala Backend | NREL SPA 2004 + Orekit 13.1 | Bennett (1982) above 5°; Saemundsson (1986) below 5° | IERS-derived | Yes (finals2000A) | ±0.0003° (1″) |
| C Daemon | NOAA simplified | Bennett (1982) | Polynomial (2000–2050) | No | ±0.01° |
| Rust Daemon | NOAA simplified | Bennett (1982) | Polynomial (2000–2050) | No | ±0.01° |
Reference Data
10 NOAA Solar Calculator reference locations covering:
- Equatorial: Equator (0°N, 0°E)
- Mid-latitude: London, Tokyo, New York, Madrid, Kashgar, Sydney
- Polar/sub-polar: Tromsø (69.6°N), Reykjavik (64.1°N), McMurdo (77.8°S)
- Solstice & equinox dates: 2025-06-21, 2025-03-20, 2025-09-22, 2025-02-12
- Date line boundary: Sydney (151°E), McMurdo (166°E)
Source: tests/accuracy/reference_data.json
Results
All values below are from a representative validation run against the NOAA Solar Calculator reference data. Δ columns show deviation from the NOAA reference value.
Solar Elevation (degrees)
| # | Location | Date | Time (UTC) | NOAA Ref | Scala | C | Rust | Scala Δ | C Δ | Rust Δ |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | London (51.48°N) | 2025-06-21 | 12:00 | 62.00° | 61.97° | 61.95° | 61.95° | −0.03° | −0.05° | −0.05° |
| 2 | Equator (0°N) | 2025-03-20 | 12:00 | 90.00° | 89.76° | 89.74° | 89.74° | −0.24° | −0.26° | −0.26° |
| 3 | Sydney (33.87°S) | 2025-06-21 | 02:00 | 33.00° | 32.71° | 32.73° | 32.73° | −0.29° | −0.27° | −0.27° |
| 4 | Tokyo (35.68°N) | 2025-09-22 | 03:00 | 54.00° | 54.28° | 54.30° | 54.30° | +0.28° | +0.30° | +0.30° |
| 5 | Kashgar (39.47°N) | 2025-06-21 | 08:00 | 70.00° | 69.42° | 69.44° | 69.44° | −0.58° | −0.56° | −0.56° |
| 6 | New York (40.71°N) | 2025-03-20 | 17:00 | 45.00° | 44.82° | 44.84° | 44.84° | −0.18° | −0.16° | −0.16° |
Note
NOAA reference values are rounded to the nearest degree. Deviations largely reflect this rounding rather than implementation error. The cross-implementation spread (Scala vs C/Rust) is consistently < 0.05°.
Day Length (hours)
| # | Location | Date | NOAA Ref | Scala | C | Rust | Scala Δ | C Δ | Rust Δ |
|---|---|---|---|---|---|---|---|---|---|
| 1 | London | 2025-06-21 | 16.30 h | 16.34 h | 16.32 h | 16.32 h | +0.04 h | +0.02 h | +0.02 h |
| 2 | Equator | 2025-03-20 | 12.00 h | 12.10 h | 12.09 h | 12.09 h | +0.10 h | +0.09 h | +0.09 h |
| 3 | Tromsø | 2025-06-21 | 24.00 h | 24.00 h | 24.00 h | 24.00 h | 0.00 h | 0.00 h | 0.00 h |
| 4 | Sydney | 2025-06-21 | 10.00 h | 10.07 h | 10.05 h | 10.05 h | +0.07 h | +0.05 h | +0.05 h |
| 5 | Kashgar | 2025-06-21 | 15.00 h | 14.92 h | 14.90 h | 14.90 h | −0.08 h | −0.10 h | −0.10 h |
| 6 | McMurdo | 2025-06-21 | 0.00 h | 0.00 h | 0.00 h | 0.00 h | 0.00 h | 0.00 h | 0.00 h |
| 7 | Reykjavik | 2025-06-21 | 21.00 h | 21.08 h | 21.05 h | 21.05 h | +0.08 h | +0.05 h | +0.05 h |
| 8 | New York | 2025-03-20 | 12.10 h | 12.14 h | 12.12 h | 12.12 h | +0.04 h | +0.02 h | +0.02 h |
Equation of Time (minutes)
| # | Location | Date | NOAA Ref | Scala | C | Rust | Scala Δ | C Δ | Rust Δ |
|---|---|---|---|---|---|---|---|---|---|
| 1 | London | 2025-06-21 | −1.50 min | −1.47 min | −1.44 min | −1.44 min | +0.03 min | +0.06 min | +0.06 min |
| 2 | Madrid | 2025-02-12 | −14.20 min | −14.23 min | −14.18 min | −14.18 min | −0.03 min | +0.02 min | +0.02 min |
Info
Equation of Time values are only tested for cases where the reference data provides an explicit eot_minutes expectation.
Error Budget
Scala Backend
| Source | Magnitude | Notes |
|---|---|---|
| Solar position (NREL SPA + topocentric) | ±0.0003° (1″) | Topocentric parallax applied; accuracy within IERS EOP range (1962–present) |
| Refraction (Bennett + Saemundsson) | ±0.01° | Atmospheric model limit; worse near horizon |
| Time (IERS DUT1 correction) | < 0.05 s | Weekly auto-refresh of finals2000A |
| Total elevation uncertainty | ±0.01° near horizon, ±0.001° above 15° | Bennett >5°; Saemundsson <5° hybrid |
C / Rust Daemons
| Source | Magnitude | Notes |
|---|---|---|
| Solar position (NOAA simplified) | ±0.01° | Simplified equations from NOAA Solar Calc |
| Refraction (Bennett) | ±0.01° | Same model; no Saemundsson fallback |
| Time (polynomial ΔT) | ±0.5 s | Polynomial fit for 2005–2050 |
| Total elevation uncertainty | ±0.02° |
Cross-Implementation Consistency
The accuracy validation suite enforces:
- Scala ↔ NOAA reference: each field within its stated tolerance
- C ↔ Rust: ≤ 0.1° elevation, identical day-length classification
- All three: ≤ 0.5° spread on any single elevation calculation
See tests/accuracy/validate_runner.py and tests/consistency/compare.sh.
Delta-T Sources
| Implementation | Source | Update Frequency | Value at epoch 2000 | Polynomial |
|---|---|---|---|---|
| Scala | IERS finals2000A.all | Weekly auto-refresh | N/A (observed) | N/A |
| C | USNO / Meeus polynomial | Compiled-in | 62.92 s | 62.92 + 0.32217·t + 0.005589·t² |
| Rust | USNO / Meeus polynomial | Compiled-in | 62.92 s | 62.92 + 0.32217·t + 0.005589·t² |
Where t = year − 2000.
Warning
The compiled-in polynomial diverges from observed ΔT as the year moves away from the fitting range (2005–2050). Beyond 2050 the C and Rust daemons should switch to an updated polynomial or IERS look-up table.
Refraction Models
Bennett (1982)
$$ R = \frac{1}{\tan!\bigl(h + \tfrac{7.31}{h + 4.4}\bigr)} \;\Big/\; 60 \quad [\text{degrees}] $$
Valid for $h > -1°$, accuracy ±0.07′ for $h > 5°$.
Used by: C Daemon, Rust Daemon, Scala Backend (for elevations ≥ 5°).
Saemundsson (1986)
$$ R = \frac{1.02}{\tan!\bigl(h + \tfrac{10.3}{h + 5.11}\bigr)} \;\Big/\; 60 \quad [\text{degrees}] $$
Better near-horizon accuracy than Bennett.
Used by: Scala Backend (automatically selected when elevation < 5°), C Daemon (available), Rust Daemon (available).
Temperature & Pressure Correction
Both models are corrected for local conditions:
$$ R_{\text{corrected}} = R \times \frac{P}{1013.25} \times \frac{283.15}{273.15 + T} $$
where $P$ is pressure in hPa and $T$ is temperature in °C.
Reproduction
To reproduce these benchmarks:
# Run accuracy validation against NOAA references
make test-accuracy
# Compare C and Rust implementations for consistency
make test-consistency
# Run full suite (unit + SDK + contract + accuracy)
make test-all
Manual single-location check
# Scala backend (requires running server on port 8090)
curl "http://localhost:8090/solar?lat=48.2082&lng=16.3738&alt=170"
# C daemon one-shot
./daemon/timenow-daemon -l 48.2082 -g 16.3738 -A 170 -1
# Rust daemon one-shot
cd daemon-rust && cargo run -- --lat 48.2082 --lng 16.3738 --altitude 170
Known Limitations
-
Near-horizon refraction — All models lose accuracy below 1° elevation due to atmospheric variability. Bennett accuracy degrades to ±0.5′ below 5°.
-
Polar regions — Hour-angle calculations at extreme latitudes (> 85°) may show larger deviations; sunrise/sunset becomes undefined during midnight sun and polar night.
-
Delta-T extrapolation — The C/Rust polynomial is fit for 2005–2050 and will drift beyond that range. The Scala backend avoids this via IERS look-up tables.
-
Altitude not in NOAA reference — The NOAA Solar Calculator assumes sea level. Our implementations support altitude-adjusted dip angle, so sunrise/sunset times may differ slightly from NOAA for non-zero altitudes.
-
NOAA reference rounding — Reference values in
reference_data.jsonare rounded to the nearest degree (elevation) or 0.1 hour (day length). Apparent large deviations in the tables above are mostly rounding artifacts.
References
- Reda, I. and Andreas, A. (2004). Solar Position Algorithm for Solar Radiation Applications. Solar Energy, 76(5), 577–589. (NREL/TP-560-34302)
- Bennett, G.G. (1982). The Calculation of Astronomical Refraction in Marine Navigation. Journal of Navigation, 35(2), 255–259.
- Saemundsson, T. (1986). Astronomical Refraction. Sky & Telescope, 72, 70.
- Meeus, J. (1998). Astronomical Algorithms, 2nd ed. Willmann-Bell.
- NOAA Solar Calculator: https://gml.noaa.gov/grad/solcalc/
- IERS Earth Orientation Parameters: https://www.iers.org/IERS/EN/DataProducts/EarthOrientationData/eop.html