00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "scitime.h"
00022
00023 typedef struct _TAItoUTC_data {
00024 double epochJD;
00025 double leapSeconds;
00026 double fact1;
00027 double fact2;
00028 } TAItoUTC_data;
00029
00030
00031 static const TAItoUTC_data _tai_to_utc[] = {
00032 { 2453736.5 , 33.0 , 41317.0 , 0.0 },
00033 { 2451179.5 , 32.0 , 41317.0 , 0.0 },
00034 { 2450630.5 , 31.0 , 41317.0 , 0.0 },
00035 { 2450083.5 , 30.0 , 41317.0 , 0.0 },
00036 { 2449534.5 , 29.0 , 41317.0 , 0.0 },
00037 { 2449169.5 , 28.0 , 41317.0 , 0.0 },
00038 { 2448804.5 , 27.0 , 41317.0 , 0.0 },
00039 { 2448257.5 , 26.0 , 41317.0 , 0.0 },
00040 { 2447892.5 , 25.0 , 41317.0 , 0.0 },
00041 { 2447161.5 , 24.0 , 41317.0 , 0.0 },
00042 { 2446247.5 , 23.0 , 41317.0 , 0.0 },
00043 { 2445516.5 , 22.0 , 41317.0 , 0.0 },
00044 { 2445151.5 , 21.0 , 41317.0 , 0.0 },
00045 { 2444786.5 , 20.0 , 41317.0 , 0.0 },
00046 { 2444239.5 , 19.0 , 41317.0 , 0.0 },
00047 { 2443874.5 , 18.0 , 41317.0 , 0.0 },
00048 { 2443509.5 , 17.0 , 41317.0 , 0.0 },
00049 { 2443144.5 , 16.0 , 41317.0 , 0.0 },
00050 { 2442778.5 , 15.0 , 41317.0 , 0.0 },
00051 { 2442413.5 , 14.0 , 41317.0 , 0.0 },
00052 { 2442048.5 , 13.0 , 41317.0 , 0.0 },
00053 { 2441683.5 , 12.0 , 41317.0 , 0.0 },
00054 { 2441499.5 , 11.0 , 41317.0 , 0.0 },
00055 { 2441317.5 , 10.0 , 41317.0 , 0.0 },
00056 { 2439887.5 , 4.21317 , 39126.0 , 0.002592 },
00057 { 2439126.5 , 4.31317 , 39126.0 , 0.002592 },
00058 { 2439004.5 , 3.84013 , 38761.0 , 0.001296 },
00059 { 2438942.5 , 3.74013 , 38761.0 , 0.001296 },
00060 { 2438820.5 , 3.64013 , 38761.0 , 0.001296 },
00061 { 2438761.5 , 3.54013 , 38761.0 , 0.001296 },
00062 { 2438639.5 , 3.44013 , 38761.0 , 0.001296 },
00063 { 2438486.5 , 3.34013 , 38761.0 , 0.001296 },
00064 { 2438395.5 , 3.24013 , 38761.0 , 0.001296 },
00065 { 2438334.5 , 1.945858, 37665.0 , 0.0011232 },
00066 { 2437665.5 , 1.845858, 37665.0 , 0.0011232 },
00067 { 2437512.5 , 1.372818, 37300.0 , 0.001296 },
00068 { 2437300.5 , 1.422818, 37300.0 , 0.001296 },
00069 { NAN , 0.0 , 0.0, 0.0 }
00070 };
00071
00072 static double _sct_get_leapseconds_from_epoch(sct_time_ptr pElem);
00073
00074
00075 SCT_TIMESCALE sct_get_timescale (sct_time_ptr pElem)
00076 {
00077 return pElem->timescale;
00078 }
00079
00080 SCT_RET sct_set_timescale (sct_time_ptr pElem, SCT_TIMESCALE timescale)
00081 {
00082 pElem->timescale = timescale;
00083 return SCT_RET_OK;
00084 }
00085
00086 SCT_RET sct_from_TAI_to_UTC (sct_time_ptr pElem)
00087 {
00088 double leapseconds;
00089 sct_time delta;
00090 #ifdef SCT_DEBUG
00091 if(pElem->timescale != SCT_TIMESCALE_TAI)
00092 {
00093 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from TAI to"
00094 "UTC a time element which is NOT TAI.\n", __FUNCTION__);
00095 }
00096 #endif
00097
00098
00099 leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00100 if(isnan(leapseconds))
00101 {
00102 return SCT_RET_INVALID_LEAPSECONDS;
00103 }
00104 leapseconds *= (-1.0);
00105
00106
00107 sct_set_delta_secs(&delta,leapseconds);
00108
00109
00110 sct_add_delta(pElem,pElem,&delta);
00111
00112
00113 pElem->timescale = SCT_TIMESCALE_UTC;
00114
00115 return SCT_RET_OK;
00116 }
00117
00118
00119 SCT_RET sct_from_TAI_to_GPS (sct_time_ptr pElem)
00120 {
00121 #ifdef SCT_DEBUG
00122 if(pElem->timescale != SCT_TIMESCALE_TAI)
00123 {
00124 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from TAI to"
00125 "GPS a time element which is NOT TAI.\n", __FUNCTION__);
00126 }
00127 #endif
00128
00129
00130
00131 sct_add_deltaDSF(pElem,pElem,0,-SCT_GPS_TAI_LEAPSECOND,0);
00132
00133
00134 pElem->timescale = SCT_TIMESCALE_GPS;
00135
00136 return SCT_RET_OK;
00137 }
00138
00139
00140 SCT_RET sct_from_TAI_to_UT (sct_time_ptr pElem)
00141 {
00142 #ifdef SCT_DEBUG
00143 if(pElem->timescale != SCT_TIMESCALE_TAI)
00144 {
00145 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from TAI to"
00146 "UT a time element which is NOT TAI.\n", __FUNCTION__);
00147 }
00148 #endif
00149
00150
00151 pElem->timescale = SCT_TIMESCALE_UT;
00152
00153 return SCT_RET_OK;
00154 }
00155
00156
00157 SCT_RET sct_from_UTC_to_TAI (sct_time_ptr pElem)
00158 {
00159 double leapseconds;
00160 sct_time delta;
00161
00162 #ifdef SCT_DEBUG
00163 if(pElem->timescale != SCT_TIMESCALE_UTC)
00164 {
00165 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UTC to"
00166 "TAI a time element which is NOT UTC.\n", __FUNCTION__);
00167 }
00168 #endif
00169
00170
00171 leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00172 if(isnan(leapseconds))
00173 {
00174 return SCT_RET_INVALID_LEAPSECONDS;
00175 }
00176
00177
00178 sct_set_delta_secs(&delta,leapseconds);
00179
00180
00181 sct_add_delta(pElem,pElem,&delta);
00182
00183
00184 pElem->timescale = SCT_TIMESCALE_TAI;
00185
00186 return SCT_RET_OK;
00187 }
00188
00189
00190 SCT_RET sct_from_UTC_to_GPS (sct_time_ptr pElem)
00191 {
00192 double leapseconds;
00193 sct_time delta;
00194
00195 #ifdef SCT_DEBUG
00196 if(pElem->timescale != SCT_TIMESCALE_UTC)
00197 {
00198 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UTC to"
00199 "GPS a time element which is NOT UTC.\n", __FUNCTION__);
00200 }
00201 #endif
00202
00203
00204 leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00205 if(isnan(leapseconds))
00206 {
00207 return SCT_RET_INVALID_LEAPSECONDS;
00208 }
00209
00210
00211 sct_set_delta_secs(&delta,leapseconds);
00212
00213
00214 sct_add_delta(pElem,pElem,&delta);
00215
00216
00217
00218 sct_add_deltaDSF(pElem,pElem,0,-SCT_GPS_TAI_LEAPSECOND,0);
00219
00220
00221 pElem->timescale = SCT_TIMESCALE_GPS;
00222
00223 return SCT_RET_OK;
00224 }
00225
00226
00227 SCT_RET sct_from_UTC_to_UT (sct_time_ptr pElem)
00228 {
00229 #ifdef SCT_DEBUG
00230 if(pElem->timescale != SCT_TIMESCALE_UTC)
00231 {
00232 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UTC to"
00233 "UT a time element which is NOT UTC.\n", __FUNCTION__);
00234 }
00235 #endif
00236
00237
00238 pElem->timescale = SCT_TIMESCALE_UT;
00239
00240 return SCT_RET_OK;
00241 }
00242
00243
00244 SCT_RET sct_from_GPS_to_TAI (sct_time_ptr pElem)
00245 {
00246 #ifdef SCT_DEBUG
00247 if(pElem->timescale != SCT_TIMESCALE_GPS)
00248 {
00249 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from GPS to"
00250 "TAI a time element which is NOT GPS.\n", __FUNCTION__);
00251 }
00252 #endif
00253
00254
00255
00256 sct_add_deltaDSF(pElem,pElem,0,SCT_GPS_TAI_LEAPSECOND,0);
00257
00258
00259 pElem->timescale = SCT_TIMESCALE_TAI;
00260
00261 return SCT_RET_OK;
00262 }
00263
00264
00265 SCT_RET sct_from_GPS_to_UTC (sct_time_ptr pElem)
00266 {
00267 double leapseconds;
00268 sct_time delta;
00269
00270 #ifdef SCT_DEBUG
00271 if(pElem->timescale != SCT_TIMESCALE_GPS)
00272 {
00273 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from GPS to"
00274 "UTC a time element which is NOT GPS.\n", __FUNCTION__);
00275 }
00276 #endif
00277
00278
00279
00280 sct_add_deltaDSF(pElem,pElem,0,SCT_GPS_TAI_LEAPSECOND,0);
00281
00282
00283 leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00284 if(isnan(leapseconds))
00285 {
00286 return SCT_RET_INVALID_LEAPSECONDS;
00287 }
00288 leapseconds *= (-1.0);
00289
00290
00291 sct_set_delta_secs(&delta,leapseconds);
00292
00293
00294 sct_add_delta(pElem,pElem,&delta);
00295
00296
00297 pElem->timescale = SCT_TIMESCALE_UTC;
00298
00299 return SCT_RET_OK;
00300 }
00301
00302
00303 SCT_RET sct_from_GPS_to_UT (sct_time_ptr pElem)
00304 {
00305 #ifdef SCT_DEBUG
00306 if(pElem->timescale != SCT_TIMESCALE_GPS)
00307 {
00308 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from GPS to"
00309 "UT a time element which is NOT GPS.\n", __FUNCTION__);
00310 }
00311 #endif
00312
00313
00314 pElem->timescale = SCT_TIMESCALE_UT;
00315
00316 return SCT_RET_OK;
00317 }
00318
00319
00320 SCT_RET sct_from_UT_to_TAI (sct_time_ptr pElem)
00321 {
00322 #ifdef SCT_DEBUG
00323 if(pElem->timescale != SCT_TIMESCALE_UT)
00324 {
00325 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UT to"
00326 "TAI a time element which is NOT UT.\n", __FUNCTION__);
00327 }
00328 #endif
00329
00330
00331 pElem->timescale = SCT_TIMESCALE_TAI;
00332
00333 return SCT_RET_OK;
00334 }
00335
00336
00337 SCT_RET sct_from_UT_to_GPS (sct_time_ptr pElem)
00338 {
00339 #ifdef SCT_DEBUG
00340 if(pElem->timescale != SCT_TIMESCALE_UT)
00341 {
00342 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UT to"
00343 "GPS a time element which is NOT UT.\n", __FUNCTION__);
00344 }
00345 #endif
00346
00347
00348 pElem->timescale = SCT_TIMESCALE_GPS;
00349
00350 return SCT_RET_OK;
00351 }
00352
00353
00354 SCT_RET sct_from_UT_to_UTC (sct_time_ptr pElem)
00355 {
00356 #ifdef SCT_DEBUG
00357 if(pElem->timescale != SCT_TIMESCALE_UT)
00358 {
00359 fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UT to"
00360 "UTC a time element which is NOT UT.\n", __FUNCTION__);
00361 }
00362 #endif
00363
00364
00365 pElem->timescale = SCT_TIMESCALE_UTC;
00366
00367 return SCT_RET_OK;
00368 }
00369
00370
00371 static double _sct_get_leapseconds_from_epoch(sct_time_ptr pElem)
00372 {
00373 extern const TAItoUTC_data _tai_to_utc[];
00374 int ind = 0;
00375 double elementJD;
00376
00377
00378 sct_get_jd(pElem,&elementJD);
00379
00380
00381 while(!isnan(_tai_to_utc[ind].epochJD))
00382 {
00383
00384 if(elementJD > _tai_to_utc[ind].epochJD)
00385 {
00386
00387 if(_tai_to_utc[ind].fact2 == 0.0)
00388 return _tai_to_utc[ind].leapSeconds;
00389 else
00390 {
00391 double elementMJD;
00392 sct_get_mjd(pElem,&elementMJD);
00393 return ( _tai_to_utc[ind].leapSeconds + \
00394 (elementMJD - _tai_to_utc[ind].fact1) * \
00395 _tai_to_utc[ind].fact2);
00396 }
00397 }
00398
00399 ind++;
00400 }
00401
00402 return NAN;
00403 }
00404