sun.js gains analemma(date, days): where the Sun is overhead at the same UTC time on each coming day, the figure-8 the globe will draw. tools/globe/check.mjs checks the pure functions against almanac values with Node's own test runner (dev only, nothing installed): the 2026 June solstice's declination, the March equinox, perihelion's distance, Turin's longest day, the season in October, and the analemma spanning the tropics and the equation of time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
46 lines
2.2 KiB
JavaScript
46 lines
2.2 KiB
JavaScript
// Checks of the globe's pure functions against almanac values, dev only (Node's own test runner, nothing installed):
|
|
// node --test tools/globe/check.mjs
|
|
// sun.js is the Astronomical Almanac's low-precision formulas, good to about 0.01° between 1950 and 2050.
|
|
import { test } from "node:test"
|
|
import assert from "node:assert/strict"
|
|
import { analemma, seasonsOf, sunAt, sunAtPlace } from "../../wwwroot/js/sun.js"
|
|
|
|
const near = (actual, expected, tolerance, what) =>
|
|
assert.ok(Math.abs(actual - expected) <= tolerance, `${what}: ${actual} is not within ${tolerance} of ${expected}`)
|
|
|
|
test("the June solstice of 2026 puts the Sun over the Tropic of Cancer", () => {
|
|
near(sunAt(new Date("2026-06-21T08:24:00Z")).lat, 23.435, 0.01, "declination")
|
|
})
|
|
|
|
test("the March equinox of 2026 puts the Sun over the equator", () => {
|
|
near(sunAt(new Date("2026-03-20T14:46:00Z")).lat, 0, 0.02, "declination")
|
|
})
|
|
|
|
test("perihelion on 2026-01-03 is the year's nearest Sun", () => {
|
|
near(sunAt(new Date("2026-01-03T17:15:00Z")).distance, 0.98329, 0.0002, "distance in AU")
|
|
})
|
|
|
|
test("Turin's longest day is about 15 h 38 min", () => {
|
|
near(sunAtPlace(sunAt(new Date("2026-06-21T12:00:00Z")), 45.07, 7.69).dayLength, 15.63, 0.05, "day length in hours")
|
|
})
|
|
|
|
test("early October is autumn in the north, and the December solstice comes next", () => {
|
|
const seasons = seasonsOf(sunAt(new Date("2026-10-06T12:00:00Z")))
|
|
assert.equal(seasons.north, "autumn")
|
|
assert.equal(seasons.south, "spring")
|
|
assert.equal(seasons.nextEvent, "december-solstice")
|
|
})
|
|
|
|
test("the analemma spans the tropics and the equation of time", () => {
|
|
const start = new Date("2026-10-06T12:00:00Z")
|
|
const points = analemma(start)
|
|
assert.equal(points.length, 366)
|
|
assert.equal(points[0].lat, sunAt(start).lat)
|
|
near(Math.max(...points.map(p => p.lat)), 23.44, 0.05, "northernmost")
|
|
near(Math.min(...points.map(p => p.lat)), -23.44, 0.05, "southernmost")
|
|
// at 12:00 UTC the Sun is overhead near the prime meridian, early or late by the equation of time (about ±16 min, ±4°)
|
|
const longitudes = points.map(p => p.lng)
|
|
near(Math.max(...longitudes), 3.7, 0.4, "easternmost")
|
|
near(Math.min(...longitudes), -4.1, 0.4, "westernmost")
|
|
})
|