@hebcal/noaa 0.8.16 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/package.json +13 -14
- package/dist/index.cjs +0 -1102
- /package/dist/{index.mjs → index.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -116,7 +116,7 @@ export declare class NOAACalculator {
|
|
|
116
116
|
* The zenith of astronomical sunrise and sunset. The sun is 90° from the vertical 0°
|
|
117
117
|
* @private
|
|
118
118
|
*/
|
|
119
|
-
|
|
119
|
+
protected static readonly GEOMETRIC_ZENITH: number;
|
|
120
120
|
/**
|
|
121
121
|
* Default value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle that the
|
|
122
122
|
* center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the Earth
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hebcal/noaa",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "sunrise and sunset via NOAA algorithm with elevation, based on KosherJava",
|
|
5
5
|
"author": "Michael J. Radwin (https://github.com/mjradwin)",
|
|
6
6
|
"contributors": [
|
|
@@ -8,26 +8,25 @@
|
|
|
8
8
|
"Eliyahu Hershfeld (https://github.com/KosherJava)",
|
|
9
9
|
"Benny Powers (https://github.com/bennypowers)"
|
|
10
10
|
],
|
|
11
|
-
"license": "LGPL-
|
|
11
|
+
"license": "LGPL-2.1",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
14
|
"url": "git+https://github.com/hebcal/noaa.git"
|
|
15
15
|
},
|
|
16
|
-
"
|
|
17
|
-
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/hebcal/noaa/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://hebcal.github.io/api/noaa/",
|
|
20
|
+
"module": "dist/index.js",
|
|
18
21
|
"typings": "dist/index.d.ts",
|
|
19
22
|
"type": "module",
|
|
20
23
|
"exports": {
|
|
21
|
-
"
|
|
22
|
-
"require": "./dist/index.cjs",
|
|
23
|
-
"types": "./dist/index.d.ts"
|
|
24
|
+
".": "./dist/index.js"
|
|
24
25
|
},
|
|
25
26
|
"scripts": {
|
|
26
27
|
"docs": "typedoc",
|
|
27
28
|
"test": "ava",
|
|
28
|
-
"build": "
|
|
29
|
-
"build:cjs": "tsc -p ./tsconfig-cjs.json",
|
|
30
|
-
"build:es6": "tsc",
|
|
29
|
+
"build": "tsc",
|
|
31
30
|
"clean": "gts clean",
|
|
32
31
|
"fix": "gts fix",
|
|
33
32
|
"prepare": "npm run build",
|
|
@@ -44,13 +43,13 @@
|
|
|
44
43
|
"dist/*"
|
|
45
44
|
],
|
|
46
45
|
"devDependencies": {
|
|
47
|
-
"@types/node": "22.
|
|
46
|
+
"@types/node": "22.13.14",
|
|
48
47
|
"ava": "^6.2.0",
|
|
49
48
|
"gts": "^5.3.1",
|
|
50
|
-
"typedoc": "^0.
|
|
51
|
-
"typescript": "^5.
|
|
49
|
+
"typedoc": "^0.28.1",
|
|
50
|
+
"typescript": "^5.8.2"
|
|
52
51
|
},
|
|
53
52
|
"dependencies": {
|
|
54
|
-
"temporal-polyfill": "^0.
|
|
53
|
+
"temporal-polyfill": "^0.3.0"
|
|
55
54
|
}
|
|
56
55
|
}
|
package/dist/index.cjs
DELETED
|
@@ -1,1102 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NOAACalculator = exports.GeoLocation = void 0;
|
|
4
|
-
require("temporal-polyfill/global");
|
|
5
|
-
/**
|
|
6
|
-
* java.lang.Math.toRadians
|
|
7
|
-
* @private
|
|
8
|
-
* @param degrees
|
|
9
|
-
*/
|
|
10
|
-
function degreesToRadians(degrees) {
|
|
11
|
-
return (degrees * Math.PI) / 180;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* java.lang.Math.toDegrees
|
|
15
|
-
* @private
|
|
16
|
-
* @param radians
|
|
17
|
-
*/
|
|
18
|
-
function radiansToDegrees(radians) {
|
|
19
|
-
return (radians * 180) / Math.PI;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* A class that contains location information such as latitude and longitude required for astronomical calculations. The
|
|
23
|
-
* elevation field may not be used by some calculation engines and would be ignored if set.
|
|
24
|
-
*
|
|
25
|
-
* @author © Eliyahu Hershfeld 2004 - 2016
|
|
26
|
-
* @version 1.1
|
|
27
|
-
*/
|
|
28
|
-
class GeoLocation {
|
|
29
|
-
/**
|
|
30
|
-
* GeoLocation constructor with parameters for all required fields.
|
|
31
|
-
*
|
|
32
|
-
* @param {string} name
|
|
33
|
-
* The location name for display use such as "Lakewood, NJ"
|
|
34
|
-
* @param {number} latitude
|
|
35
|
-
* the latitude in a double format such as 40.095965 for Lakewood, NJ.
|
|
36
|
-
* <b>Note: </b> For latitudes south of the equator, a negative value should be used.
|
|
37
|
-
* @param {number} longitude
|
|
38
|
-
* double the longitude in a double format such as -74.222130 for Lakewood, NJ.
|
|
39
|
-
* <b>Note: </b> For longitudes west of the <a href="http://en.wikipedia.org/wiki/Prime_Meridian">Prime
|
|
40
|
-
* Meridian </a> (Greenwich), a negative value should be used.
|
|
41
|
-
* @param {number} elevation
|
|
42
|
-
* the elevation above sea level in Meters. Elevation is not used in most algorithms used for calculating
|
|
43
|
-
* sunrise and set.
|
|
44
|
-
* @param {string} timeZoneId
|
|
45
|
-
* the <code>TimeZone</code> for the location.
|
|
46
|
-
*/
|
|
47
|
-
constructor(name, latitude, longitude, elevation, timeZoneId) {
|
|
48
|
-
/**
|
|
49
|
-
* @private
|
|
50
|
-
*/
|
|
51
|
-
this.locationName = null;
|
|
52
|
-
this.setLocationName(name);
|
|
53
|
-
this.setLatitude(latitude);
|
|
54
|
-
this.setLongitude(longitude);
|
|
55
|
-
this.setElevation(elevation);
|
|
56
|
-
this.setTimeZone(timeZoneId);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Method to get the elevation in Meters.
|
|
60
|
-
*
|
|
61
|
-
* @return {number} Returns the elevation in Meters.
|
|
62
|
-
*/
|
|
63
|
-
getElevation() {
|
|
64
|
-
return this.elevation;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Method to set the elevation in Meters <b>above </b> sea level.
|
|
68
|
-
*
|
|
69
|
-
* @param {number} elevation
|
|
70
|
-
* The elevation to set in Meters. An Error will be thrown if the value is a negative.
|
|
71
|
-
*/
|
|
72
|
-
setElevation(elevation) {
|
|
73
|
-
if (typeof elevation !== 'number')
|
|
74
|
-
throw new TypeError('Invalid elevation');
|
|
75
|
-
if (elevation < 0) {
|
|
76
|
-
throw new RangeError(`elevation ${elevation} must be zero or positive`);
|
|
77
|
-
}
|
|
78
|
-
this.elevation = elevation;
|
|
79
|
-
}
|
|
80
|
-
setLatitude(latitude) {
|
|
81
|
-
if (typeof latitude !== 'number')
|
|
82
|
-
throw new TypeError('Invalid latitude');
|
|
83
|
-
if (latitude < -90 || latitude > 90) {
|
|
84
|
-
throw new RangeError(`Latitude ${latitude} out of range [-90,90]`);
|
|
85
|
-
}
|
|
86
|
-
this.latitude = latitude;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* @return {number} Returns the latitude.
|
|
90
|
-
*/
|
|
91
|
-
getLatitude() {
|
|
92
|
-
return this.latitude;
|
|
93
|
-
}
|
|
94
|
-
setLongitude(longitude) {
|
|
95
|
-
if (typeof longitude !== 'number')
|
|
96
|
-
throw new TypeError('Invalid longitude');
|
|
97
|
-
if (longitude < -180 || longitude > 180) {
|
|
98
|
-
throw new RangeError(`Longitude ${longitude} out of range [-180,180]`);
|
|
99
|
-
}
|
|
100
|
-
this.longitude = longitude;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* @return {number} Returns the longitude.
|
|
104
|
-
*/
|
|
105
|
-
getLongitude() {
|
|
106
|
-
return this.longitude;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* @return {string|null} Returns the location name.
|
|
110
|
-
*/
|
|
111
|
-
getLocationName() {
|
|
112
|
-
return this.locationName;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* @param {string|null} name
|
|
116
|
-
* The setter method for the display name.
|
|
117
|
-
*/
|
|
118
|
-
setLocationName(name) {
|
|
119
|
-
this.locationName = name;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* @return {string} Returns the timeZone.
|
|
123
|
-
*/
|
|
124
|
-
getTimeZone() {
|
|
125
|
-
return this.timeZoneId;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Method to set the TimeZone.
|
|
129
|
-
* @param {string} timeZoneId
|
|
130
|
-
* The timeZone to set.
|
|
131
|
-
*/
|
|
132
|
-
setTimeZone(timeZoneId) {
|
|
133
|
-
this.timeZoneId = timeZoneId;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
exports.GeoLocation = GeoLocation;
|
|
137
|
-
/**
|
|
138
|
-
* The commonly used average solar refraction. Calendrical Calculations lists a more accurate global average of
|
|
139
|
-
* 34.478885263888294
|
|
140
|
-
* @private
|
|
141
|
-
*/
|
|
142
|
-
const refraction = 34 / 60;
|
|
143
|
-
// private double refraction = 34.478885263888294 / 60d;
|
|
144
|
-
/**
|
|
145
|
-
* The commonly used average solar radius in minutes of a degree.
|
|
146
|
-
* @private
|
|
147
|
-
*/
|
|
148
|
-
const solarRadius = 16 / 60;
|
|
149
|
-
/**
|
|
150
|
-
* The commonly used average earth radius in KM. At this time, this only affects elevation adjustment and not the
|
|
151
|
-
* sunrise and sunset calculations. The value currently defaults to 6356.9 KM.
|
|
152
|
-
* @private
|
|
153
|
-
*/
|
|
154
|
-
const earthRadius = 6356.9; // in KM
|
|
155
|
-
/**
|
|
156
|
-
* Implementation of sunrise and sunset methods to calculate astronomical times based on the <a
|
|
157
|
-
* href="http://noaa.gov">NOAA</a> algorithm. This calculator uses the Java algorithm based on the implementation by <a
|
|
158
|
-
* href="http://noaa.gov">NOAA - National Oceanic and Atmospheric Administration</a>'s <a href =
|
|
159
|
-
* "http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html">Surface Radiation Research Branch</a>. NOAA's <a
|
|
160
|
-
* href="http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF">implementation</a> is based on equations from <a
|
|
161
|
-
* href="http://www.willbell.com/math/mc1.htm">Astronomical Algorithms</a> by <a
|
|
162
|
-
* href="http://en.wikipedia.org/wiki/Jean_Meeus">Jean Meeus</a>. Added to the algorithm is an adjustment of the zenith
|
|
163
|
-
* to account for elevation. The algorithm can be found in the <a
|
|
164
|
-
* href="http://en.wikipedia.org/wiki/Sunrise_equation">Wikipedia Sunrise Equation</a> article.
|
|
165
|
-
*
|
|
166
|
-
* @author © Eliyahu Hershfeld 2011 - 2019
|
|
167
|
-
*/
|
|
168
|
-
class NOAACalculator {
|
|
169
|
-
/**
|
|
170
|
-
* A constructor that takes in <a href="http://en.wikipedia.org/wiki/Geolocation">geolocation</a> information as a
|
|
171
|
-
* parameter.
|
|
172
|
-
*
|
|
173
|
-
* @param {GeoLocation} geoLocation
|
|
174
|
-
* The location information used for calculating astronomical sun times.
|
|
175
|
-
* @param {Temporal.PlainDate} date
|
|
176
|
-
*/
|
|
177
|
-
constructor(geoLocation, date) {
|
|
178
|
-
this.date = date;
|
|
179
|
-
this.geoLocation = geoLocation;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* The getSunrise method Returns a `Date` representing the
|
|
183
|
-
* {@link getElevationAdjustment elevation adjusted} sunrise time. The zenith used
|
|
184
|
-
* for the calculation uses {@link GEOMETRIC_ZENITH geometric zenith} of 90° plus
|
|
185
|
-
* {@link getElevationAdjustment}. This is adjusted
|
|
186
|
-
* to add approximately 50/60 of a degree to account for 34 archminutes of refraction
|
|
187
|
-
* and 16 archminutes for the sun's radius for a total of {@link adjustZenith 90.83333°}.
|
|
188
|
-
*
|
|
189
|
-
* @return {Temporal.ZonedDateTime | null} the `Date` representing the exact sunrise time. If the calculation can't be computed such as
|
|
190
|
-
* in the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it
|
|
191
|
-
* does not set, a null will be returned. See detailed explanation on top of the page.
|
|
192
|
-
* @see adjustZenith
|
|
193
|
-
* @see getSeaLevelSunrise()
|
|
194
|
-
* @see getUTCSunrise
|
|
195
|
-
*/
|
|
196
|
-
getSunrise() {
|
|
197
|
-
const sunrise = this.getUTCSunrise0(NOAACalculator.GEOMETRIC_ZENITH);
|
|
198
|
-
if (isNaN(sunrise))
|
|
199
|
-
return null;
|
|
200
|
-
return this.getDateFromTime(sunrise, true);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* A method that returns the sunrise without {@link getElevationAdjustment elevation
|
|
204
|
-
* adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
|
|
205
|
-
* something that is not affected by elevation. This method returns sunrise calculated at sea level. This forms the
|
|
206
|
-
* base for dawn calculations that are calculated as a dip below the horizon before sunrise.
|
|
207
|
-
*
|
|
208
|
-
* @return {Temporal.ZonedDateTime | null} the `Date` representing the exact sea-level sunrise time. If the calculation can't be computed
|
|
209
|
-
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
|
|
210
|
-
* where it does not set, a null will be returned. See detailed explanation on top of the page.
|
|
211
|
-
* @see getSunrise
|
|
212
|
-
* @see getUTCSeaLevelSunrise
|
|
213
|
-
* @see getSeaLevelSunset()
|
|
214
|
-
*/
|
|
215
|
-
getSeaLevelSunrise() {
|
|
216
|
-
const sunrise = this.getUTCSeaLevelSunrise(NOAACalculator.GEOMETRIC_ZENITH);
|
|
217
|
-
if (isNaN(sunrise))
|
|
218
|
-
return null;
|
|
219
|
-
return this.getDateFromTime(sunrise, true);
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* A method that returns the beginning of civil twilight (dawn) using a zenith of {@link CIVIL_ZENITH 96°}.
|
|
223
|
-
*
|
|
224
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of civil twilight using a zenith of 96°. If the calculation
|
|
225
|
-
* can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
226
|
-
* @see CIVIL_ZENITH
|
|
227
|
-
*/
|
|
228
|
-
getBeginCivilTwilight() {
|
|
229
|
-
return this.getSunriseOffsetByDegrees(NOAACalculator.CIVIL_ZENITH);
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* A method that returns the beginning of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}.
|
|
233
|
-
*
|
|
234
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of nautical twilight using a zenith of 102°. If the
|
|
235
|
-
* calculation can't be computed null will be returned. See detailed explanation on top of the page.
|
|
236
|
-
* @see NAUTICAL_ZENITH
|
|
237
|
-
*/
|
|
238
|
-
getBeginNauticalTwilight() {
|
|
239
|
-
return this.getSunriseOffsetByDegrees(NOAACalculator.NAUTICAL_ZENITH);
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* A method that returns the beginning of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH
|
|
243
|
-
* 108°}.
|
|
244
|
-
*
|
|
245
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the beginning of astronomical twilight using a zenith of 108°. If the
|
|
246
|
-
* calculation can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
247
|
-
* @see ASTRONOMICAL_ZENITH
|
|
248
|
-
*/
|
|
249
|
-
getBeginAstronomicalTwilight() {
|
|
250
|
-
return this.getSunriseOffsetByDegrees(NOAACalculator.ASTRONOMICAL_ZENITH);
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* The getSunset method Returns a `Date` representing the
|
|
254
|
-
* {@link getElevationAdjustment elevation adjusted} sunset time. The zenith used for
|
|
255
|
-
* the calculation uses {@link GEOMETRIC_ZENITH geometric zenith} of 90° plus
|
|
256
|
-
* {@link getElevationAdjustment}. This is adjusted
|
|
257
|
-
* to add approximately 50/60 of a degree to account for 34 archminutes of refraction
|
|
258
|
-
* and 16 archminutes for the sun's radius for a total of {@link adjustZenith 90.83333°}.
|
|
259
|
-
* Note:
|
|
260
|
-
* In certain cases the calculates sunset will occur before sunrise. This will typically happen when a timezone
|
|
261
|
-
* other than the local timezone is used (calculating Los Angeles sunset using a GMT timezone for example). In this
|
|
262
|
-
* case the sunset date will be incremented to the following date.
|
|
263
|
-
*
|
|
264
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` representing the exact sunset time. If the calculation can't be computed such as in
|
|
265
|
-
* the Arctic Circle where there is at least one day a year where the sun does not rise, and one where it
|
|
266
|
-
* does not set, a null will be returned. See detailed explanation on top of the page.
|
|
267
|
-
* @see adjustZenith
|
|
268
|
-
* @see getSeaLevelSunset()
|
|
269
|
-
* @see getUTCSunset
|
|
270
|
-
*/
|
|
271
|
-
getSunset() {
|
|
272
|
-
const sunset = this.getUTCSunset0(NOAACalculator.GEOMETRIC_ZENITH);
|
|
273
|
-
if (isNaN(sunset))
|
|
274
|
-
return null;
|
|
275
|
-
return this.getDateFromTime(sunset, false);
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* A method that returns the sunset without {@link getElevationAdjustment elevation
|
|
279
|
-
* adjustment}. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible light,
|
|
280
|
-
* something that is not affected by elevation. This method returns sunset calculated at sea level. This forms the
|
|
281
|
-
* base for dusk calculations that are calculated as a dip below the horizon after sunset.
|
|
282
|
-
*
|
|
283
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` representing the exact sea-level sunset time. If the calculation can't be computed
|
|
284
|
-
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
|
|
285
|
-
* where it does not set, a null will be returned. See detailed explanation on top of the page.
|
|
286
|
-
* @see getSunset
|
|
287
|
-
* @see getUTCSeaLevelSunset
|
|
288
|
-
*/
|
|
289
|
-
getSeaLevelSunset() {
|
|
290
|
-
const sunset = this.getUTCSeaLevelSunset(NOAACalculator.GEOMETRIC_ZENITH);
|
|
291
|
-
if (isNaN(sunset))
|
|
292
|
-
return null;
|
|
293
|
-
return this.getDateFromTime(sunset, false);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* A method that returns the end of civil twilight using a zenith of {@link CIVIL_ZENITH 96°}.
|
|
297
|
-
*
|
|
298
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of civil twilight using a zenith of {@link CIVIL_ZENITH 96°}. If
|
|
299
|
-
* the calculation can't be computed, null will be returned. See detailed explanation on top of the page.
|
|
300
|
-
* @see CIVIL_ZENITH
|
|
301
|
-
*/
|
|
302
|
-
getEndCivilTwilight() {
|
|
303
|
-
return this.getSunsetOffsetByDegrees(NOAACalculator.CIVIL_ZENITH);
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* A method that returns the end of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}.
|
|
307
|
-
*
|
|
308
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of nautical twilight using a zenith of {@link NAUTICAL_ZENITH 102°}
|
|
309
|
-
* . If the calculation can't be computed, null will be returned. See detailed explanation on top of the
|
|
310
|
-
* page.
|
|
311
|
-
* @see NAUTICAL_ZENITH
|
|
312
|
-
*/
|
|
313
|
-
getEndNauticalTwilight() {
|
|
314
|
-
return this.getSunsetOffsetByDegrees(NOAACalculator.NAUTICAL_ZENITH);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* A method that returns the end of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH 108°}.
|
|
318
|
-
*
|
|
319
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the end of astronomical twilight using a zenith of {@link ASTRONOMICAL_ZENITH
|
|
320
|
-
* 108°}. If the calculation can't be computed, null will be returned. See detailed explanation on top
|
|
321
|
-
* of the page.
|
|
322
|
-
* @see ASTRONOMICAL_ZENITH
|
|
323
|
-
*/
|
|
324
|
-
getEndAstronomicalTwilight() {
|
|
325
|
-
return this.getSunsetOffsetByDegrees(NOAACalculator.ASTRONOMICAL_ZENITH);
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* A utility method that returns a date offset by the offset time passed in. Please note that the level of light
|
|
329
|
-
* during twilight is not affected by elevation, so if this is being used to calculate an offset before sunrise or
|
|
330
|
-
* after sunset with the intent of getting a rough "level of light" calculation, the sunrise or sunset time passed
|
|
331
|
-
* to this method should be sea level sunrise and sunset.
|
|
332
|
-
*
|
|
333
|
-
* @param {Temporal.ZonedDateTime | null} time
|
|
334
|
-
* the start time
|
|
335
|
-
* @param {number} offset
|
|
336
|
-
* the offset in milliseconds to add to the time.
|
|
337
|
-
* @return {Temporal.ZonedDateTime | null} the `Date` with the offset in milliseconds added to it
|
|
338
|
-
*/
|
|
339
|
-
static getTimeOffset(time, offset) {
|
|
340
|
-
if (time === null || isNaN(offset)) {
|
|
341
|
-
return null;
|
|
342
|
-
}
|
|
343
|
-
return time.add({ milliseconds: offset });
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* A utility method that returns the time of an offset by degrees below or above the horizon of
|
|
347
|
-
* {@link getSunrise() sunrise}. Note that the degree offset is from the vertical, so for a calculation of 14°
|
|
348
|
-
* before sunrise, an offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
349
|
-
*
|
|
350
|
-
* @param {number} offsetZenith
|
|
351
|
-
* the degrees before {@link getSunrise} to use in the calculation. For time after sunrise use
|
|
352
|
-
* negative numbers. Note that the degree offset is from the vertical, so for a calculation of 14°
|
|
353
|
-
* before sunrise, an offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a
|
|
354
|
-
* parameter.
|
|
355
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` of the offset after (or before) {@link getSunrise}. If the calculation
|
|
356
|
-
* can't be computed such as in the Arctic Circle where there is at least one day a year where the sun does
|
|
357
|
-
* not rise, and one where it does not set, a null will be returned. See detailed explanation on top of the
|
|
358
|
-
* page.
|
|
359
|
-
*/
|
|
360
|
-
getSunriseOffsetByDegrees(offsetZenith) {
|
|
361
|
-
const dawn = this.getUTCSunrise0(offsetZenith);
|
|
362
|
-
if (isNaN(dawn))
|
|
363
|
-
return null;
|
|
364
|
-
return this.getDateFromTime(dawn, true);
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* A utility method that returns the time of an offset by degrees below or above the horizon of {@link getSunset()
|
|
368
|
-
* sunset}. Note that the degree offset is from the vertical, so for a calculation of 14° after sunset, an
|
|
369
|
-
* offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
370
|
-
*
|
|
371
|
-
* @param {number} offsetZenith
|
|
372
|
-
* the degrees after {@link getSunset} to use in the calculation. For time before sunset use negative
|
|
373
|
-
* numbers. Note that the degree offset is from the vertical, so for a calculation of 14° after
|
|
374
|
-
* sunset, an offset of 14 + {@link GEOMETRIC_ZENITH} = 104 would have to be passed as a parameter.
|
|
375
|
-
* @return {Temporal.ZonedDateTime | null} The `Date`of the offset after (or before) {@link getSunset}. If the calculation can't
|
|
376
|
-
* be computed such as in the Arctic Circle where there is at least one day a year where the sun does not
|
|
377
|
-
* rise, and one where it does not set, a null will be returned. See detailed explanation on top of the
|
|
378
|
-
* page.
|
|
379
|
-
*/
|
|
380
|
-
getSunsetOffsetByDegrees(offsetZenith) {
|
|
381
|
-
const sunset = this.getUTCSunset0(offsetZenith);
|
|
382
|
-
if (isNaN(sunset))
|
|
383
|
-
return null;
|
|
384
|
-
return this.getDateFromTime(sunset, false);
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
|
|
388
|
-
* daylight savings time.
|
|
389
|
-
*
|
|
390
|
-
* @param {number} zenith
|
|
391
|
-
* the degrees below the horizon. For time after sunrise use negative numbers.
|
|
392
|
-
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
393
|
-
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
394
|
-
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
395
|
-
*/
|
|
396
|
-
getUTCSunrise0(zenith) {
|
|
397
|
-
return this.getUTCSunrise(this.getAdjustedDate(), this.geoLocation, zenith, true);
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* A method that returns the sunrise in UTC time without correction for time zone offset from GMT and without using
|
|
401
|
-
* daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the amount of visible
|
|
402
|
-
* light, something that is not affected by elevation. This method returns UTC sunrise calculated at sea level. This
|
|
403
|
-
* forms the base for dawn calculations that are calculated as a dip below the horizon before sunrise.
|
|
404
|
-
*
|
|
405
|
-
* @param {number} zenith
|
|
406
|
-
* the degrees below the horizon. For time after sunrise use negative numbers.
|
|
407
|
-
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
408
|
-
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
409
|
-
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
410
|
-
* @see getUTCSunrise
|
|
411
|
-
* @see getUTCSeaLevelSunset
|
|
412
|
-
*/
|
|
413
|
-
getUTCSeaLevelSunrise(zenith) {
|
|
414
|
-
return this.getUTCSunrise(this.getAdjustedDate(), this.geoLocation, zenith, false);
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* A method that returns the sunset in UTC time without correction for time zone offset from GMT and without using
|
|
418
|
-
* daylight savings time.
|
|
419
|
-
*
|
|
420
|
-
* @param {number} zenith
|
|
421
|
-
* the degrees below the horizon. For time after sunset use negative numbers.
|
|
422
|
-
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
423
|
-
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
424
|
-
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
425
|
-
* @see getUTCSeaLevelSunset
|
|
426
|
-
*/
|
|
427
|
-
getUTCSunset0(zenith) {
|
|
428
|
-
return this.getUTCSunset(this.getAdjustedDate(), this.geoLocation, zenith, true);
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* A method that returns the sunset in UTC time without correction for elevation, time zone offset from GMT and
|
|
432
|
-
* without using daylight savings time. Non-sunrise and sunset calculations such as dawn and dusk, depend on the
|
|
433
|
-
* amount of visible light, something that is not affected by elevation. This method returns UTC sunset calculated
|
|
434
|
-
* at sea level. This forms the base for dusk calculations that are calculated as a dip below the horizon after
|
|
435
|
-
* sunset.
|
|
436
|
-
*
|
|
437
|
-
* @param {number} zenith
|
|
438
|
-
* the degrees below the horizon. For time before sunset use negative numbers.
|
|
439
|
-
* @return {number} The time in the format: 18.75 for 18:45:00 UTC/GMT. If the calculation can't be computed such as in the
|
|
440
|
-
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
441
|
-
* not set, `NaN` will be returned. See detailed explanation on top of the page.
|
|
442
|
-
* @see getUTCSunset
|
|
443
|
-
* @see getUTCSeaLevelSunrise
|
|
444
|
-
*/
|
|
445
|
-
getUTCSeaLevelSunset(zenith) {
|
|
446
|
-
return this.getUTCSunset(this.getAdjustedDate(), this.geoLocation, zenith, false);
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Adjusts the <code>Calendar</code> to deal with edge cases where the location crosses the antimeridian.
|
|
450
|
-
* @private
|
|
451
|
-
* @see GeoLocation#getAntimeridianAdjustment()
|
|
452
|
-
* @return the adjusted Calendar
|
|
453
|
-
*/
|
|
454
|
-
getAdjustedDate() {
|
|
455
|
-
return this.date;
|
|
456
|
-
}
|
|
457
|
-
/**
|
|
458
|
-
* Method to return the adjustment to the zenith required to account for the elevation. Since a person at a higher
|
|
459
|
-
* elevation can see farther below the horizon, the calculation for sunrise / sunset is calculated below the horizon
|
|
460
|
-
* used at sea level. This is only used for sunrise and sunset and not times before or after it such as
|
|
461
|
-
* {@link getBeginNauticalTwilight() nautical twilight} since those
|
|
462
|
-
* calculations are based on the level of available light at the given dip below the horizon, something that is not
|
|
463
|
-
* affected by elevation, the adjustment should only made if the zenith == 90° {@link adjustZenith adjusted}
|
|
464
|
-
* for refraction and solar radius. The algorithm used is
|
|
465
|
-
*
|
|
466
|
-
* <pre>
|
|
467
|
-
* elevationAdjustment = Math.toDegrees(Math.acos(earthRadiusInMeters / (earthRadiusInMeters + elevationMeters)));
|
|
468
|
-
* </pre>
|
|
469
|
-
*
|
|
470
|
-
* The source of this algorithm is <a href="http://www.calendarists.com">Calendrical Calculations</a> by Edward M.
|
|
471
|
-
* Reingold and Nachum Dershowitz. An alternate algorithm that produces an almost identical (but not accurate)
|
|
472
|
-
* result found in Ma'aglay Tzedek by Moishe Kosower and other sources is:
|
|
473
|
-
*
|
|
474
|
-
* <pre>
|
|
475
|
-
* elevationAdjustment = 0.0347 * Math.sqrt(elevationMeters);
|
|
476
|
-
* </pre>
|
|
477
|
-
*
|
|
478
|
-
* @param {number} elevation
|
|
479
|
-
* elevation in Meters.
|
|
480
|
-
* @return {number} the adjusted zenith
|
|
481
|
-
*/
|
|
482
|
-
getElevationAdjustment(elevation) {
|
|
483
|
-
// double elevationAdjustment = 0.0347 * Math.sqrt(elevation);
|
|
484
|
-
const elevationAdjustment = radiansToDegrees(Math.acos(earthRadius / (earthRadius + elevation / 1000)));
|
|
485
|
-
return elevationAdjustment;
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* Adjusts the zenith of astronomical sunrise and sunset to account for solar refraction, solar radius and
|
|
489
|
-
* elevation. The value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle
|
|
490
|
-
* that the center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the
|
|
491
|
-
* Earth were without an atmosphere, true sunset and sunrise would correspond to a 90° zenith. Because the Sun
|
|
492
|
-
* is not a point, and because the atmosphere refracts light, this 90° zenith does not, in fact, correspond to
|
|
493
|
-
* true sunset or sunrise, instead the centre of the Sun's disk must lie just below the horizon for the upper edge
|
|
494
|
-
* to be obscured. This means that a zenith of just above 90° must be used. The Sun subtends an angle of 16
|
|
495
|
-
* minutes of arc, and atmospheric refraction
|
|
496
|
-
* accounts for 34 minutes or so, giving a total
|
|
497
|
-
* of 50 arcminutes. The total value for ZENITH is 90+(5/6) or 90.8333333° for true sunrise/sunset. Since a
|
|
498
|
-
* person at an elevation can see blow the horizon of a person at sea level, this will also adjust the zenith to
|
|
499
|
-
* account for elevation if available. Note that this will only adjust the value if the zenith is exactly 90 degrees.
|
|
500
|
-
* For values below and above this no correction is done. As an example, astronomical twilight is when the sun is
|
|
501
|
-
* 18° below the horizon or {@link ASTRONOMICAL_ZENITH 108°
|
|
502
|
-
* below the zenith}. This is traditionally calculated with none of the above mentioned adjustments. The same goes
|
|
503
|
-
* for various <em>tzais</em> and <em>alos</em> times such as the
|
|
504
|
-
* {@link ZmanimCalendar#ZENITH_16_POINT_1 16.1°} dip used in
|
|
505
|
-
* {@link ComplexZmanimCalendar#getAlos16Point1Degrees}.
|
|
506
|
-
*
|
|
507
|
-
* @param {number} zenith
|
|
508
|
-
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link adjustZenith
|
|
509
|
-
* zenith} used for the calculation uses geometric zenith of 90° and {@link adjustZenith adjusts}
|
|
510
|
-
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
511
|
-
* {@link getEndNauticalTwilight} that passes
|
|
512
|
-
* {@link NAUTICAL_ZENITH} to this method.
|
|
513
|
-
* @param {number} elevation
|
|
514
|
-
* elevation in Meters.
|
|
515
|
-
* @return {number} The zenith adjusted to include the sun's radius, refracton
|
|
516
|
-
* and {@link getElevationAdjustment elevation} adjustment. This will only be adjusted for
|
|
517
|
-
* sunrise and sunset (if the zenith == 90°)
|
|
518
|
-
* @see getElevationAdjustment
|
|
519
|
-
*/
|
|
520
|
-
adjustZenith(zenith, elevation) {
|
|
521
|
-
let adjustedZenith = zenith;
|
|
522
|
-
if (zenith === NOAACalculator.GEOMETRIC_ZENITH) {
|
|
523
|
-
// only adjust if it is exactly sunrise or sunset
|
|
524
|
-
adjustedZenith =
|
|
525
|
-
zenith +
|
|
526
|
-
(solarRadius + refraction + this.getElevationAdjustment(elevation));
|
|
527
|
-
}
|
|
528
|
-
return adjustedZenith;
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* A method that calculates UTC sunrise as well as any time based on an angle above or below sunrise.
|
|
532
|
-
* @param date
|
|
533
|
-
* Used to calculate day of year.
|
|
534
|
-
* @param geoLocation
|
|
535
|
-
* The location information used for astronomical calculating sun times.
|
|
536
|
-
* @param zenith
|
|
537
|
-
* the azimuth below the vertical zenith of 90 degrees. for sunrise typically the {@link adjustZenith
|
|
538
|
-
* zenith} used for the calculation uses geometric zenith of 90° and {@link adjustZenith adjusts}
|
|
539
|
-
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
540
|
-
* {@link getBeginNauticalTwilight} that passes
|
|
541
|
-
* {@link NAUTICAL_ZENITH} to this method.
|
|
542
|
-
* @param adjustForElevation
|
|
543
|
-
* Should the time be adjusted for elevation
|
|
544
|
-
* @return The UTC time of sunrise in 24 hour format. 5:45:00 AM will return 5.75.0. If an error was encountered in
|
|
545
|
-
* the calculation (expected behavior for some locations such as near the poles,
|
|
546
|
-
* `NaN` will be returned.
|
|
547
|
-
*/
|
|
548
|
-
getUTCSunrise(date, geoLocation, zenith, adjustForElevation) {
|
|
549
|
-
const elevation = adjustForElevation
|
|
550
|
-
? geoLocation.getElevation()
|
|
551
|
-
: 0;
|
|
552
|
-
const adjustedZenith = this.adjustZenith(zenith, elevation);
|
|
553
|
-
let sunrise = NOAACalculator.getSunriseUTC(NOAACalculator.getJulianDay(date), geoLocation.getLatitude(), -geoLocation.getLongitude(), adjustedZenith);
|
|
554
|
-
sunrise = sunrise / 60;
|
|
555
|
-
// ensure that the time is >= 0 and < 24
|
|
556
|
-
while (sunrise < 0) {
|
|
557
|
-
sunrise += 24;
|
|
558
|
-
}
|
|
559
|
-
while (sunrise >= 24) {
|
|
560
|
-
sunrise -= 24;
|
|
561
|
-
}
|
|
562
|
-
return sunrise;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* A method that calculates UTC sunset as well as any time based on an angle above or below sunset.
|
|
566
|
-
* @param date
|
|
567
|
-
* Used to calculate day of year.
|
|
568
|
-
* @param geoLocation
|
|
569
|
-
* The location information used for astronomical calculating sun times.
|
|
570
|
-
* @param zenith
|
|
571
|
-
* the azimuth below the vertical zenith of 90°. For sunset typically the {@link adjustZenith
|
|
572
|
-
* zenith} used for the calculation uses geometric zenith of 90° and {@link adjustZenith adjusts}
|
|
573
|
-
* this slightly to account for solar refraction and the sun's radius. Another example would be
|
|
574
|
-
* {@link getEndNauticalTwilight} that passes
|
|
575
|
-
* {@link NAUTICAL_ZENITH} to this method.
|
|
576
|
-
* @param adjustForElevation
|
|
577
|
-
* Should the time be adjusted for elevation
|
|
578
|
-
* @return The UTC time of sunset in 24 hour format. 5:45:00 AM will return 5.75.0. If an error was encountered in
|
|
579
|
-
* the calculation (expected behavior for some locations such as near the poles,
|
|
580
|
-
* `NaN` will be returned.
|
|
581
|
-
*/
|
|
582
|
-
getUTCSunset(date, geoLocation, zenith, adjustForElevation) {
|
|
583
|
-
const elevation = adjustForElevation
|
|
584
|
-
? geoLocation.getElevation()
|
|
585
|
-
: 0;
|
|
586
|
-
const adjustedZenith = this.adjustZenith(zenith, elevation);
|
|
587
|
-
let sunset = NOAACalculator.getSunsetUTC(NOAACalculator.getJulianDay(date), geoLocation.getLatitude(), -geoLocation.getLongitude(), adjustedZenith);
|
|
588
|
-
sunset = sunset / 60;
|
|
589
|
-
// ensure that the time is >= 0 and < 24
|
|
590
|
-
while (sunset < 0) {
|
|
591
|
-
sunset += 24;
|
|
592
|
-
}
|
|
593
|
-
while (sunset >= 24) {
|
|
594
|
-
sunset -= 24;
|
|
595
|
-
}
|
|
596
|
-
return sunset;
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* A utility method that will allow the calculation of a temporal (solar) hour based on the sunrise and sunset
|
|
600
|
-
* passed as parameters to this method. An example of the use of this method would be the calculation of a
|
|
601
|
-
* non-elevation adjusted temporal hour by passing in {@link getSeaLevelSunrise() sea level sunrise} and
|
|
602
|
-
* {@link getSeaLevelSunset() sea level sunset} as parameters.
|
|
603
|
-
*
|
|
604
|
-
* @param {Temporal.ZonedDateTime | null} startOfDay
|
|
605
|
-
* The start of the day.
|
|
606
|
-
* @param {Temporal.ZonedDateTime | null} endOfDay
|
|
607
|
-
* The end of the day.
|
|
608
|
-
*
|
|
609
|
-
* @return {number} the <code>long</code> millisecond length of the temporal hour. If the calculation can't be computed a
|
|
610
|
-
* `NaN` will be returned. See detailed explanation on top of the page.
|
|
611
|
-
*
|
|
612
|
-
* @see getTemporalHour()
|
|
613
|
-
*/
|
|
614
|
-
getTemporalHour(startOfDay = this.getSeaLevelSunrise(), endOfDay = this.getSeaLevelSunset()) {
|
|
615
|
-
if (startOfDay === null || endOfDay === null) {
|
|
616
|
-
return NaN;
|
|
617
|
-
}
|
|
618
|
-
const delta = endOfDay.epochMilliseconds - startOfDay.epochMilliseconds;
|
|
619
|
-
return Math.floor(delta / 12);
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* A method that returns sundial or solar noon. It occurs when the Sun is <a href
|
|
623
|
-
* ="http://en.wikipedia.org/wiki/Transit_%28astronomy%29">transiting</a> the <a
|
|
624
|
-
* href="http://en.wikipedia.org/wiki/Meridian_%28astronomy%29">celestial meridian</a>. In this class it is
|
|
625
|
-
* calculated as halfway between the sunrise and sunset passed to this method. This time can be slightly off the
|
|
626
|
-
* real transit time due to changes in declination (the lengthening or shortening day).
|
|
627
|
-
*
|
|
628
|
-
* @param {Temporal.ZonedDateTime | null} startOfDay
|
|
629
|
-
* the start of day for calculating the sun's transit. This can be sea level sunrise, visual sunrise (or
|
|
630
|
-
* any arbitrary start of day) passed to this method.
|
|
631
|
-
* @param {Temporal.ZonedDateTime | null} endOfDay
|
|
632
|
-
* the end of day for calculating the sun's transit. This can be sea level sunset, visual sunset (or any
|
|
633
|
-
* arbitrary end of day) passed to this method.
|
|
634
|
-
*
|
|
635
|
-
* @return {Temporal.ZonedDateTime | null} The `Date` representing Sun's transit. If the calculation can't be computed such as in the
|
|
636
|
-
* Arctic Circle where there is at least one day a year where the sun does not rise, and one where it does
|
|
637
|
-
* not set, null will be returned. See detailed explanation on top of the page.
|
|
638
|
-
*/
|
|
639
|
-
getSunTransit(startOfDay = this.getSeaLevelSunrise(), endOfDay = this.getSeaLevelSunset()) {
|
|
640
|
-
const temporalHour = this.getTemporalHour(startOfDay, endOfDay);
|
|
641
|
-
return NOAACalculator.getTimeOffset(startOfDay, temporalHour * 6);
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* A method that returns a `Date` from the time passed in as a parameter.
|
|
645
|
-
* @protected
|
|
646
|
-
* @param {number} time
|
|
647
|
-
* The time to be set as the time for the `Date`. The time expected is in the format: 18.75
|
|
648
|
-
* for 6:45:00 PM.
|
|
649
|
-
* @param {boolean} isSunrise true if the time is sunrise, and false if it is sunset
|
|
650
|
-
* @return {Temporal.ZonedDateTime | null} The Date.
|
|
651
|
-
*/
|
|
652
|
-
getDateFromTime(time, isSunrise) {
|
|
653
|
-
if (isNaN(time)) {
|
|
654
|
-
return null;
|
|
655
|
-
}
|
|
656
|
-
let calculatedTime = time;
|
|
657
|
-
let cal = this.getAdjustedDate();
|
|
658
|
-
// let cal = new Temporal.PlainDate(adj.year, adj.month, adj.day);
|
|
659
|
-
const hours = Math.trunc(calculatedTime); // retain only the hours
|
|
660
|
-
calculatedTime -= hours;
|
|
661
|
-
const minutes = Math.trunc((calculatedTime *= 60)); // retain only the minutes
|
|
662
|
-
calculatedTime -= minutes;
|
|
663
|
-
const seconds = Math.trunc((calculatedTime *= 60)); // retain only the seconds
|
|
664
|
-
calculatedTime -= seconds; // remaining milliseconds
|
|
665
|
-
// Check if a date transition has occurred, or is about to occur - this indicates the date of the event is
|
|
666
|
-
// actually not the target date, but the day prior or after
|
|
667
|
-
const localTimeHours = Math.trunc(this.geoLocation.getLongitude() / 15);
|
|
668
|
-
if (isSunrise && localTimeHours + hours > 18) {
|
|
669
|
-
cal = cal.add({ days: -1 });
|
|
670
|
-
// cal = cal.minus({days: 1});
|
|
671
|
-
}
|
|
672
|
-
else if (!isSunrise && localTimeHours + hours < 6) {
|
|
673
|
-
cal = cal.add({ days: 1 });
|
|
674
|
-
}
|
|
675
|
-
return cal
|
|
676
|
-
.toZonedDateTime({
|
|
677
|
-
timeZone: 'UTC',
|
|
678
|
-
plainTime: new Temporal.PlainTime(hours, minutes, seconds, Math.trunc(calculatedTime * 1000)),
|
|
679
|
-
})
|
|
680
|
-
.withTimeZone(this.geoLocation.getTimeZone());
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> from a Java Calendar
|
|
684
|
-
* @private
|
|
685
|
-
* @param {Temporal.ZonedDateTime} date
|
|
686
|
-
* The Java Calendar
|
|
687
|
-
* @return the Julian day corresponding to the date Note: Number is returned for start of day. Fractional days
|
|
688
|
-
* should be added later.
|
|
689
|
-
*/
|
|
690
|
-
static getJulianDay(date) {
|
|
691
|
-
let { year, month } = date;
|
|
692
|
-
const { day } = date;
|
|
693
|
-
if (month <= 2) {
|
|
694
|
-
year -= 1;
|
|
695
|
-
month += 12;
|
|
696
|
-
}
|
|
697
|
-
const a = Math.trunc(year / 100);
|
|
698
|
-
const b = Math.trunc(2 - a + a / 4);
|
|
699
|
-
return (Math.floor(365.25 * (year + 4716)) +
|
|
700
|
-
Math.floor(30.6001 * (month + 1)) +
|
|
701
|
-
day +
|
|
702
|
-
b -
|
|
703
|
-
1524.5);
|
|
704
|
-
}
|
|
705
|
-
/**
|
|
706
|
-
* Convert <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> to centuries since J2000.0.
|
|
707
|
-
* @private
|
|
708
|
-
* @param julianDay
|
|
709
|
-
* the Julian Day to convert
|
|
710
|
-
* @return the centuries since 2000 Julian corresponding to the Julian Day
|
|
711
|
-
*/
|
|
712
|
-
static getJulianCenturiesFromJulianDay(julianDay) {
|
|
713
|
-
return ((julianDay - NOAACalculator.JULIAN_DAY_JAN_1_2000) /
|
|
714
|
-
NOAACalculator.JULIAN_DAYS_PER_CENTURY);
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* Convert centuries since J2000.0 to <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a>.
|
|
718
|
-
* @private
|
|
719
|
-
* @param julianCenturies
|
|
720
|
-
* the number of Julian centuries since J2000.0
|
|
721
|
-
* @return the Julian Day corresponding to the Julian centuries passed in
|
|
722
|
-
*/
|
|
723
|
-
static getJulianDayFromJulianCenturies(julianCenturies) {
|
|
724
|
-
return (julianCenturies * NOAACalculator.JULIAN_DAYS_PER_CENTURY +
|
|
725
|
-
NOAACalculator.JULIAN_DAY_JAN_1_2000);
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Returns the Geometric <a href="http://en.wikipedia.org/wiki/Mean_longitude">Mean Longitude</a> of the Sun.
|
|
729
|
-
* @private
|
|
730
|
-
* @param julianCenturies
|
|
731
|
-
* the number of Julian centuries since J2000.0
|
|
732
|
-
* @return the Geometric Mean Longitude of the Sun in degrees
|
|
733
|
-
*/
|
|
734
|
-
static getSunGeometricMeanLongitude(julianCenturies) {
|
|
735
|
-
let longitude = 280.46646 + julianCenturies * (36000.76983 + 0.0003032 * julianCenturies);
|
|
736
|
-
while (longitude > 360) {
|
|
737
|
-
longitude -= 360;
|
|
738
|
-
}
|
|
739
|
-
while (longitude < 0) {
|
|
740
|
-
longitude += 360;
|
|
741
|
-
}
|
|
742
|
-
return longitude; // in degrees
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* Returns the Geometric <a href="http://en.wikipedia.org/wiki/Mean_anomaly">Mean Anomaly</a> of the Sun.
|
|
746
|
-
* @private
|
|
747
|
-
* @param julianCenturies
|
|
748
|
-
* the number of Julian centuries since J2000.0
|
|
749
|
-
* @return the Geometric Mean Anomaly of the Sun in degrees
|
|
750
|
-
*/
|
|
751
|
-
static getSunGeometricMeanAnomaly(julianCenturies) {
|
|
752
|
-
return (357.52911 + julianCenturies * (35999.05029 - 0.0001537 * julianCenturies)); // in degrees
|
|
753
|
-
}
|
|
754
|
-
/**
|
|
755
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Eccentricity_%28orbit%29">eccentricity of earth's orbit</a>.
|
|
756
|
-
* @private
|
|
757
|
-
* @param julianCenturies
|
|
758
|
-
* the number of Julian centuries since J2000.0
|
|
759
|
-
* @return the unitless eccentricity
|
|
760
|
-
*/
|
|
761
|
-
static getEarthOrbitEccentricity(julianCenturies) {
|
|
762
|
-
return (0.016708634 -
|
|
763
|
-
julianCenturies * (0.000042037 + 0.0000001267 * julianCenturies)); // unitless
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
* Returns the <a href="http://en.wikipedia.org/wiki/Equation_of_the_center">equation of center</a> for the sun.
|
|
767
|
-
* @private
|
|
768
|
-
* @param julianCenturies
|
|
769
|
-
* the number of Julian centuries since J2000.0
|
|
770
|
-
* @return the equation of center for the sun in degrees
|
|
771
|
-
*/
|
|
772
|
-
static getSunEquationOfCenter(julianCenturies) {
|
|
773
|
-
const m = NOAACalculator.getSunGeometricMeanAnomaly(julianCenturies);
|
|
774
|
-
const mrad = degreesToRadians(m);
|
|
775
|
-
const sinm = Math.sin(mrad);
|
|
776
|
-
const sin2m = Math.sin(mrad + mrad);
|
|
777
|
-
const sin3m = Math.sin(mrad + mrad + mrad);
|
|
778
|
-
return (sinm *
|
|
779
|
-
(1.914602 - julianCenturies * (0.004817 + 0.000014 * julianCenturies)) +
|
|
780
|
-
sin2m * (0.019993 - 0.000101 * julianCenturies) +
|
|
781
|
-
sin3m * 0.000289); // in degrees
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Return the true longitude of the sun
|
|
785
|
-
* @private
|
|
786
|
-
* @param julianCenturies
|
|
787
|
-
* the number of Julian centuries since J2000.0
|
|
788
|
-
* @return the sun's true longitude in degrees
|
|
789
|
-
*/
|
|
790
|
-
static getSunTrueLongitude(julianCenturies) {
|
|
791
|
-
const sunLongitude = NOAACalculator.getSunGeometricMeanLongitude(julianCenturies);
|
|
792
|
-
const center = NOAACalculator.getSunEquationOfCenter(julianCenturies);
|
|
793
|
-
return sunLongitude + center; // in degrees
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* Return the apparent longitude of the sun
|
|
797
|
-
* @private
|
|
798
|
-
* @param julianCenturies
|
|
799
|
-
* the number of Julian centuries since J2000.0
|
|
800
|
-
* @return sun's apparent longitude in degrees
|
|
801
|
-
*/
|
|
802
|
-
static getSunApparentLongitude(julianCenturies) {
|
|
803
|
-
const sunTrueLongitude = NOAACalculator.getSunTrueLongitude(julianCenturies);
|
|
804
|
-
const omega = 125.04 - 1934.136 * julianCenturies;
|
|
805
|
-
const lambda = sunTrueLongitude - 0.00569 - 0.00478 * Math.sin(degreesToRadians(omega));
|
|
806
|
-
return lambda; // in degrees
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* Returns the mean <a href="http://en.wikipedia.org/wiki/Axial_tilt">obliquity of the ecliptic</a> (Axial tilt).
|
|
810
|
-
* @private
|
|
811
|
-
* @param julianCenturies
|
|
812
|
-
* the number of Julian centuries since J2000.0
|
|
813
|
-
* @return the mean obliquity in degrees
|
|
814
|
-
*/
|
|
815
|
-
static getMeanObliquityOfEcliptic(julianCenturies) {
|
|
816
|
-
const seconds = 21.448 -
|
|
817
|
-
julianCenturies *
|
|
818
|
-
(46.815 + julianCenturies * (0.00059 - julianCenturies * 0.001813));
|
|
819
|
-
return 23 + (26 + seconds / 60) / 60; // in degrees
|
|
820
|
-
}
|
|
821
|
-
/**
|
|
822
|
-
* Returns the corrected <a href="http://en.wikipedia.org/wiki/Axial_tilt">obliquity of the ecliptic</a> (Axial
|
|
823
|
-
* tilt).
|
|
824
|
-
* @private
|
|
825
|
-
* @param julianCenturies
|
|
826
|
-
* the number of Julian centuries since J2000.0
|
|
827
|
-
* @return the corrected obliquity in degrees
|
|
828
|
-
*/
|
|
829
|
-
static getObliquityCorrection(julianCenturies) {
|
|
830
|
-
const obliquityOfEcliptic = NOAACalculator.getMeanObliquityOfEcliptic(julianCenturies);
|
|
831
|
-
const omega = 125.04 - 1934.136 * julianCenturies;
|
|
832
|
-
return obliquityOfEcliptic + 0.00256 * Math.cos(degreesToRadians(omega)); // in degrees
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Declination">declination</a> of the sun.
|
|
836
|
-
* @private
|
|
837
|
-
* @param julianCenturies
|
|
838
|
-
* the number of Julian centuries since J2000.0
|
|
839
|
-
* @return
|
|
840
|
-
* the sun's declination in degrees
|
|
841
|
-
*/
|
|
842
|
-
static getSunDeclination(julianCenturies) {
|
|
843
|
-
const obliquityCorrection = NOAACalculator.getObliquityCorrection(julianCenturies);
|
|
844
|
-
const lambda = NOAACalculator.getSunApparentLongitude(julianCenturies);
|
|
845
|
-
const sint = Math.sin(degreesToRadians(obliquityCorrection)) *
|
|
846
|
-
Math.sin(degreesToRadians(lambda));
|
|
847
|
-
const theta = radiansToDegrees(Math.asin(sint));
|
|
848
|
-
return theta; // in degrees
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Equation_of_time">Equation of Time</a> - the difference between
|
|
852
|
-
* true solar time and mean solar time
|
|
853
|
-
* @private
|
|
854
|
-
* @param julianCenturies
|
|
855
|
-
* the number of Julian centuries since J2000.0
|
|
856
|
-
* @return equation of time in minutes of time
|
|
857
|
-
*/
|
|
858
|
-
static getEquationOfTime(julianCenturies) {
|
|
859
|
-
const epsilon = NOAACalculator.getObliquityCorrection(julianCenturies);
|
|
860
|
-
const geomMeanLongSun = NOAACalculator.getSunGeometricMeanLongitude(julianCenturies);
|
|
861
|
-
const eccentricityEarthOrbit = NOAACalculator.getEarthOrbitEccentricity(julianCenturies);
|
|
862
|
-
const geomMeanAnomalySun = NOAACalculator.getSunGeometricMeanAnomaly(julianCenturies);
|
|
863
|
-
let y = Math.tan(degreesToRadians(epsilon) / 2);
|
|
864
|
-
y *= y;
|
|
865
|
-
const sin2l0 = Math.sin(2 * degreesToRadians(geomMeanLongSun));
|
|
866
|
-
const sinm = Math.sin(degreesToRadians(geomMeanAnomalySun));
|
|
867
|
-
const cos2l0 = Math.cos(2 * degreesToRadians(geomMeanLongSun));
|
|
868
|
-
const sin4l0 = Math.sin(4 * degreesToRadians(geomMeanLongSun));
|
|
869
|
-
const sin2m = Math.sin(2 * degreesToRadians(geomMeanAnomalySun));
|
|
870
|
-
const equationOfTime = y * sin2l0 -
|
|
871
|
-
2 * eccentricityEarthOrbit * sinm +
|
|
872
|
-
4 * eccentricityEarthOrbit * y * sinm * cos2l0 -
|
|
873
|
-
0.5 * y * y * sin4l0 -
|
|
874
|
-
1.25 * eccentricityEarthOrbit * eccentricityEarthOrbit * sin2m;
|
|
875
|
-
return radiansToDegrees(equationOfTime) * 4; // in minutes of time
|
|
876
|
-
}
|
|
877
|
-
/**
|
|
878
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun at sunrise for the
|
|
879
|
-
* latitude.
|
|
880
|
-
* @private
|
|
881
|
-
* @param {number} lat
|
|
882
|
-
* , the latitude of observer in degrees
|
|
883
|
-
* @param solarDec
|
|
884
|
-
* the declination angle of sun in degrees
|
|
885
|
-
* @param {number} zenith
|
|
886
|
-
* the zenith
|
|
887
|
-
* @return hour angle of sunrise in radians
|
|
888
|
-
*/
|
|
889
|
-
static getSunHourAngleAtSunrise(lat, solarDec, zenith) {
|
|
890
|
-
const latRad = degreesToRadians(lat);
|
|
891
|
-
const sdRad = degreesToRadians(solarDec);
|
|
892
|
-
return Math.acos(Math.cos(degreesToRadians(zenith)) /
|
|
893
|
-
(Math.cos(latRad) * Math.cos(sdRad)) -
|
|
894
|
-
Math.tan(latRad) * Math.tan(sdRad)); // in radians
|
|
895
|
-
}
|
|
896
|
-
/**
|
|
897
|
-
* Returns the <a href="http://en.wikipedia.org/wiki/Hour_angle">hour angle</a> of the sun at sunset for the
|
|
898
|
-
* latitude.
|
|
899
|
-
* @private
|
|
900
|
-
* @param {number} lat
|
|
901
|
-
* the latitude of observer in degrees
|
|
902
|
-
* @param solarDec
|
|
903
|
-
* the declination angle of sun in degrees
|
|
904
|
-
* @param {number} zenith
|
|
905
|
-
* the zenith
|
|
906
|
-
* @return the hour angle of sunset in radians
|
|
907
|
-
*/
|
|
908
|
-
static getSunHourAngleAtSunset(lat, solarDec, zenith) {
|
|
909
|
-
const latRad = degreesToRadians(lat);
|
|
910
|
-
const sdRad = degreesToRadians(solarDec);
|
|
911
|
-
const hourAngle = Math.acos(Math.cos(degreesToRadians(zenith)) /
|
|
912
|
-
(Math.cos(latRad) * Math.cos(sdRad)) -
|
|
913
|
-
Math.tan(latRad) * Math.tan(sdRad));
|
|
914
|
-
return -hourAngle; // in radians
|
|
915
|
-
}
|
|
916
|
-
/**
|
|
917
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Elevation</a> for the
|
|
918
|
-
* horizontal coordinate system at the given location at the given time. Can be negative if the sun is below the
|
|
919
|
-
* horizon. Not corrected for altitude.
|
|
920
|
-
*
|
|
921
|
-
* @param {Temporal.ZonedDateTime} date
|
|
922
|
-
* time of calculation
|
|
923
|
-
* @param {number} lat
|
|
924
|
-
* latitude of location for calculation
|
|
925
|
-
* @param {number} lon
|
|
926
|
-
* longitude of location for calculation
|
|
927
|
-
* @return {number} solar elevation in degrees - horizon is 0 degrees, civil twilight is -6 degrees
|
|
928
|
-
*/
|
|
929
|
-
static getSolarElevation(date, lat, lon) {
|
|
930
|
-
const julianDay = NOAACalculator.getJulianDay(date.toPlainDate());
|
|
931
|
-
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
932
|
-
const equationOfTime = NOAACalculator.getEquationOfTime(julianCenturies);
|
|
933
|
-
let longitude = date.hour + 12 + (date.minute + equationOfTime + date.second / 60) / 60;
|
|
934
|
-
longitude = -((longitude * 360) / 24) % 360;
|
|
935
|
-
const hourAngleRad = degreesToRadians(lon - longitude);
|
|
936
|
-
const declination = NOAACalculator.getSunDeclination(julianCenturies);
|
|
937
|
-
const decRad = degreesToRadians(declination);
|
|
938
|
-
const latRad = degreesToRadians(lat);
|
|
939
|
-
return radiansToDegrees(Math.asin(Math.sin(latRad) * Math.sin(decRad) +
|
|
940
|
-
Math.cos(latRad) * Math.cos(decRad) * Math.cos(hourAngleRad)));
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Celestial_coordinate_system">Solar Azimuth</a> for the
|
|
944
|
-
* horizontal coordinate system at the given location at the given time. Not corrected for altitude. True south is 0
|
|
945
|
-
* degrees.
|
|
946
|
-
*
|
|
947
|
-
* @param {Temporal.ZonedDateTime} date
|
|
948
|
-
* time of calculation
|
|
949
|
-
* @param {number} latitude
|
|
950
|
-
* latitude of location for calculation
|
|
951
|
-
* @param {number} lon
|
|
952
|
-
* longitude of location for calculation
|
|
953
|
-
* @return {number}
|
|
954
|
-
*/
|
|
955
|
-
static getSolarAzimuth(date, latitude, lon) {
|
|
956
|
-
const julianDay = NOAACalculator.getJulianDay(date.toPlainDate());
|
|
957
|
-
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
958
|
-
const equationOfTime = NOAACalculator.getEquationOfTime(julianCenturies);
|
|
959
|
-
let longitude = date.hour + 12 + (date.minute + equationOfTime + date.second / 60) / 60;
|
|
960
|
-
longitude = -((longitude * 360) / 24) % 360;
|
|
961
|
-
const hourAngleRad = degreesToRadians(lon - longitude);
|
|
962
|
-
const declination = NOAACalculator.getSunDeclination(julianCenturies);
|
|
963
|
-
const decRad = degreesToRadians(declination);
|
|
964
|
-
const latRad = degreesToRadians(latitude);
|
|
965
|
-
return (radiansToDegrees(Math.atan(Math.sin(hourAngleRad) /
|
|
966
|
-
(Math.cos(hourAngleRad) * Math.sin(latRad) -
|
|
967
|
-
Math.tan(decRad) * Math.cos(latRad)))) + 180);
|
|
968
|
-
}
|
|
969
|
-
/**
|
|
970
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
971
|
-
* of sunrise for the given day at the given location on earth
|
|
972
|
-
* @private
|
|
973
|
-
* @param julianDay
|
|
974
|
-
* the Julian day
|
|
975
|
-
* @param {number} latitude
|
|
976
|
-
* the latitude of observer in degrees
|
|
977
|
-
* @param {number} longitude
|
|
978
|
-
* the longitude of observer in degrees
|
|
979
|
-
* @param {number} zenith
|
|
980
|
-
* the zenith
|
|
981
|
-
* @return the time in minutes from zero UTC
|
|
982
|
-
*/
|
|
983
|
-
static getSunriseUTC(julianDay, latitude, longitude, zenith) {
|
|
984
|
-
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
985
|
-
// Find the time of solar noon at the location, and use that declination. This is better than start of the
|
|
986
|
-
// Julian day
|
|
987
|
-
const noonmin = NOAACalculator.getSolarNoonUTC(julianCenturies, longitude);
|
|
988
|
-
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440);
|
|
989
|
-
// First pass to approximate sunrise (using solar noon)
|
|
990
|
-
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
991
|
-
let solarDec = NOAACalculator.getSunDeclination(tnoon);
|
|
992
|
-
let hourAngle = NOAACalculator.getSunHourAngleAtSunrise(latitude, solarDec, zenith);
|
|
993
|
-
let delta = longitude - radiansToDegrees(hourAngle);
|
|
994
|
-
let timeDiff = 4 * delta; // in minutes of time
|
|
995
|
-
let timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
996
|
-
// Second pass includes fractional Julian Day in gamma calc
|
|
997
|
-
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
998
|
-
timeUTC / 1440);
|
|
999
|
-
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
1000
|
-
solarDec = NOAACalculator.getSunDeclination(newt);
|
|
1001
|
-
hourAngle = NOAACalculator.getSunHourAngleAtSunrise(latitude, solarDec, zenith);
|
|
1002
|
-
delta = longitude - radiansToDegrees(hourAngle);
|
|
1003
|
-
timeDiff = 4 * delta;
|
|
1004
|
-
timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
1005
|
-
return timeUTC;
|
|
1006
|
-
}
|
|
1007
|
-
/**
|
|
1008
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
1009
|
-
* of <a href="http://en.wikipedia.org/wiki/Noon#Solar_noon">solar noon</a> for the given day at the given location
|
|
1010
|
-
* on earth.
|
|
1011
|
-
* @private
|
|
1012
|
-
* @param julianCenturies
|
|
1013
|
-
* the number of Julian centuries since J2000.0
|
|
1014
|
-
* @param {number} longitude
|
|
1015
|
-
* the longitude of observer in degrees
|
|
1016
|
-
* @return the time in minutes from zero UTC
|
|
1017
|
-
*/
|
|
1018
|
-
static getSolarNoonUTC(julianCenturies, longitude) {
|
|
1019
|
-
// First pass uses approximate solar noon to calculate eqtime
|
|
1020
|
-
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
1021
|
-
longitude / 360);
|
|
1022
|
-
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
1023
|
-
const solNoonUTC = 720 + longitude * 4 - eqTime; // min
|
|
1024
|
-
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) -
|
|
1025
|
-
0.5 +
|
|
1026
|
-
solNoonUTC / 1440);
|
|
1027
|
-
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
1028
|
-
return 720 + longitude * 4 - eqTime; // min
|
|
1029
|
-
}
|
|
1030
|
-
/**
|
|
1031
|
-
* Return the <a href="http://en.wikipedia.org/wiki/Universal_Coordinated_Time">Universal Coordinated Time</a> (UTC)
|
|
1032
|
-
* of sunset for the given day at the given location on earth
|
|
1033
|
-
* @private
|
|
1034
|
-
* @param julianDay
|
|
1035
|
-
* the Julian day
|
|
1036
|
-
* @param {number} latitude
|
|
1037
|
-
* the latitude of observer in degrees
|
|
1038
|
-
* @param {number} longitude
|
|
1039
|
-
* : longitude of observer in degrees
|
|
1040
|
-
* @param {number} zenith
|
|
1041
|
-
* the zenith
|
|
1042
|
-
* @return the time in minutes from zero Universal Coordinated Time (UTC)
|
|
1043
|
-
*/
|
|
1044
|
-
static getSunsetUTC(julianDay, latitude, longitude, zenith) {
|
|
1045
|
-
const julianCenturies = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay);
|
|
1046
|
-
// Find the time of solar noon at the location, and use that declination. This is better than start of the
|
|
1047
|
-
// Julian day
|
|
1048
|
-
const noonmin = NOAACalculator.getSolarNoonUTC(julianCenturies, longitude);
|
|
1049
|
-
const tnoon = NOAACalculator.getJulianCenturiesFromJulianDay(julianDay + noonmin / 1440);
|
|
1050
|
-
// First calculates sunrise and approx length of day
|
|
1051
|
-
let eqTime = NOAACalculator.getEquationOfTime(tnoon);
|
|
1052
|
-
let solarDec = NOAACalculator.getSunDeclination(tnoon);
|
|
1053
|
-
let hourAngle = NOAACalculator.getSunHourAngleAtSunset(latitude, solarDec, zenith);
|
|
1054
|
-
let delta = longitude - radiansToDegrees(hourAngle);
|
|
1055
|
-
let timeDiff = 4 * delta;
|
|
1056
|
-
let timeUTC = 720 + timeDiff - eqTime;
|
|
1057
|
-
// Second pass includes fractional Julian Day in gamma calc
|
|
1058
|
-
const newt = NOAACalculator.getJulianCenturiesFromJulianDay(NOAACalculator.getJulianDayFromJulianCenturies(julianCenturies) +
|
|
1059
|
-
timeUTC / 1440);
|
|
1060
|
-
eqTime = NOAACalculator.getEquationOfTime(newt);
|
|
1061
|
-
solarDec = NOAACalculator.getSunDeclination(newt);
|
|
1062
|
-
hourAngle = NOAACalculator.getSunHourAngleAtSunset(latitude, solarDec, zenith);
|
|
1063
|
-
delta = longitude - radiansToDegrees(hourAngle);
|
|
1064
|
-
timeDiff = 4 * delta;
|
|
1065
|
-
timeUTC = 720 + timeDiff - eqTime; // in minutes
|
|
1066
|
-
return timeUTC;
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
exports.NOAACalculator = NOAACalculator;
|
|
1070
|
-
/**
|
|
1071
|
-
* The zenith of astronomical sunrise and sunset. The sun is 90° from the vertical 0°
|
|
1072
|
-
* @private
|
|
1073
|
-
*/
|
|
1074
|
-
NOAACalculator.GEOMETRIC_ZENITH = 90;
|
|
1075
|
-
/**
|
|
1076
|
-
* Default value for Sun's zenith and true rise/set Zenith (used in this class and subclasses) is the angle that the
|
|
1077
|
-
* center of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the Earth
|
|
1078
|
-
* were without an atmosphere, true sunset and sunrise would correspond to a 90° zenith. Because the Sun is not
|
|
1079
|
-
* a point, and because the atmosphere refracts light, this 90° zenith does not, in fact, correspond to true
|
|
1080
|
-
* sunset or sunrise, instead the center of the Sun's disk must lie just below the horizon for the upper edge to be
|
|
1081
|
-
* obscured. This means that a zenith of just above 90° must be used. The Sun subtends an angle of 16 minutes of
|
|
1082
|
-
* arc, and atmospheric refraction accounts for
|
|
1083
|
-
* 34 minutes or so, giving a total of 50
|
|
1084
|
-
* arcminutes. The total value for ZENITH is 90+(5/6) or 90.8333333° for true sunrise/sunset.
|
|
1085
|
-
*/
|
|
1086
|
-
// const ZENITH: number = GEOMETRIC_ZENITH + 5.0 / 6.0;
|
|
1087
|
-
/** Sun's zenith at civil twilight (96°). */
|
|
1088
|
-
NOAACalculator.CIVIL_ZENITH = 96;
|
|
1089
|
-
/** Sun's zenith at nautical twilight (102°). */
|
|
1090
|
-
NOAACalculator.NAUTICAL_ZENITH = 102;
|
|
1091
|
-
/** Sun's zenith at astronomical twilight (108°). */
|
|
1092
|
-
NOAACalculator.ASTRONOMICAL_ZENITH = 108;
|
|
1093
|
-
/**
|
|
1094
|
-
* The <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> of January 1, 2000
|
|
1095
|
-
* @private
|
|
1096
|
-
*/
|
|
1097
|
-
NOAACalculator.JULIAN_DAY_JAN_1_2000 = 2451545;
|
|
1098
|
-
/**
|
|
1099
|
-
* Julian days per century
|
|
1100
|
-
* @private
|
|
1101
|
-
*/
|
|
1102
|
-
NOAACalculator.JULIAN_DAYS_PER_CENTURY = 36525;
|
|
File without changes
|