1 /* 2 * This library is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU Lesser General Public 4 * License as published by the Free Software Foundation; either 5 * version 2 of the License, or (at your option) any later version. 6 * 7 * This library is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * Lesser General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 * 16 * Copyright (C) 2000 - 2005 Liam Girdwood <lgirdwood@gmail.com> 17 */ 18 19 module nova.dynamical_time; 20 21 import std.stdio; 22 23 enum TERMS = 192; 24 25 struct year_TD 26 { 27 int year; 28 double TD; 29 } 30 31 extern (C) { 32 33 /* Stephenson and Houlden for years prior to 948 A.D.*/ 34 // static double get_dynamical_diff_sh1(double JD); 35 36 /* Stephenson and Houlden for years between 948 A.D. and 1600 A.D.*/ 37 // static double get_dynamical_diff_sh2(double JD); 38 39 /* Table 9.a pg 72 for years 1620..1992.*/ 40 // static double get_dynamical_diff_table(double JD); 41 42 /* get the dynamical time diff in the near past / future 1992 .. 2010 */ 43 // static double get_dynamical_diff_near(double JD); 44 45 /* uses equation 9.1 pg 73 to calc JDE for othe JD values */ 46 // static double get_dynamical_diff_other(double JD); 47 48 } 49 50 /* dynamical time in seconds for every second year from 1620 to 1992 */ 51 const static double[TERMS] delta_t = 52 [ 124.0, 115.0, 106.0, 98.0, 91.0, 53 85.0, 79.0, 74.0, 70.0, 65.0, 54 62.0, 58.0, 55.0, 53.0, 50.0, 55 48.0, 46.0, 44.0, 42.0, 40.0, 56 37.0, 35.0, 33.0, 31.0, 28.0, 57 26.0, 24.0, 22.0, 20.0, 18.0, 58 16.0, 14.0, 13.0, 12.0, 11.0, 59 10.0, 9.0, 9.0, 9.0, 9.0, 60 9.0, 9.0, 9.0, 9.0, 10.0, 61 10.0, 10.0, 10.0, 10.0, 11.0, 62 11.0, 11.0, 11.0, 11.0, 11.0, 63 11.0, 12.0, 12.0, 12.0, 12.0, 64 12.0, 12.0, 13.0, 13.0, 13.0, 65 13.0, 14.0, 14.0, 14.0, 15.0, 66 15.0, 15.0, 15.0, 16.0, 16.0, 67 16.0, 16.0, 16.0, 17.0, 17.0, 68 17.0, 17.0, 17.0, 17.0, 17.0, 69 17.0, 16.0, 16.0, 15.0, 14.0, 70 13.7, 13.1, 12.7, 12.5, 12.5, 71 12.5, 12.5, 12.5, 12.5, 12.3, 72 12.0, 11.4, 10.6, 9.6, 8.6, 73 7.5, 6.6, 6.0, 5.7, 5.6, 74 5.7, 5.9, 6.2, 6.5, 6.8, 75 7.1, 7.3, 7.5, 7.7, 7.8, 76 7.9, 7.5, 6.4, 5.4, 2.9, 77 1.6, -1.0, -2.7, -3.6, -4.7, 78 -5.4, -5.2, -5.5, -5.6, -5.8, 79 -5.9, -6.2, -6.4, -6.1, -4.7, 80 -2.7, 0.0, 2.6, 5.4, 7.7, 81 10.5, 13.4, 16.0, 18.2, 20.2, 82 21.2, 22.4, 23.5, 23.9, 24.3, 83 24.0, 23.9, 23.9, 23.7, 24.0, 84 24.3, 25.3, 26.2, 27.3, 28.2, 85 29.1, 30.0, 30.7, 31.4, 32.2, 86 33.1, 34.0, 35.0, 36.5, 38.3, 87 40.2, 42.2, 44.5, 46.5, 48.5, 88 50.5, 52.2, 53.8, 54.9, 55.8, 89 56.9, 58.3 90 ]; 91 92 extern (C) { 93 94 /* Stephenson and Houlden for years prior to 948 A.D.*/ 95 static @nogc double get_dynamical_diff_sh1(double JD) nothrow 96 { 97 double TD,E; 98 99 /* number of centuries from 948 */ 100 E =(JD - 2067314.5) / 36525.0; 101 102 TD = 1830.0 - 405.0 * E + 46.5 * E * E; 103 return TD; 104 } 105 106 /* Stephenson and Houlden for years between 948 A.D. and 1600 A.D.*/ 107 static @nogc double get_dynamical_diff_sh2(double JD) nothrow 108 { 109 double TD,t; 110 111 /* number of centuries from 1850 */ 112 t =(JD - 2396758.5) / 36525.0; 113 114 TD = 22.5 * t * t; 115 return TD; 116 } 117 118 /* Table 9.a pg 72 for years 1600..1992.*/ 119 /* uses interpolation formula 3.3 on pg 25 */ 120 static @nogc double get_dynamical_diff_table(double JD) nothrow 121 { 122 double TD = 0; 123 double a,b,c,n; 124 int i; 125 126 /* get no days since 1620 and divide by 2 years */ 127 i = cast(int)((JD - 2312752.5) / 730.5); 128 129 /* get the base interpolation factor in the table */ 130 if (i > (TERMS - 2)) 131 i = TERMS - 2; 132 133 /* calc a,b,c,n */ 134 a = delta_t[i+1] - delta_t[i]; 135 b = delta_t[i+2] - delta_t[i+1]; 136 c = a - b; 137 n = ((JD - (2312752.5 + (730.5 * i))) / 730.5); 138 139 TD = delta_t[i + 1] + n / 2 * (a + b + n * c); 140 141 return TD; 142 } 143 144 /* get the dynamical time diff in the near past / future 1992 .. 2010 */ 145 /* uses interpolation formula 3.3 on pg 25 */ 146 static @nogc double get_dynamical_diff_near(double JD) nothrow 147 { 148 double TD = 0; 149 /* TD for 1990, 2000, 2010 */ 150 double[3] delta_T = [56.86, 63.83, 70.0]; 151 double a,b,c,n; 152 153 /* calculate TD by interpolating value */ 154 a = delta_T[1] - delta_T[0]; 155 b = delta_T[2] - delta_T[1]; 156 c = b - a; 157 158 /* get number of days since 2000 and divide by 10 years */ 159 n =(JD - 2451544.5) / 3652.5; 160 TD = delta_T[1] + (n / 2) * (a + b + n * c); 161 162 return TD; 163 } 164 165 /* uses equation 9.1 pg 73 to calc JDE for other JD values */ 166 static @nogc double get_dynamical_diff_other(double JD) nothrow 167 { 168 double TD, a; 169 170 a = (JD - 2382148.0); 171 a *= a; 172 173 TD = -15.0 + a / 41048480.0; 174 175 return TD; 176 } 177 178 /*! \fn double ln_get_dynamical_time_diff(double JD) 179 * \param JD Julian Day 180 * \return TD 181 * 182 * Calculates the dynamical time (TD) difference in seconds (delta T) from 183 * universal time. 184 */ 185 /* Equation 9.1 on pg 73. 186 */ 187 @nogc double ln_get_dynamical_time_diff(double JD) nothrow 188 { 189 double TD; 190 191 /* check when JD is, and use corresponding formula */ 192 /* check for date < 948 A.D. */ 193 if (JD < 2067314.5) 194 /* Stephenson and Houlden */ 195 TD = get_dynamical_diff_sh1(JD); 196 else if (JD >= 2067314.5 && JD < 2305447.5) 197 /* check for date 948..1600 A.D. Stephenson and Houlden */ 198 TD = get_dynamical_diff_sh2(JD); 199 else if (JD >= 2312752.5 && JD < 2448622.5) 200 /* check for value in table 1620..1992 interpolation of table */ 201 TD = get_dynamical_diff_table(JD); 202 else if (JD >= 2448622.5 && JD <= 2455197.5) 203 /* check for near future 1992..2010 interpolation */ 204 TD = get_dynamical_diff_near(JD); 205 else 206 /* other time period outside */ 207 TD = get_dynamical_diff_other(JD); 208 209 return TD; 210 } 211 212 213 /*! \fn double ln_get_jde(double JD) 214 * \param JD Julian Day 215 * \return Julian Ephemeris day 216 * 217 * Calculates the Julian Ephemeris Day(JDE) from the given julian day 218 */ 219 220 @nogc double ln_get_jde(double JD) nothrow 221 { 222 double JDE; 223 double secs_in_day = 24.0 * 60.0 * 60.0; 224 225 JDE = JD + ln_get_dynamical_time_diff(JD) / secs_in_day; 226 227 return JDE; 228 } 229 230 }