UNPKG

5.05 kBJavaScriptView Raw
1/**
2 * @copyright 2013 Sonia Keys
3 * @copyright 2016 commenthol
4 * @license MIT
5 * @module deltat
6 */
7
8/**
9 * DeltaT: Chapter 10, Dynamical Time and Universal Time.
10 *
11 * This package uses no functions from the Chapter. Polynoms are from
12 * <http://eclipse.gsfc.nasa.gov/SEcat5/deltatpoly.html>, data sets are from
13 * <http://maia.usno.navy.mil/ser7/>
14 *
15 * Functions in this package compute ΔT for various ranges of dates.
16 *
17 * ΔT = TD - UT1
18 *
19 * TD = "Dynamical Time", which is related to:
20 * ET "Ephermis Time", an older term.
21 * TDB "Barycentric Dynamical Time", very close to TD.
22 * TDT "Terrestrial Dynamical Time", a more correct term.
23 * TT "Terrestrial Time", a newer and more correct term.
24 *
25 * UT = "Universal Time", which is related (if ambiguously) to GMT "Greenwich
26 * Mean Time".
27 *
28 * Terrestrial Time is effectively equal to International Atomic Time (TAI)
29 * plus 32.184 seconds exactly: TT = TAI + 32.184
30 * The epoch designated "J2000.0" is specified as Julian date 2451545.0 TT,
31 * or 2000 January 1, 12h TT. This epoch can also be expressed as
32 * 2000 January 1, 11:59:27.816 TAI or 2000 January 1, 11:58:55.816 UTC.
33 */
34import base from './base';
35import interp from './interpolation';
36import deltat from '../data/deltat';
37import { Calendar, LeapYearGregorian } from './julian';
38/**
39 * deltaT returns the difference ΔT = TD - UT between Dynamical Time TD and
40 * Univeral Time (GMT+12) in seconds
41 *
42 * Polynoms are from <http://eclipse.gsfc.nasa.gov/SEcat5/deltatpoly.html>
43 * and <http://www.staff.science.uu.nl/~gent0113/deltat/deltat_old.htm>
44 *
45 * @param {Number} dyear - decimal year
46 * @returns {Number} ΔT in seconds.
47 */
48
49export function deltaT(dyear) {
50 var ΔT;
51
52 if (dyear < -500) {
53 ΔT = base.horner((dyear - 1820) * 0.01, -20, 0, 32);
54 } else if (dyear < 500) {
55 ΔT = base.horner(dyear * 0.01, 10583.6, -1014.41, 33.78311, -5.952053, -0.1798452, 0.022174192, 0.0090316521);
56 } else if (dyear < 1600) {
57 ΔT = base.horner((dyear - 1000) * 0.01, 1574.2, -556.01, 71.23472, 0.319781, -0.8503463, -0.005050998, 0.0083572073);
58 } else if (dyear < deltat.historic.first) {
59 ΔT = base.horner(dyear - 1600, 120, -0.9808, -0.01532, 1 / 7129);
60 } else if (dyear < deltat.data.first) {
61 ΔT = interpolate(dyear, deltat.historic);
62 } else if (dyear < deltat.data.last - 0.25) {
63 // -0.25 ~= do not consider last 3 months in dataset
64 ΔT = interpolateData(dyear, deltat.data);
65 } else if (dyear < deltat.prediction.last) {
66 ΔT = interpolate(dyear, deltat.prediction);
67 } else if (dyear < 2050) {
68 ΔT = base.horner((dyear - 2000) / 100, 62.92, 32.217, 55.89);
69 } else if (dyear < 2150) {
70 ΔT = base.horner((dyear - 1820) / 100, -205.72, 56.28, 32);
71 } else {
72 var u = (dyear - 1820) / 100;
73 ΔT = -20 + 32 * u * u;
74 }
75
76 return ΔT;
77}
78/**
79 * interpolation of dataset
80 * @private
81 * @param {Number} dyear - julian year
82 * @returns {Number} ΔT in seconds.
83 */
84
85function interpolate(dyear, data) {
86 var d3 = interp.len3ForInterpolateX(dyear, data.first, data.last, data.table);
87 return d3.interpolateX(dyear);
88}
89/**
90 * interpolation of dataset from finals2000A with is one entry per month
91 * linear interpolation over whole dataset is inaccurate as points per month
92 * are not equidistant. Therefore points are approximated using 2nd diff. interpolation
93 * from current month using the following two points
94 *
95 * @private
96 * @param {Number} dyear - julian year
97 * @returns {Number} ΔT in seconds.
98 */
99
100
101function interpolateData(dyear, data) {
102 var _data$firstYM = data.firstYM,
103 fyear = _data$firstYM[0],
104 fmonth = _data$firstYM[1];
105
106 var _monthOfYear = monthOfYear(dyear),
107 year = _monthOfYear.year,
108 month = _monthOfYear.month,
109 first = _monthOfYear.first,
110 last = _monthOfYear.last;
111
112 var pos = 12 * (year - fyear) + (month - fmonth);
113 var table = data.table.slice(pos, pos + 3);
114 var d3 = new interp.Len3(first, last, table);
115 return d3.interpolateX(dyear);
116}
117/**
118* Get month of Year from fraction. Fraction differs at leap years.
119* @private
120* @param {Number} dyear - decimal year
121* @return {Object} `{year: Number, month: Number, first: Number, last}`
122*/
123
124
125function monthOfYear(dyear) {
126 if (!monthOfYear.data) {
127 // memoize yearly fractions per month
128 monthOfYear.data = {
129 0: [],
130 1: []
131 };
132
133 for (var m = 0; m <= 12; m++) {
134 monthOfYear.data[0][m] = new Calendar(1999, m, 1).toYear() - 1999; // non leap year
135
136 monthOfYear.data[1][m] = new Calendar(2000, m, 1).toYear() - 2000; // leap year
137 }
138 }
139
140 var year = dyear | 0;
141 var f = dyear - year;
142 var d = LeapYearGregorian(year) ? 1 : 0;
143 var data = monthOfYear.data[d];
144 var month = 12; // TODO loop could be improved
145
146 while (month > 0 && data[month] > f) {
147 month--;
148 }
149
150 var first = year + data[month];
151 var last = month < 11 ? year + data[month + 2] : year + 1 + data[(month + 2) % 12];
152 return {
153 year: year,
154 month: month,
155 first: first,
156 last: last
157 };
158}
159
160export default {
161 deltaT: deltaT
162};
\No newline at end of file