Skip to content

Sun

This example computes solar event times (sunrise, sunset, twilights, golden hour) for a ground location, then queries the Sun's ECI position and its topocentric look angles. Use these APIs when scheduling optical observation windows or modeling lighting conditions for a site.

ts
import { Degrees, GroundStation, Kilometers, Meters, Sun } from 'ootk';

Run it

bash
npm run build
npx tsx ./examples/sun.ts

Observer setup

Ground locations are represented by GroundStation, which takes latitude and longitude in degrees and altitude in kilometers. A fixed date keeps the output reproducible.

ts
// Fixed date so the output is reproducible
const date = new Date('2024-01-28T12:00:00.000Z');

// Ground observer near Cape Cod, Massachusetts
const lat = 41 as Degrees;
const lon = -71 as Degrees;
const alt = 0 as Meters;

const station = new GroundStation({
  name: 'Cape Cod',
  lat,
  lon,
  alt: 0 as Kilometers,
});

console.log(`Observer: ${station.name} (${lat} deg N, ${Math.abs(lon)} deg W)`);
console.log(`Date: ${date.toISOString()}`);

Sun event times

Sun.getTimes returns a SunTime object containing every solar event for the day: rise and set, civil/nautical/astronomical dawn and dusk, golden and blue hours, solar noon, and nadir. It takes latitude and longitude in degrees and altitude in meters; the final isUtc flag anchors the calculation to noon UTC instead of local noon.

ts
console.log('\n=== Sun Event Times ===\n');

// Sun.getTimes returns every solar event for the day: rise/set, twilights,
// golden hour, blue hour, solar noon, and nadir. Times are Date objects.
const times = Sun.getTimes(date, lat, lon, alt, true);

console.log(`Astronomical dawn: ${times.astronomicalDawn.toISOString()}`);
console.log(`Nautical dawn:     ${times.nauticalDawn.toISOString()}`);
console.log(`Civil dawn:        ${times.civilDawn.toISOString()}`);
console.log(`Sunrise:           ${times.sunriseStart.toISOString()}`);
console.log(`Solar noon:        ${times.solarNoon.toISOString()}`);
console.log(`Sunset:            ${times.sunsetEnd.toISOString()}`);
console.log(`Civil dusk:        ${times.civilDusk.toISOString()}`);
console.log(`Nautical dusk:     ${times.nauticalDusk.toISOString()}`);
console.log(`Astronomical dusk: ${times.astronomicalDusk.toISOString()}`);
console.log(`Golden hour (PM):  ${times.goldenHourDuskStart.toISOString()}`);

Sunrise and sunset via astronomy-engine

Sun.getSunriseSunset runs a higher-precision horizon-crossing search using astronomy-engine, scanning forward one day from the given date. Either value is null when the Sun never crosses the horizon (polar day or night). Pass 0 as Degrees for the elevation argument; negative values are rejected by the underlying search.

ts
console.log('\n=== Sunrise/Sunset via astronomy-engine ===\n');

// getSunriseSunset uses the higher-precision astronomy-engine search.
// The search runs forward from the given date, so start at midnight UTC.
// It returns null when the Sun never crosses the horizon (polar day/night).
const midnight = new Date('2024-01-28T00:00:00.000Z');
const { sunrise, sunset } = Sun.getSunriseSunset(station, midnight, 0 as Degrees);

console.log(`Sunrise: ${sunrise ? sunrise.toISOString() : 'none'}`);
console.log(`Sunset:  ${sunset ? sunset.toISOString() : 'none'}`);

Sun position

Sun.eci returns the Sun's position as a Vector3D<Kilometers> in Earth-centered inertial coordinates, and Sun.getDistanceFromEarth gives the geocentric distance directly.

ts
console.log('\n=== Sun Position (ECI) ===\n');

// Sun.eci returns the Sun's position in Earth-centered inertial coordinates
const sunEci = Sun.eci(date);

console.log(`X: ${sunEci.x.toExponential(4)} km`);
console.log(`Y: ${sunEci.y.toExponential(4)} km`);
console.log(`Z: ${sunEci.z.toExponential(4)} km`);

const distance = Sun.getDistanceFromEarth(date);

console.log(`\nDistance from Earth: ${distance.toExponential(4)} km`);
console.log(`                     ${(distance / 149597870.7).toFixed(4)} AU`);

Azimuth and elevation

Sun.getAzEl computes topocentric look angles for a ground observer, applying atmospheric refraction by default. getRightAscension and getDeclination return geocentric equatorial coordinates in radians.

ts
console.log('\n=== Sun Azimuth/Elevation for Observer ===\n');

// getAzEl computes the topocentric look angles, with atmospheric refraction
// applied by default
const azEl = Sun.getAzEl(station, date);

console.log(`Azimuth:   ${azEl.az.toFixed(4)} deg`);
console.log(`Elevation: ${azEl.el.toFixed(4)} deg`);

const ra = Sun.getRightAscension(date);
const dec = Sun.getDeclination(date);

console.log(`\nRight Ascension: ${(ra * (12 / Math.PI)).toFixed(4)} hours`);
console.log(`Declination:     ${(dec * (180 / Math.PI)).toFixed(4)} deg`);

Output

txt
Observer: Cape Cod (41 deg N, 71 deg W)
Date: 2024-01-28T12:00:00.000Z

=== Sun Event Times ===

Astronomical dawn: 2024-01-28T10:25:00.217Z
Nautical dawn:     2024-01-28T10:57:27.460Z
Civil dawn:        2024-01-28T11:30:38.150Z
Sunrise:           2024-01-28T12:00:03.896Z
Solar noon:        2024-01-28T16:58:02.446Z
Sunset:            2024-01-28T21:56:00.996Z
Civil dusk:        2024-01-28T22:25:26.742Z
Nautical dusk:     2024-01-28T22:58:37.431Z
Astronomical dusk: 2024-01-28T23:31:04.675Z
Golden hour (PM):  2024-01-28T21:15:16.619Z

=== Sunrise/Sunset via astronomy-engine ===

Sunrise: 2024-01-28T11:58:37.250Z
Sunset:  2024-01-28T21:55:31.421Z

=== Sun Position (ECI) ===

X: 9.0107e+7 km
Y: -1.0693e+8 km
Z: -4.6354e+7 km

Distance from Earth: 1.4732e+8 km
                     0.9848 AU

=== Sun Azimuth/Elevation for Observer ===

Azimuth:   113.9559 deg
Elevation: -0.0210 deg

Right Ascension: 20.6746 hours
Declination:     -18.3407 deg

Released under the AGPL-3.0 License.