"use strict"; function round2(x) { return Math.round(x * 100) / 100; } const DEG2RAD = Math.PI / 180; function declination(dayOfYear) { // Cooper's formula: delta = 23.45 * sin( (360/365) * (284 + N) ) degrees const angleDeg = (360 / 365) * (284 + dayOfYear); return 23.45 * Math.sin(angleDeg * DEG2RAD); } module.exports = { slug: "sun-declination-by-day-of-year", title: "Solar declination from day of year", deck_category: "astronomy", description: "Estimates the sun's declination angle for a given day of the year using Cooper's formula.", inputs: [ { name: "day_of_year", type: "integer", unit: "day (1-366)", required: true, description: "Day of the year, January 1 = 1.", min: 1, max: 366 } ], outputs: [ { name: "declination_degrees", unit: "degrees", description: "Solar declination, positive north of the celestial equator." } ], steps: [ "Cooper's formula: declination = 23.45 * sin( (360/365) * (284 + N) ), where N is the day of year and the sine argument is in degrees.", "Convert the argument to radians before taking the sine, since standard math libraries use radians.", "Round the result to 2 decimals.", "This is a smooth approximation to Earth's actual declination curve (accurate to roughly within 1 degree); it does not model leap-year or orbital-eccentricity irregularities." ], constants: [ { name: "max_declination_degrees", value: 23.45, unit: "degrees", source: 0 }, { name: "days_in_year", value: 365, unit: "days", source: 0 }, { name: "phase_offset_days", value: 284, unit: "days", source: 0 } ], sources: [ { kind: "doi", value: "Cooper, P.I. (1969). The absorption of solar radiation in solar stills. Solar Energy, 12(3), 333-346.", title: "The absorption of solar radiation in solar stills", publisher: "Solar Energy (journal)", retrieved_utc: "2026-09-30T19:42:00Z", note: "Source of the widely used Cooper approximation for solar declination." } ], disclaimer: null, questionText(inputs) { return `Using Cooper's formula, what is the sun's declination on day ${inputs.day_of_year} of the year?`; }, run(inputs) { const n = inputs && inputs.day_of_year; if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n > 366) { throw new Error("day_of_year must be an integer between 1 and 366"); } const dec = round2(declination(n)); return { answer: `${dec.toFixed(2)} degrees`, values: { declination_degrees: dec } }; }, examples: [ { name: "worked example", inputs: { day_of_year: 172 }, expected: { answer: "23.45 degrees" }, check: "Day 172 is on or near the June solstice; Earth's axial tilt is a well known fact of 23.45 degrees, and it is the known maximum of the declination curve, so the formula should return a value essentially equal to that maximum, which it does (23.4499 rounds to 23.45)." }, { name: "test vector: December solstice", inputs: { day_of_year: 355 }, expected: { answer: "-23.45 degrees" }, check: "Day 355 is on or near the December solstice, the known minimum of the declination curve at -23.45 degrees (Earth's axial tilt with the opposite sign), which the formula reproduces (-23.4498 rounds to -23.45)." } ] };