@sffjunkie/astral
Version:
calculations for the position of the sun and the moon
948 lines (946 loc) • 35 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var luxon_1 = require("luxon");
var index_1 = require("./index");
var error_1 = require("./error");
// Using 32 arc minutes as sun's apparent diameter
var SUN_APPARENT_RADIUS = 32.0 / (60.0 * 2.0);
/** Calculate the Julian Day for the specified date */
function julianDayNumber(date) {
var y = date.year;
var m = date.month;
var d = date.day;
if (m <= 2) {
y -= 1;
m += 12;
}
var a = Math.floor(y / 100.0);
var b = 2 - a + Math.floor(a / 4.0);
var jd = Math.floor(365.25 * (y + 4716)) +
Math.floor(30.6001 * (m + 1)) +
d +
b -
1524.5;
return jd;
}
exports.julianDayNumber = julianDayNumber;
/**
* Convert a Julian Day number to a Julian Century
*
* @param julianday - The Julian Day number to convert
*/
function julianDayNumberToJulianCentury(julianday) {
// """Convert a Julian Day number to a Julian Century"""
return (julianday - 2451545.0) / 36525.0;
}
/**
* Convert a Julian Century number to a Julian Day
*
* @param juliancentury - The Julian Century number to convert
*/
function julianCenturyToJulianDayNumber(juliancentury) {
// """Convert a Julian Century number to a Julian Day"""
return juliancentury * 36525.0 + 2451545.0;
}
/**
* Calculate the geometric mean longitude of the sun */
function geomMeanLongSun(juliancentury) {
var l0 = 280.46646 + juliancentury * (36000.76983 + 0.0003032 * juliancentury);
return ((l0 % 360.0) + 360.0) % 360.0;
}
/**
* Calculate the geometric mean anomaly of the sun */
function geomMeanAnomalySun(juliancentury) {
// """calculate the geometric mean anomaly of the sun"""
return (357.52911 + juliancentury * (35999.05029 - 0.0001537 * juliancentury));
}
/**
* Calculate the eccentricity of Earth's orbit
*/
function eccentricLocationEarthOrbit(juliancentury) {
return (0.016708634 -
juliancentury * (0.000042037 + 0.0000001267 * juliancentury));
}
/**
* Calculate the equation of the center of the sun */
function sunEqOfCenter(juliancentury) {
var m = geomMeanAnomalySun(juliancentury);
var mrad = _toRadians(m);
var sinm = Math.sin(mrad);
var sin2m = Math.sin(mrad + mrad);
var sin3m = Math.sin(mrad + mrad + mrad);
var c = sinm *
(1.914602 - juliancentury * (0.004817 + 0.000014 * juliancentury)) +
sin2m * (0.019993 - 0.000101 * juliancentury) +
sin3m * 0.000289;
return c;
}
/**
* Calculate the sun's true longitude */
function sunTrueLong(juliancentury) {
var l0 = geomMeanLongSun(juliancentury);
var c = sunEqOfCenter(juliancentury);
return l0 + c;
}
/**
* Calculate the sun's true anomaly */
function sunTrueAnomoly(juliancentury) {
var m = geomMeanAnomalySun(juliancentury);
var c = sunEqOfCenter(juliancentury);
return m + c;
}
function sunRadVector(juliancentury) {
var v = sunTrueAnomoly(juliancentury);
var e = eccentricLocationEarthOrbit(juliancentury);
return (1.000001018 * (1 - e * e)) / (1 + e * Math.cos(_toRadians(v)));
}
/**
* Calculate the sun's apparent longitude */
function sunApparentLong(juliancentury) {
var true_long = sunTrueLong(juliancentury);
var omega = 125.04 - 1934.136 * juliancentury;
return true_long - 0.00569 - 0.00478 * Math.sin(_toRadians(omega));
}
function meanObliquityOfEcliptic(juliancentury) {
var seconds = 21.448 -
juliancentury *
(46.815 + juliancentury * (0.00059 - juliancentury * 0.001813));
return 23.0 + (26.0 + seconds / 60.0) / 60.0;
}
function obliquityCorrection(juliancentury) {
var e0 = meanObliquityOfEcliptic(juliancentury);
var omega = 125.04 - 1934.136 * juliancentury;
return e0 + 0.00256 * Math.cos(_toRadians(omega));
}
/**
* Calculate the sun's right ascension */
function sunRtAscension(juliancentury) {
// """calculate the sun's right ascension"""
var oc = obliquityCorrection(juliancentury);
var al = sunApparentLong(juliancentury);
var tananum = Math.cos(_toRadians(oc)) * Math.sin(_toRadians(al));
var tanadenom = Math.cos(_toRadians(al));
return _toDegrees(Math.atan2(tananum, tanadenom));
}
/**
* Calculate the sun's declination */
function sunDeclination(juliancentury) {
// """calculate the sun's declination"""
var e = obliquityCorrection(juliancentury);
var lambd = sunApparentLong(juliancentury);
var sint = Math.sin(_toRadians(e)) * Math.sin(_toRadians(lambd));
return _toDegrees(Math.asin(sint));
}
function var_y(juliancentury) {
var epsilon = obliquityCorrection(juliancentury);
var y = Math.tan(_toRadians(epsilon) / 2.0);
return y * y;
}
function eqOfTime(juliancentury) {
var l0 = geomMeanLongSun(juliancentury);
var e = eccentricLocationEarthOrbit(juliancentury);
var m = geomMeanAnomalySun(juliancentury);
var y = var_y(juliancentury);
var sin2l0 = Math.sin(2.0 * _toRadians(l0));
var sinm = Math.sin(_toRadians(m));
var cos2l0 = Math.cos(2.0 * _toRadians(l0));
var sin4l0 = Math.sin(4.0 * _toRadians(l0));
var sin2m = Math.sin(2.0 * _toRadians(m));
var Etime = y * sin2l0 -
2.0 * e * sinm +
4.0 * e * y * sinm * cos2l0 -
0.5 * y * y * sin4l0 -
1.25 * e * e * sin2m;
return _toDegrees(Etime) * 4.0;
}
/**
* Calculate the hour angle of the sun
* See https://en.wikipedia.org/wiki/Hour_angle#Solar_hour_angle
*
* @param latitude - The latitude of the observer
* @param declination - The declination of the sun
* @param zenith - The zenith angle of the sun
* @param direction - The direction of traversal of the sun
* @throws MathError
*/
function hourAngle(latitude, declination, zenith, direction) {
var latitude_rad = _toRadians(latitude);
var declination_rad = _toRadians(declination);
var zenith_rad = _toRadians(zenith);
var h = (Math.cos(zenith_rad) -
Math.sin(latitude_rad) * Math.sin(declination_rad)) /
(Math.cos(latitude_rad) * Math.cos(declination_rad));
if (isNaN(h)) {
throw new error_1.MathError('Unable to calculate hour_angle');
}
var HA = Math.acos(h);
if (isNaN(HA)) {
throw new error_1.MathError('Unable to calculate hour_angle');
}
else {
if (direction == index_1.SunDirection.SETTING) {
HA = -HA;
}
return HA;
}
}
/**
* Calculate the extra degrees of depression that you can see round the earth
due to the increase in elevation.
* @param elevation - Elevation above the earth in metres
* @returns A number of degrees to add to adjust for the elevation of the observer
*/
function adjustToHorizon(elevation) {
if (elevation <= 0) {
return 0;
}
var r = 6356900; // radius of the earth
var a1 = r;
var h1 = r + elevation;
var theta1 = Math.acos(a1 / h1);
var a2 = r * Math.sin(theta1);
var b2 = r - r * Math.cos(theta1);
var h2 = Math.sqrt(Math.pow(a2, 2) + Math.pow(b2, 2));
var alpha = Math.acos(a2 / h2);
return _toDegrees(alpha);
}
/**
* Calculate the extra degrees of depression needed for the sun to be visible
* over an obscuring feature.
* @param elevation - A tuple of 2 floating point numbers. The first number is
* the horizontal distance to the feature and the second is
* the vertical distance
*/
function adjustToObscuringFeature(elevation) {
if (elevation[0] == 0.0) {
return 0.0;
}
var sign = elevation[0] < 0.0 ? -1 : 1;
return (sign *
_toDegrees(Math.acos(Math.abs(elevation[0]) /
Math.sqrt(Math.pow(elevation[0], 2) + Math.pow(elevation[1], 2)))));
}
/**
* Calculate the degrees of refraction of the sun due to the sun's elevation.
* @param zenith - The zenith angle to the sun
*/
function refractionAtZenith(zenith) {
var elevation = 90 - zenith;
if (elevation >= 85.0) {
return 0;
}
var refractionCorrection = 0.0;
var te = Math.tan(_toRadians(elevation));
if (elevation > 5.0) {
refractionCorrection =
58.1 / te -
0.07 / (te * te * te) +
0.000086 / (te * te * te * te * te);
}
else if (elevation > -0.575) {
var step1 = -12.79 + elevation * 0.711;
var step2 = 103.4 + elevation * step1;
var step3 = -518.2 + elevation * step2;
refractionCorrection = 1735.0 + elevation * step3;
}
else {
refractionCorrection = -20.774 / te;
}
refractionCorrection = refractionCorrection / 3600.0;
return refractionCorrection;
}
/**
* Calculate the time in the UTC timezone when the sun transits the specificed zenith
* @param observer - An observer viewing the sun at a specific, latitude, longitude and elevation
* @param date - The date to calculate for
* @param zenith - The zenith angle for which to calculate the transit time
* @param direction - The direction that the sun is traversing
* @returns The time when the sun transits the specificed zenith
*/
function timeOfTransit(observer, date, zenith, direction) {
var latitude;
if (observer.latitude > 89.8) {
latitude = 89.8;
}
else if (observer.latitude < -89.8) {
latitude = -89.8;
}
else {
latitude = observer.latitude;
}
var adjustment_for_elevation = 0.0;
if (typeof observer.elevation == 'number' && observer.elevation > 0.0) {
adjustment_for_elevation = adjustToHorizon(observer.elevation);
}
else if (observer.elevation instanceof Array) {
adjustment_for_elevation = adjustToObscuringFeature(observer.elevation);
}
var adjustment_for_refraction = refractionAtZenith(zenith + adjustment_for_elevation);
var jd = julianDayNumber(date);
var t = julianDayNumberToJulianCentury(jd);
var solarDec = sunDeclination(t);
var hourangle = hourAngle(latitude, solarDec, zenith + adjustment_for_elevation - adjustment_for_refraction, direction);
var delta = -observer.longitude - _toDegrees(hourangle);
var timeDiff = 4.0 * delta;
var timeUTC = 720.0 + timeDiff - eqOfTime(t);
t = julianDayNumberToJulianCentury(julianCenturyToJulianDayNumber(t) + timeUTC / 1440.0);
solarDec = sunDeclination(t);
hourangle = hourAngle(latitude, solarDec, zenith + adjustment_for_elevation + adjustment_for_refraction, direction);
delta = -observer.longitude - _toDegrees(hourangle);
timeDiff = 4.0 * delta;
timeUTC = 720 + timeDiff - eqOfTime(t);
// let td = minutes_to_timedelta(timeUTC);
var dt = luxon_1.DateTime.utc(date.year, date.month, date.day).plus({
minutes: timeUTC
});
// dt = pytz.utc.localize(dt);
return dt;
}
exports.timeOfTransit = timeOfTransit;
/**
* Calculates the time when the sun is at the specified elevation on the specified date.
*
* Note:
* This method uses positive elevations for those above the horizon.
* Elevations greater than 90 degrees are converted to a setting sun
* i.e. an elevation of 110 will calculate the time for a setting sun at 70 degrees.
*
* @param observer - Observer to calculate for
* @param elevation - Elevation of the sun in degrees above the horizon to calculate for.
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param direction - Determines whether the calculated time is for the sun rising or setting.
* Use `SunDirection.RISING` or `SunDirection.SETTING`. Default is rising.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which the sun is at the specified elevation.
*/
function timeAtElevation(observer, elevation, date, direction, tzinfo) {
if (direction === void 0) { direction = index_1.SunDirection.RISING; }
if (tzinfo === void 0) { tzinfo = 'utc'; }
if (elevation > 90.0) {
elevation = 180.0 - elevation;
direction = index_1.SunDirection.SETTING;
}
if (!date) {
date = index_1.today(tzinfo);
}
var zenith = 90 - elevation;
try {
var tot = timeOfTransit(observer, date, zenith, direction);
if (tzinfo != null) {
tot = tot.setZone(tzinfo);
}
return tot;
}
catch (error) {
if (error instanceof error_1.MathError) {
throw new error_1.ValueError("Sun never reaches an elevation of " + elevation + " degrees at this location.");
}
else {
throw error;
}
}
}
exports.timeAtElevation = timeAtElevation;
/**
* Calculate solar noon time when the sun is at its highest point.
* @param observer - An observer viewing the sun at a specific, latitude, longitude and elevation
* @param date - Date to calculate for. Default is today for the specified tzinfo.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which noon occurs.
*/
function noon(observer, date, tzinfo) {
if (date === void 0) { date = null; }
if (tzinfo === void 0) { tzinfo = 'utc'; }
if (!date) {
date = index_1.today(tzinfo);
}
var jc = julianDayNumberToJulianCentury(julianDayNumber(date));
var eqtime = eqOfTime(jc);
var timeUTC = (720.0 - 4 * observer.longitude - eqtime) / 60.0;
var hour = Math.floor(timeUTC);
var minute = Math.floor((timeUTC - hour) * 60);
var second = Math.floor(((timeUTC - hour) * 60 - minute) * 60);
if (second > 59) {
second -= 60;
minute += 1;
}
else if (second < 0) {
second += 60;
minute -= 1;
}
if (minute > 59) {
minute -= 60;
hour += 1;
}
else if (minute < 0) {
minute += 60;
hour -= 1;
}
if (hour > 23) {
hour -= 24;
date.plus({ days: 1 });
}
else if (hour < 0) {
hour += 24;
date.minus({ days: 1 });
}
var noon = luxon_1.DateTime.utc(date.year, date.month, date.day, hour, minute, second);
if (tzinfo != null) {
noon = noon.setZone(tzinfo);
}
return noon;
}
exports.noon = noon;
/**
* Calculate solar midnight time.
*
* Note:
* This calculates the solar midnight that is closest
* to 00:00:00 of the specified date i.e. it may return a time that is on
* the previous day.
*
* @param observer - An observer viewing the sun at a specific, latitude, longitude and elevation
* @param date - Date to calculate for. Default is today for the specified tzinfo.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which midnight occurs.
*/
function midnight(observer, date, tzinfo) {
if (tzinfo === void 0) { tzinfo = 'utc'; }
if (!date) {
date = index_1.today(tzinfo);
}
var jd = julianDayNumber(date);
var newt = julianDayNumberToJulianCentury(jd + 0.5 + -observer.longitude / 360.0);
var eqtime = eqOfTime(newt);
var timeUTC = -observer.longitude * 4.0 - eqtime;
timeUTC = timeUTC / 60.0;
var hour = Math.floor(timeUTC);
var minute = Math.floor((timeUTC - hour) * 60);
var second = Math.floor(((timeUTC - hour) * 60 - minute) * 60);
if (second > 59) {
second -= 60;
minute += 1;
}
else if (second < 0) {
second += 60;
minute -= 1;
}
if (minute > 59) {
minute -= 60;
hour += 1;
}
else if (minute < 0) {
minute += 60;
hour -= 1;
}
if (hour < 0) {
hour += 24;
date.minus({ days: 1 });
}
var midnight = luxon_1.DateTime.utc(date.year, date.month, date.day, hour, minute, second);
if (tzinfo != null) {
midnight = midnight.setZone(tzinfo);
}
return midnight;
}
exports.midnight = midnight;
function zenithAndAzimuth(observer, dateandtime, with_refraction) {
if (with_refraction === void 0) { with_refraction = true; }
var latitude;
if (observer.latitude > 89.8) {
latitude = 89.8;
}
else if (observer.latitude < -89.8) {
latitude = -89.8;
}
else {
latitude = observer.latitude;
}
var longitude = observer.longitude;
var utc_datetime, zone;
if (dateandtime.zoneName == 'UTC') {
zone = 0.0;
utc_datetime = dateandtime;
}
else {
zone = -dateandtime.offset / 60.0; // type: ignore
utc_datetime = dateandtime.setZone('utc');
}
var timenow = utc_datetime.hour +
utc_datetime.minute / 60.0 +
utc_datetime.second / 3600.0;
var JD = julianDayNumber(dateandtime);
var t = julianDayNumberToJulianCentury(JD + timenow / 24.0);
var solarDec = sunDeclination(t);
var eqtime = eqOfTime(t);
var solarTimeFix = eqtime - 4.0 * -longitude + 60 * zone;
var trueSolarTime = dateandtime.hour * 60.0 +
dateandtime.minute +
dateandtime.second / 60.0 +
solarTimeFix;
// in minutes as a float, fractional part is seconds
while (trueSolarTime > 1440) {
trueSolarTime = trueSolarTime - 1440;
}
var hourangle = trueSolarTime / 4.0 - 180.0;
// Thanks to Louis Schwarzmayr for the next line:
if (hourangle < -180) {
hourangle = hourangle + 360.0;
}
var harad = _toRadians(hourangle);
var csz = Math.sin(_toRadians(latitude)) * Math.sin(_toRadians(solarDec)) +
Math.cos(_toRadians(latitude)) *
Math.cos(_toRadians(solarDec)) *
Math.cos(harad);
if (csz > 1.0) {
csz = 1.0;
}
else if (csz < -1.0) {
csz = -1.0;
}
var azimuth;
var zenith = _toDegrees(Math.acos(csz));
var azDenom = Math.cos(_toRadians(latitude)) * Math.sin(_toRadians(zenith));
if (Math.abs(azDenom) > 0.001) {
var azRad = (Math.sin(_toRadians(latitude)) * Math.cos(_toRadians(zenith)) -
Math.sin(_toRadians(solarDec))) /
azDenom;
if (Math.abs(azRad) > 1.0) {
if (azRad < 0) {
azRad = -1.0;
}
else {
azRad = 1.0;
}
}
azimuth = 180.0 - _toDegrees(Math.acos(azRad));
if (hourangle > 0.0) {
azimuth = -azimuth;
}
}
else {
if (latitude > 0.0) {
azimuth = 180.0;
}
else {
azimuth = 0.0;
}
}
if (azimuth < 0.0) {
azimuth = azimuth + 360.0;
}
if (with_refraction) {
zenith -= refractionAtZenith(zenith);
}
return [zenith, azimuth];
}
/**
* Calculate the azimuth angle of the sun.
*
* @param observer - Observer to calculate the solar azimuth for
* @param dateandtime - The date and time for which to calculate the angle.
* If `dateandtime` is not provided
* then it is assumed to be right [[now]] in the UTC timezone.
* @returns The azimuth angle in degrees clockwise from North.
*/
function azimuth(observer, dateandtime) {
if (!dateandtime) {
dateandtime = index_1.now('utc');
}
return zenithAndAzimuth(observer, dateandtime)[1];
}
exports.azimuth = azimuth;
/**
* Calculate the zenith angle of the sun.
*
* @param observer - Observer to calculate the solar zenith for
* @param dateandtime - The date and time for which to calculate the angle.
* If `dateandtime` is not provided
* then it is assumed to be right [[now]] in the UTC timezone.
* @param with_refraction - If true adjust zenith to take refraction into account
* @returns The zenith angle in degrees.
*/
function zenith(observer, dateandtime, with_refraction) {
if (with_refraction === void 0) { with_refraction = true; }
if (!dateandtime) {
dateandtime = index_1.now('utc');
}
return zenithAndAzimuth(observer, dateandtime, with_refraction)[0];
}
exports.zenith = zenith;
/**
* Calculate the sun's angle of elevation.
*
* @param observer - Observer to calculate the solar elevation for
* @param dateandtime - The date and time for which to calculate the angle.
* If `dateandtime` is not provided then it is assumed to be right
* [[now]] in the UTC timezone.
* @param with_refraction - If true adjust zenith to take refraction into account
* @returns The elevation angle in degrees.
*/
function elevation(observer, dateandtime, with_refraction) {
if (with_refraction === void 0) { with_refraction = true; }
if (!dateandtime) {
dateandtime = index_1.now('utc');
}
return 90.0 - zenith(observer, dateandtime, with_refraction);
}
exports.elevation = elevation;
/**
* Calculate dawn time.
*
* @param observer - Observer to calculate dawn for
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param depression - Number of degrees below the horizon to use to calculate dawn.
* Default is for Civil dawn i.e. 6.0
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which dawn occurs.
* @throws [[ValueError]] if dawn does not occur on the specified date
*/
function dawn(observer, date, depression, tzinfo) {
if (depression === void 0) { depression = index_1.Depression.CIVIL; }
if (tzinfo === void 0) { tzinfo = 'utc'; }
if (!date) {
date = index_1.today(tzinfo);
}
// TODO: Handle enum
var dep = 0.0;
// console.log(typeof depression);
// if (typeof depression == "Depression"){
// dep = depression.value; }
// else {
dep = depression;
// }
try {
return timeOfTransit(observer, date, 90.0 + dep, index_1.SunDirection.RISING).setZone(tzinfo);
}
catch (error) {
if (error instanceof error_1.MathError) {
throw new error_1.ValueError("Sun never reaches " + dep + " degrees below the horizon, at this location.");
}
else {
throw error;
}
}
}
exports.dawn = dawn;
/**
* Calculate sunrise time.
*
* @param observer - Observer to calculate sunrise for
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which sunrise occurs.
* @throws [[ValueError]] if the sun does not reach the horizon
*/
function sunrise(observer, date, tzinfo) {
if (tzinfo === void 0) { tzinfo = 'utc'; }
tzinfo = tzinfo || 'utc';
date = date || index_1.today(tzinfo);
try {
return timeOfTransit(observer, date, 90.0 + SUN_APPARENT_RADIUS, index_1.SunDirection.RISING).setZone(tzinfo);
}
catch (error) {
var msg = void 0;
if (error instanceof error_1.MathError) {
var z = zenith(observer, noon(observer, date));
if (z > 90.0) {
msg =
'Sun is always below the horizon on this day, at this location.';
}
else {
msg =
'Sun is always above the horizon on this day, at this location.';
}
throw new error_1.ValueError(msg);
}
else {
throw error;
}
}
}
exports.sunrise = sunrise;
/**
* Calculate sunset time.
*
* @param observer - Observer to calculate sunset for
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which sunset occurs.
* @throws [[ValueError]] if the sun does not reach the horizon
*/
function sunset(observer, date, tzinfo) {
if (tzinfo === void 0) { tzinfo = 'utc'; }
if (!date) {
date = index_1.today(tzinfo);
}
try {
return timeOfTransit(observer, date, 90.0 + SUN_APPARENT_RADIUS, index_1.SunDirection.SETTING).setZone(tzinfo);
}
catch (error) {
var msg = void 0;
if (error instanceof error_1.MathError) {
var z = zenith(observer, noon(observer, date));
if (z > 90.0) {
msg =
'Sun is always below the horizon on this day, at this location.';
}
else {
msg =
'Sun is always above the horizon on this day, at this location.';
}
throw new error_1.ValueError(msg);
}
else {
throw error;
}
}
}
exports.sunset = sunset;
/**
* Calculate dusk time.
* @param observer - Observer to calculate dusk for
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param depression - Number of degrees below the horizon to use to calculate dusk. Default is for Civil dusk i.e. 6.0
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Date and time at which dusk occurs.
* @throws [[ValueError]] if dusk does not occur on the specified date
*/
function dusk(observer, date, depression, tzinfo) {
if (depression === void 0) { depression = index_1.Depression.CIVIL; }
if (tzinfo === void 0) { tzinfo = 'utc'; }
if (!date) {
date = index_1.today(tzinfo);
}
var dep = 0.0;
// if (typeof depression == "Depression") {
// dep = depression.value;
// }
// else {
dep = depression;
// }
try {
return timeOfTransit(observer, date, 90.0 + dep, index_1.SunDirection.SETTING).setZone(tzinfo);
}
catch (error) {
if (error instanceof error_1.MathError) {
throw new error_1.ValueError("Sun never reaches " + dep + " degrees below the horizon, at this location.");
}
else {
throw error;
}
}
}
exports.dusk = dusk;
/**
* Calculate daylight start and end times.
* @param observer - Observer to calculate daylight for
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns A tuple of the date and time at which daylight starts and ends.
* @throws [[ValueError]] if the sun does not rise or does not set
*/
function daylight(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.tzinfo, tzinfo = _c === void 0 ? 'utc' : _c;
if (!date) {
date = index_1.today(tzinfo);
}
var start = sunrise(observer, date, tzinfo);
var end = sunset(observer, date, tzinfo);
return [start, end];
}
exports.daylight = daylight;
/**
* Calculate night start and end times.
*
* Night is calculated to be between astronomical dusk on the
* date specified and astronomical dawn of the next day.
*
* @param observer - Observer to calculate night for
* @param date - Date to calculate for. Default is today's date for the specified tzinfo.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns A tuple of the date and time at which night starts and ends.
* @throws [[ValueError]] if dawn does not occur on the specified date or dusk on the following day
*/
function night(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.tzinfo, tzinfo = _c === void 0 ? 'utc' : _c;
if (!date) {
date = index_1.today(tzinfo);
}
var start = dusk(observer, date, 6, tzinfo);
var tomorrow = date.plus({ days: 1 });
var end = dawn(observer, tomorrow, 6, tzinfo);
return [start, end];
}
exports.night = night;
/**
* Returns the start and end times of Twilight
*
* This method defines twilight as being between the time
* when the sun is at -6 degrees and sunrise/sunset.
*
* @param observer - Observer to calculate twilight for when the sun is traversing in the specified direction.
* @param date - Date for which to calculate the times. Default is today's date in the timezone `tzinfo`.
* @param direction - Determines whether the time is for the sun rising or setting. Use `SunDirection.RISING` or `SunDirection.SETTING`.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns A tuple of the date and time at which twilight starts and ends.
* @throws [[ValueError]] if the sun does not rise or does not set
*/
function twilight(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.direction, direction = _c === void 0 ? index_1.SunDirection.RISING : _c, _d = _b.tzinfo, tzinfo = _d === void 0 ? 'utc' : _d;
if (!date) {
date = index_1.today(tzinfo);
}
var start = timeOfTransit(observer, date, 90 + 6, direction).setZone(tzinfo);
var end;
if (direction == index_1.SunDirection.RISING) {
end = sunrise(observer, date, tzinfo).setZone(tzinfo);
}
else {
end = sunset(observer, date, tzinfo).setZone(tzinfo);
}
if (direction == index_1.SunDirection.RISING) {
return [start, end];
}
else {
return [end, start];
}
}
exports.twilight = twilight;
/**
* Returns the start and end times of the Golden Hour
* when the sun is traversing in the specified direction.
*
* This method uses the definition from
* [PhotoPills](https://www.photopills.com/articles/understanding-golden-hour-blue-hour-and-twilights)
* i.e. the golden hour is when the sun is between 4 degrees below the horizon
* and 6 degrees above.
*
* @param observer - Observer to calculate the golden hour for
* @param date - Date for which to calculate the times. Default is today's date in the timezone `tzinfo`.
* @param direction - Determines whether the time is for the sun rising or setting. Use `SunDirection.RISING` or `SunDirection.SETTING`.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns A tuple of the date and time at which the Golden Hour starts and ends.
* @throws [[ValueError]] if the sun does not transit the elevations -4 & +6 degrees
*/
function goldenHour(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.direction, direction = _c === void 0 ? index_1.SunDirection.RISING : _c, _d = _b.tzinfo, tzinfo = _d === void 0 ? 'utc' : _d;
if (!date) {
date = index_1.today(tzinfo);
}
var start, end;
try {
start = timeOfTransit(observer, date, 90 + 4, direction).setZone(tzinfo);
end = timeOfTransit(observer, date, 90 - 6, direction).setZone(tzinfo);
}
catch (error) {
if (error instanceof error_1.MathError) {
throw new error_1.ValueError('Sun does not transit the elevations -4 & +6 degrees at this location');
}
}
if (direction == index_1.SunDirection.RISING) {
return [start, end];
}
else {
return [end, start];
}
}
exports.goldenHour = goldenHour;
/**
* Returns the start and end times of the Blue Hour when the sun is traversing in the specified direction.
*
* This method uses the definition from PhotoPills i.e. the
* blue hour is when the sun is between 6 and 4 degrees below the horizon.
* @param observer - Observer to calculate the blue hour for
* @param date - Date for which to calculate the times. Default is today's date in the timezone `tzinfo`.
* @param direction - Determines whether the time is for the sun rising or setting. Use `SunDirection.RISING` or `SunDirection.SETTING`.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns A tuple of the date and time at which the Blue Hour starts and ends.
* @throws [[ValueError]] if the sun does not transit the elevations -4 & -6 degrees
*/
function blueHour(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.direction, direction = _c === void 0 ? index_1.SunDirection.RISING : _c, _d = _b.tzinfo, tzinfo = _d === void 0 ? 'utc' : _d;
if (!date) {
date = index_1.today(tzinfo);
}
var start, end;
try {
start = timeOfTransit(observer, date, 90 + 6, direction).setZone(tzinfo);
end = timeOfTransit(observer, date, 90 + 4, direction).setZone(tzinfo);
}
catch (error) {
if (error instanceof error_1.MathError) {
throw new error_1.ValueError('Sun does not transit the elevations -4 & -6 degrees at this location');
}
}
if (direction == index_1.SunDirection.RISING) {
return [start, end];
}
else {
return [end, start];
}
}
exports.blueHour = blueHour;
/**
* Calculate ruhakaalam times.
* @param observer - Observer to calculate rahukaalam for
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param daytime - If True calculate for the day time else calculate for the night time.
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Tuple containing the start and end times for Rahukaalam.
* @throws [[ValueError]] if the sun does not rise or does not set
*/
function rahukaalam(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.daytime, daytime = _c === void 0 ? true : _c, _d = _b.tzinfo, tzinfo = _d === void 0 ? 'utc' : _d;
if (!date) {
date = index_1.today(tzinfo);
}
var start, end;
if (daytime) {
start = sunrise(observer, date, tzinfo);
end = sunset(observer, date, tzinfo);
}
else {
start = sunset(observer, date, tzinfo);
end = sunrise(observer, date.plus({ days: 1 }), tzinfo);
}
var octant_duration = (end - start) / 8;
// Mo,Sa,Fr,We,Th,Tu,Su
var octant_index = [1, 6, 4, 5, 3, 2, 7];
var weekday = date.weekday;
var octant = octant_index[weekday];
start = start.plus({ second: octant_duration * octant });
end = start.plus({ second: octant_duration });
return [start, end];
}
exports.rahukaalam = rahukaalam;
/**
* Calculate dawn, sunrise, noon, sunset and dusk for the sun.
*
* @param observer - Observer for which to calculate the times of the sun
* @param date - Date to calculate for. Default is today's date in the timezone `tzinfo`.
* @param dawn_dusk_depression - Depression to use to calculate dawn and dusk. Default is for Civil dusk i.e. 6.0
* @param tzinfo - Timezone to return times in. Default is UTC.
* @returns Object with keys `dawn`, `sunrise`, `noon`, `sunset` and `dusk` whose values are the results of the corresponding functions.
* @throws [[ValueError]] if thrown by any of the functions
*/
function sun(observer, _a) {
var _b = _a === void 0 ? {} : _a, date = _b.date, _c = _b.dawn_dusk_depression, dawn_dusk_depression = _c === void 0 ? index_1.Depression.CIVIL : _c, _d = _b.tzinfo, tzinfo = _d === void 0 ? 'utc' : _d;
if (!date) {
date = index_1.today(tzinfo);
}
return {
dawn: dawn(observer, date, dawn_dusk_depression, tzinfo),
sunrise: sunrise(observer, date, tzinfo),
noon: noon(observer, date, tzinfo),
sunset: sunset(observer, date, tzinfo),
dusk: dusk(observer, date, dawn_dusk_depression, tzinfo)
};
}
exports.sun = sun;
function _toRadians(degrees) {
return degrees * (Math.PI / 180.0);
}
function _toDegrees(radians) {
return radians * (180.0 / Math.PI);
}