Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/sun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { EclipticCoordinate, EquatorialCoordinate, GeographicCoordinate } f

import { AU_IN_METERS, c } from './constants'

import { convertEclipticToEquatorial, convertEquatorialToHorizontal } from './coordinates'
import { convertEclipticToEquatorial } from './coordinates'

import { B, L, R, getEccentricityOfOrbit } from './earth'

Expand All @@ -22,7 +22,7 @@ import { getLocalHorizon } from './observer'

import { getFOrbitalParameter } from './orbit'

import { convertDegreesToRadians as radians } from './utilities'
import { convertRadiansToDegrees as degrees, convertDegreesToRadians as radians } from './utilities'

import { calculateB, calculateL, calculateR } from './vsop87'

Expand Down Expand Up @@ -472,10 +472,23 @@ export const SOLAR_STANDARD_ALTITUDE_OF_RISE_AND_SET = -0.8333 as const
/*****************************************************************************************************************/

// The geometric altitude of the centre of the Sun (in degrees), e.g., the altitude the standard
// almanac convention of rise and set is stated against, which is not corrected for refraction:
// almanac convention of rise and set is stated against, which is not corrected for refraction.
//
// N.B. The altitude is resolved from the apparent hour angle of the Sun, e.g., taken against
// the apparent sidereal time, as the right ascension of the Sun is an apparent place that
// carries the nutation in longitude, which the mean sidereal time would leave unbalanced by
// the equation of the equinoxes:
const getSolarGeometricAltitude = (datetime: Date, observer: GeographicCoordinate): number => {
return convertEquatorialToHorizontal(datetime, observer, getSolarEquatorialCoordinate(datetime))
.alt
const { ra, dec } = getSolarEquatorialCoordinate(datetime)

// Get the apparent hour angle of the Sun (in radians):
const ha = radians(getApparentHourAngle(datetime, observer.longitude, ra))

const φ = radians(observer.latitude)

const δ = radians(dec)

return degrees(Math.asin(Math.sin(φ) * Math.sin(δ) + Math.cos(φ) * Math.cos(δ) * Math.cos(ha)))
}

/*****************************************************************************************************************/
Expand Down
6 changes: 4 additions & 2 deletions tests/conformance/spa.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ const APPARENT_MERIDIAN_TRANSIT_TOLERANCE = 0.1

// The sunrise and sunset of the standard almanac convention, e.g., the crossings of the
// geometric altitude of the centre of the Sun through the standard altitude of -0.8333° (in
// seconds). The residual carries the equation of the equinoxes, as the meridian transit does:
const STANDARD_RISE_AND_SET_TOLERANCE = 2
// seconds). The altitude is resolved from the apparent hour angle, and so the equation of the
// equinoxes is balanced, and the residual is that of the bisection resolution and of the
// apparent place of the Sun against the full series of the SPA:
const STANDARD_RISE_AND_SET_TOLERANCE = 0.1

/*****************************************************************************************************************/

Expand Down
6 changes: 3 additions & 3 deletions tests/sun.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ describe('getSunrise', () => {

it('should return the sunrise of the standard almanac convention for the given date', () => {
const sunrise = getSunrise(datetime, { latitude: 49.914425, longitude: -6.315165 })
expect(sunrise?.toISOString()).toBe('2021-05-14T04:40:52.430Z')
expect(sunrise?.toISOString()).toBe('2021-05-14T04:40:53.501Z')
})

it('should return an earlier sunrise for an observer at an elevation', () => {
Expand All @@ -343,7 +343,7 @@ describe('getSunrise', () => {
elevation: 2000
})

expect(sunrise?.toISOString()).toBe('2021-05-14T04:31:18.119Z')
expect(sunrise?.toISOString()).toBe('2021-05-14T04:31:19.190Z')
})

it('should return null for an observer in perpetual daylight', () => {
Expand Down Expand Up @@ -371,7 +371,7 @@ describe('getSunset', () => {

it('should return the sunset of the standard almanac convention for the given date', () => {
const sunset = getSunset(datetime, { latitude: 49.914425, longitude: -6.315165 })
expect(sunset?.toISOString()).toBe('2021-05-14T20:03:12.954Z')
expect(sunset?.toISOString()).toBe('2021-05-14T20:03:14.025Z')
})

it('should return null for an observer in perpetual daylight', () => {
Expand Down