Changeset 1614
- Timestamp:
- Aug 24, 2004, 3:37:45 PM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 4 edited
-
astro/psTime.c (modified) (11 diffs)
-
astro/psTime.h (modified) (3 diffs)
-
astronomy/psTime.c (modified) (11 diffs)
-
astronomy/psTime.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astro/psTime.c
r1598 r1614 1 2 1 /** @file psTime.c 3 2 * … … 7 6 * A collection of functions are required by psLib to manipulate time data. These functions primarily consist 8 7 * of conversions between specific time formats. PSLib currently uses the UNIX timeval time system as the 9 * base upon which International Atomic Time (TAI) time is calculated. TAI time varies over time due to the 10 * earth's rotation and the movement of the continental plates. It is currentls 32 seconds faster than 11 * UTC/timeval time. 8 * base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI 9 * time varies over time due to the earth's rotation and the movement of the continental plates. It is 10 * currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates 11 * is given in the table below, which comes from: 12 * 13 * ftp://maia.usno.navy.mil/ser7/tai-utc.dat 14 * 15 * This table is placed into a static array and used by the psTime functions for conversions. 16 * 17 * 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + (MJD - 37300.) X 0.001296 S 18 * 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + (MJD - 37300.) X 0.001296 S 19 * 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + (MJD - 37665.) X 0.0011232S 20 * 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + (MJD - 37665.) X 0.0011232S 21 * 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + (MJD - 38761.) X 0.001296 S 22 * 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + (MJD - 38761.) X 0.001296 S 23 * 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + (MJD - 38761.) X 0.001296 S 24 * 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + (MJD - 38761.) X 0.001296 S 25 * 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + (MJD - 38761.) X 0.001296 S 26 * 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + (MJD - 38761.) X 0.001296 S 27 * 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + (MJD - 38761.) X 0.001296 S 28 * 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + (MJD - 39126.) X 0.002592 S 29 * 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + (MJD - 39126.) X 0.002592 S 30 * 1972 JAN 1 =JD 2441317.5 TAI-UTC= 10.0 S + (MJD - 41317.) X 0.0 S 31 * 1972 JUL 1 =JD 2441499.5 TAI-UTC= 11.0 S + (MJD - 41317.) X 0.0 S 32 * 1973 JAN 1 =JD 2441683.5 TAI-UTC= 12.0 S + (MJD - 41317.) X 0.0 S 33 * 1974 JAN 1 =JD 2442048.5 TAI-UTC= 13.0 S + (MJD - 41317.) X 0.0 S 34 * 1975 JAN 1 =JD 2442413.5 TAI-UTC= 14.0 S + (MJD - 41317.) X 0.0 S 35 * 1976 JAN 1 =JD 2442778.5 TAI-UTC= 15.0 S + (MJD - 41317.) X 0.0 S 36 * 1977 JAN 1 =JD 2443144.5 TAI-UTC= 16.0 S + (MJD - 41317.) X 0.0 S 37 * 1978 JAN 1 =JD 2443509.5 TAI-UTC= 17.0 S + (MJD - 41317.) X 0.0 S 38 * 1979 JAN 1 =JD 2443874.5 TAI-UTC= 18.0 S + (MJD - 41317.) X 0.0 S 39 * 1980 JAN 1 =JD 2444239.5 TAI-UTC= 19.0 S + (MJD - 41317.) X 0.0 S 40 * 1981 JUL 1 =JD 2444786.5 TAI-UTC= 20.0 S + (MJD - 41317.) X 0.0 S 41 * 1982 JUL 1 =JD 2445151.5 TAI-UTC= 21.0 S + (MJD - 41317.) X 0.0 S 42 * 1983 JUL 1 =JD 2445516.5 TAI-UTC= 22.0 S + (MJD - 41317.) X 0.0 S 43 * 1985 JUL 1 =JD 2446247.5 TAI-UTC= 23.0 S + (MJD - 41317.) X 0.0 S 44 * 1988 JAN 1 =JD 2447161.5 TAI-UTC= 24.0 S + (MJD - 41317.) X 0.0 S 45 * 1990 JAN 1 =JD 2447892.5 TAI-UTC= 25.0 S + (MJD - 41317.) X 0.0 S 46 * 1991 JAN 1 =JD 2448257.5 TAI-UTC= 26.0 S + (MJD - 41317.) X 0.0 S 47 * 1992 JUL 1 =JD 2448804.5 TAI-UTC= 27.0 S + (MJD - 41317.) X 0.0 S 48 * 1993 JUL 1 =JD 2449169.5 TAI-UTC= 28.0 S + (MJD - 41317.) X 0.0 S 49 * 1994 JUL 1 =JD 2449534.5 TAI-UTC= 29.0 S + (MJD - 41317.) X 0.0 S 50 * 1996 JAN 1 =JD 2450083.5 TAI-UTC= 30.0 S + (MJD - 41317.) X 0.0 S 51 * 1997 JUL 1 =JD 2450630.5 TAI-UTC= 31.0 S + (MJD - 41317.) X 0.0 S 52 * 1999 JAN 1 =JD 2451179.5 TAI-UTC= 32.0 S + (MJD - 41317.) X 0.0 S 12 53 * 13 54 * @author Ross Harman, MHPCC 14 55 * 15 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $16 * @date $Date: 2004-08- 19 18:57:49$56 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 57 * @date $Date: 2004-08-25 01:37:34 $ 17 58 * 18 59 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 26 67 #include "psError.h" 27 68 #include "psMemory.h" 28 29 /******************************************************************************/ 30 /* DEFINE STATEMENTS */ 31 /******************************************************************************/ 32 /******************************************************************************/ 33 /* DEFINE STATEMENTS */ 34 /******************************************************************************/ 35 36 // None 37 38 /******************************************************************************/ 39 /* TYPE DEFINITIONS */ 40 /******************************************************************************/ 41 42 // None 43 44 /*****************************************************************************/ 45 /* GLOBAL VARIABLES */ 46 /*****************************************************************************/ 47 48 // None 49 50 /*****************************************************************************/ 51 /* FILE STATIC VARIABLES */ 52 /*****************************************************************************/ 53 54 // None 55 56 /*****************************************************************************/ 57 /* FUNCTION IMPLEMENTATION - LOCAL */ 58 /*****************************************************************************/ 59 60 /******************************************************************************/ 61 /* DEFINE STATEMENTS */ 62 /******************************************************************************/ 69 #include "psAbort.h" 70 63 71 64 72 /** Number of available leapsecond updates */ 65 #define NUM_ LEAPSECOND_UPDATES 2373 #define NUM_UPDATES 36 66 74 67 75 /** Maximum length of time string */ … … 83 91 #define USEC_PER_DAY 86400000000.0 84 92 85 /** Preprocessor macro to generate error for negative time instruct */86 #define CHECK_N EGATIVE_TIME_STRUCT(NAME,RETURN)\87 if( NAME.tv_sec < 0) {\88 psError(__func__,"N egative seconds are not allowed: %ld", NAME.tv_sec);\93 /** Preprocessor macro to check for null psTime struct */ 94 #define CHECK_NULL_TIME(TIME,RETURN) \ 95 if(TIME == NULL) { \ 96 psError(__func__,"NULL value not allowed"); \ 89 97 return RETURN; \ 90 } else if(NAME.tv_usec<0) { \ 91 psError(__func__,"Negative microseconds are not allowed: %ld", NAME.tv_usec); \ 92 return RETURN; \ 93 } 94 95 /** Preprocessor macro to generate error for negative time */ 96 #define CHECK_NEGATIVE_TIME(NAME,RETURN) \ 97 if(NAME < 0.0) { \ 98 psError(__func__,"Negative time is not allowed: %f", NAME); \ 99 return RETURN; \ 100 } \ 101 102 /* The table below comes from http://tycho.usno.navy.mil/leapsec.html, which reports the current state of 103 the TAI/UTC leapsecond conversion times. This table is placed into a two dimensional array and used by 104 the psTimeGetTime() function to calculate TAI time from UTC time. 105 106 1972 JAN 1 = JD 2441317.5 TAI-UTC = 10.0 107 1972 JUL 1 = JD 2441499.5 TAI-UTC = 11.0 108 1973 JAN 1 = JD 2441683.5 TAI-UTC = 12.0 109 1974 JAN 1 = JD 2442048.5 TAI-UTC = 13.0 110 1975 JAN 1 = JD 2442413.5 TAI-UTC = 14.0 111 1976 JAN 1 = JD 2442778.5 TAI-UTC = 15.0 112 1977 JAN 1 = JD 2443144.5 TAI-UTC = 16.0 113 1978 JAN 1 = JD 2443509.5 TAI-UTC = 17.0 114 1979 JAN 1 = JD 2443874.5 TAI-UTC = 18.0 115 1980 JAN 1 = JD 2444239.5 TAI-UTC = 19.0 116 1981 JUL 1 = JD 2444786.5 TAI-UTC = 20.0 117 1982 JUL 1 = JD 2445151.5 TAI-UTC = 21.0 118 1983 JUL 1 = JD 2445516.5 TAI-UTC = 22.0 119 1985 JUL 1 = JD 2446247.5 TAI-UTC = 23.0 120 1988 JAN 1 = JD 2447161.5 TAI-UTC = 24.0 121 1990 JAN 1 = JD 2447892.5 TAI-UTC = 25.0 122 1991 JAN 1 = JD 2448257.5 TAI-UTC = 26.0 123 1992 JUL 1 = JD 2448804.5 TAI-UTC = 27.0 124 1993 JUL 1 = JD 2449169.5 TAI-UTC = 28.0 125 1994 JUL 1 = JD 2449534.5 TAI-UTC = 29.0 126 1996 JAN 1 = JD 2450083.5 TAI-UTC = 30.0 127 1997 JUL 1 = JD 2450630.5 TAI-UTC = 31.0 128 1999 JAN 1 = JD 2451179.5 TAI-UTC = 32.0 98 } 99 100 /** Preprocessor macro to allocate psTime strict */ 101 #define ALLOC_TIME(TIME) \ 102 TIME = (psTime*)psAlloc(sizeof(psTime)); \ 103 if (TIME == NULL) { \ 104 psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); \ 105 } 106 107 /* 108 The table below comes from ftp://maia.usno.navy.mil/ser7/tai-utc.dat, which reports the current state of 109 the TAI/UTC leapsecond conversion times. 129 110 */ 130 static double leapseconds[NUM_LEAPSECOND_UPDATES][2] = { 131 {2441317.5, 10.0}, 132 {2441499.5, 11.0}, 133 {2441683.5, 12.0}, 134 {2442048.5, 13.0}, 135 {2442413.5, 14.0}, 136 {2442778.5, 15.0}, 137 {2443144.5, 16.0}, 138 {2443509.5, 17.0}, 139 {2443874.5, 18.0}, 140 {2444239.5, 19.0}, 141 {2444786.5, 20.0}, 142 {2445151.5, 21.0}, 143 {2445516.5, 22.0}, 144 {2446247.5, 23.0}, 145 {2447161.5, 24.0}, 146 {2447892.5, 25.0}, 147 {2448257.5, 26.0}, 148 {2448804.5, 27.0}, 149 {2449169.5, 28.0}, 150 {2449534.5, 29.0}, 151 {2450083.5, 30.0}, 152 {2450630.5, 31.0}, 153 {2451179.5, 32.0} 154 }; 155 156 psTime psTimeGetTime(void) 111 static double lsTable[NUM_UPDATES][4] = { 112 {2437300.5, 1.422818, 37300.0, 0.0012960}, 113 {2437512.5, 1.372818, 37300.0, 0.0012960}, 114 {2437665.5, 1.845858, 37665.0, 0.0011232}, 115 {2438334.5, 1.945858, 37665.0, 0.0011232}, 116 {2438395.5, 3.240130, 38761.0, 0.0012960}, 117 {2438486.5, 3.340130, 38761.0, 0.0012960}, 118 {2438639.5, 3.440130, 38761.0, 0.0012960}, 119 {2438761.5, 3.540130, 38761.0, 0.0012960}, 120 {2438820.5, 3.640130, 38761.0, 0.0012960}, 121 {2438942.5, 3.740130, 38761.0, 0.0012960}, 122 {2439004.5, 3.840130, 38761.0, 0.0012960}, 123 {2439126.5, 4.313170, 39126.0, 0.0025920}, 124 {2439887.5, 4.213170, 39126.0, 0.0025920}, 125 {2441317.5, 10.000000, 41317.0, 0.0000000}, 126 {2441499.5, 11.000000, 41317.0, 0.0000000}, 127 {2441683.5, 12.000000, 41317.0, 0.0000000}, 128 {2442048.5, 13.000000, 41317.0, 0.0000000}, 129 {2442413.5, 14.000000, 41317.0, 0.0000000}, 130 {2442778.5, 15.000000, 41317.0, 0.0000000}, 131 {2443144.5, 16.000000, 41317.0, 0.0000000}, 132 {2443509.5, 17.000000, 41317.0, 0.0000000}, 133 {2443874.5, 18.000000, 41317.0, 0.0000000}, 134 {2444239.5, 19.000000, 41317.0, 0.0000000}, 135 {2444786.5, 20.000000, 41317.0, 0.0000000}, 136 {2445151.5, 21.000000, 41317.0, 0.0000000}, 137 {2445516.5, 22.000000, 41317.0, 0.0000000}, 138 {2446247.5, 23.000000, 41317.0, 0.0000000}, 139 {2447161.5, 24.000000, 41317.0, 0.0000000}, 140 {2447892.5, 25.000000, 41317.0, 0.0000000}, 141 {2448257.5, 26.000000, 41317.0, 0.0000000}, 142 {2448804.5, 27.000000, 41317.0, 0.0000000}, 143 {2449169.5, 28.000000, 41317.0, 0.0000000}, 144 {2449534.5, 29.000000, 41317.0, 0.0000000}, 145 {2450083.5, 30.000000, 41317.0, 0.0000000}, 146 {2450630.5, 31.000000, 41317.0, 0.0000000}, 147 {2451179.5, 32.000000, 41317.0, 0.0000000} 148 }; 149 150 151 psTime* psTimeGetTime(psTimeType type) 157 152 { 158 153 struct timeval now; 159 psTime time;160 161 time.tv_sec = 0;162 time.tv_usec = 0;154 psTime *time = NULL; 155 156 // Allocate psTime struct 157 ALLOC_TIME(time); 163 158 164 159 if (gettimeofday(&now, (struct timezone *)0) == -1) { 165 160 psError(__func__, " : Line %d - Failed to get time", __LINE__); 166 return time; 167 } 161 return NULL; 162 } 163 168 164 // Convert timeval time to psTime 169 time.tv_sec = now.tv_sec; 170 time.tv_usec = now.tv_usec; 171 172 // Add most current leapseconds value to UTC time to get TAI time 173 time.tv_sec += leapseconds[NUM_LEAPSECOND_UPDATES - 1][1]; 165 time->sec = now.tv_sec; 166 time->usec = now.tv_usec; 167 time->type = type; 168 169 // Add most leapseconds to UTC time to get TAI time if necessary 170 if(type == PS_TIME_TAI) { 171 time->sec += psGetTAIDelta(time); 172 } 174 173 175 174 return time; 176 175 } 177 176 178 char *psTimeToISO(psTime time) 177 psTime* psTimeConvert(psTime *time, psTimeType type) 178 { 179 double delta = 0.0; 180 181 if(time->type == type) { 182 psError(__func__, " : Line %d - Time is already in the correct psTime format. Time type: %d", __LINE__, type); 183 return NULL; 184 } 185 186 delta = psGetTAIDelta(time); 187 188 if(type == PS_TIME_UTC) { 189 time->sec = time->sec - delta; // User wants UTC time. Remove leapseconds. 190 } else if(type == PS_TIME_TAI) { 191 time->sec = time->sec + delta; // User wants TAI time. Add leapseconds. 192 } else { 193 psError(__func__, " : Line %d - Invalid psTimeType: %d", __LINE__, type); 194 } 195 196 return time; 197 } 198 199 double psTimeToLST(psTime *time, double longitude) 200 { 201 double delta = 0; 202 203 return delta; 204 } 205 206 psTime* psLSTToTime(double time, double longitude) 207 { 208 psTime *outTime = NULL; 209 210 return outTime; 211 } 212 213 double psGetUT1Delta(psTime *time) 214 { 215 double delta = 0; 216 217 return delta; 218 } 219 220 double psGetTAIDelta(psTime *time) 221 { 222 int i = 0; 223 double delta = 0.0; 224 double jd = 0.0; 225 double mjd = 0.0; 226 227 // Determine Julian and modified Julian dates used in table lookup and time delta calculation 228 jd = psTimeToJD(time); 229 mjd = psTimeToMJD(time); 230 231 // Perform table lookup 232 if(jd < lsTable[0][1]) { // Times earlier than 1961 233 delta = 0.0; 234 } else if(jd > lsTable[NUM_UPDATES-1][1]) { // Times greater than latest table entry 235 delta = lsTable[NUM_UPDATES-1][1] + (mjd - lsTable[NUM_UPDATES-1][2]) * lsTable[NUM_UPDATES-1][3]; 236 } else { // All other times 237 for (i = 0; i<NUM_UPDATES-1; i++) { 238 if (jd>lsTable[i][0] && jd<lsTable[i+1][0]) { 239 delta = lsTable[i][1] + (mjd - lsTable[i][2]) * lsTable[i][3]; 240 } 241 } 242 } 243 244 return delta; 245 } 246 247 double psTimeToJD(psTime *time) 248 { 249 double jd = 0.0; 250 251 // NULL error check 252 CHECK_NULL_TIME(time,0.0); 253 254 // Julian date conversion courtesy of Eugene Magnier 255 if(time->sec < 0) { 256 jd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 2440587.5; // psTime earlier than epoch 257 } else { 258 jd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 2440587.5; // psTime greater than epoch 259 } 260 261 return jd; 262 } 263 264 double psTimeToMJD(psTime *time) 265 { 266 double mjd = 0.0; 267 268 // NULL error check 269 CHECK_NULL_TIME(time,0.0); 270 271 // Modified Julian date conversion courtesy of Eugene Magnier 272 if(time->sec < 0) { 273 mjd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 40587.0; // psTime earlier than epoch 274 } else { 275 mjd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 40587.0; // psTime greater than epoch 276 } 277 278 return mjd; 279 } 280 281 char* psTimeToISO(psTime *time) 179 282 { 180 283 int ms = 0; … … 184 287 time_t sec; 185 288 186 CHECK_NEGATIVE_TIME_STRUCT(time, NULL); 289 // NULL error check 290 CHECK_NULL_TIME(time,NULL); 187 291 188 292 tempString = psAlloc(MAX_TIME_STRING_LENGTH); 189 293 timeString = psAlloc(MAX_TIME_STRING_LENGTH); 190 294 191 // Converts psTime to YYYY/MM/DD,HH:MM:SS.SSS in string form 192 ms = time.tv_usec / 1000; 193 194 sec = time.tv_sec; 295 ms = time->usec / 1000; 296 sec = time->sec; 297 195 298 // tmTime variable is statically allocated, no need to free 196 299 tmTime = gmtime(&sec); 197 if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y/%m/%d,%H:%M:%S", tmTime)) { 300 301 // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form 302 if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) { 198 303 psError(__func__, " : Line %d - Failed strftime conversion", __LINE__); 199 304 } 200 305 201 if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3d ", tempString, ms) < 0) {306 if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) { 202 307 psError(__func__, " : Line %d - Failed snprintf conversion", __LINE__); 203 308 } … … 207 312 } 208 313 209 psTime psTimeToUTC(psTime time) 210 { 211 int i = 0; 212 double jd = 0.0; 213 double ls = 0.0; 214 double *jdTable = NULL; 215 psTime outTime; 216 217 CHECK_NEGATIVE_TIME_STRUCT(time, outTime); 218 219 // Find leapseconds to subtract from psTime to get UTC time 220 jd = psTimeToJD(time); 221 jdTable = leapseconds[0]; 222 for (i = 0; i < NUM_LEAPSECOND_UPDATES; i++, jdTable += 2) { 223 if (jd > *jdTable) { 224 ls = *(jdTable + 1); 225 } 226 } 227 228 outTime.tv_sec = time.tv_sec - ls; 229 outTime.tv_usec = time.tv_usec; 230 231 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 232 233 return outTime; 234 } 235 236 double psTimeToMJD(psTime time) 237 { 238 double mjd = 0.0; 239 240 CHECK_NEGATIVE_TIME_STRUCT(time, mjd); 241 242 // Modified Julian date conversion courtesy of Eugene Magnier 243 mjd = time.tv_sec / SEC_PER_DAY + time.tv_usec / USEC_PER_DAY + 40587.0; 244 245 return mjd; 246 } 247 248 double psTimeToJD(psTime time) 249 { 250 double jd = 0.0; 251 252 CHECK_NEGATIVE_TIME_STRUCT(time, jd); 253 254 // Julian date conversion courtesy of Eugene Magnier 255 jd = time.tv_sec / SEC_PER_DAY + time.tv_usec / USEC_PER_DAY + 2440587.5; 256 257 return jd; 258 } 259 260 struct timeval psTimeToTimeval(psTime time) 314 struct timeval psTimeToTimeval(psTime *time) 261 315 { 262 316 struct timeval timevalTime; 263 317 264 CHECK_NEGATIVE_TIME_STRUCT(time, timevalTime); 265 timevalTime.tv_sec = time.tv_sec; 266 timevalTime.tv_usec = time.tv_usec; 318 // NULL error check 319 CHECK_NULL_TIME(time,timevalTime); 320 321 timevalTime.tv_sec = time->sec; 322 timevalTime.tv_usec = time->usec; 267 323 268 324 return timevalTime; 269 325 } 270 326 271 struct tm *psTimeToTM(psTimetime)327 struct tm* psTimeToTM(psTime *time) 272 328 { 273 329 struct tm *tmTime = NULL; 274 330 time_t sec; 275 331 276 CHECK_NEGATIVE_TIME_STRUCT(time, tmTime); 277 sec = time.tv_sec; 332 sec = time->sec; 278 333 tmTime = gmtime(&sec); 279 334 … … 281 336 } 282 337 283 psTime psISOToTime(char *time) 338 psTime* psJDToTime(double time) 339 { 340 double days = 0.0; 341 double seconds = 0.0; 342 psTime *outTime = NULL; 343 344 // Allocate psTime struct 345 ALLOC_TIME(outTime); 346 347 // Julian date conversion courtesy of Eugene Magnier 348 days = time - 2440587.5; 349 seconds = days * SEC_PER_DAY; 350 if(seconds < 0.0) { 351 outTime->usec = (seconds - (long)seconds) * -1000000.0; // psTime earlier than epoch 352 } else { 353 outTime->usec = (seconds - (long)seconds) * 1000000.0; // psTime greater than epoch 354 } 355 outTime->sec = seconds; 356 357 return outTime; 358 } 359 360 psTime* psMJDToTime(double time) 361 { 362 double days = 0.0; 363 double seconds = 0.0; 364 psTime *outTime = NULL; 365 366 // Allocate psTime struct 367 ALLOC_TIME(outTime); 368 369 // Modified Julian date conversion courtesy of Eugene Magnier 370 days = time - 40587.0; 371 seconds = days * SEC_PER_DAY; 372 if(seconds < 0.0) { 373 outTime->usec = (seconds - (long)seconds) * -1000000.0; // psTime earlier than epoch 374 } else { 375 outTime->usec = (seconds - (long)seconds) * 1000000.0; // psTime greater than epoch 376 } 377 outTime->sec = seconds; 378 379 return outTime; 380 } 381 382 psTime* psISOToTime(char *time) 284 383 { 285 384 char tempString[MAX_TIME_STRING_LENGTH]; … … 292 391 int millisecond; 293 392 struct tm tmTime; 294 psTime outTime; 295 393 psTime *outTime = NULL; 394 395 // Preserve input string by creating duplicate 296 396 strncpy(tempString, time, MAX_TIME_STRING_LENGTH); 297 397 298 // Convert YYYY /MM/DD,HH:MM:SS.SSSin string form to tm time299 year = atoi(strtok(tempString, " /"));300 if (year < 1900) {301 psError(__func__, "Years less than 1900 not allowed. Value: %d", year);302 return outTime; 303 } 304 305 month = atoi(strtok(NULL, " /"));398 // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time 399 year = atoi(strtok(tempString, "-")); 400 if (year < 0) { 401 psError(__func__, "Years less than 0 not allowed. Value: %d", year); 402 return outTime; 403 } 404 405 month = atoi(strtok(NULL, "-")); 306 406 if (month < 1 || month > 12) { 307 407 psError(__func__, "Month must have a value from 1 to 12. Value: %d", month); … … 309 409 } 310 410 311 day = atoi(strtok(NULL, " ,"));411 day = atoi(strtok(NULL, "T")); 312 412 if (day < 1 || day > 31) { 313 413 psError(__func__, "Day must have a value from 1 to 31. Value: %d", day); … … 333 433 } 334 434 335 millisecond = atoi(strtok(NULL, " X"));435 millisecond = atoi(strtok(NULL, "Z")); 336 436 if (millisecond < 0 || millisecond > 1000) { 337 437 psError(__func__, "Millisecond must have a value from 0 to 999. Value: %d", millisecond); … … 347 447 tmTime.tm_isdst = -1; 348 448 449 // Allocate psTime struct 450 ALLOC_TIME(outTime) 451 349 452 // Convert tm time to psTime 350 453 outTime = psTMToTime(&tmTime); 351 outTime.tv_usec = millisecond * 1000; 352 353 return outTime; 354 } 355 356 psTime psUTCToTime(psTime time) 357 { 358 psTime outTime; 359 360 CHECK_NEGATIVE_TIME_STRUCT(time, outTime); 361 362 // Convert UTC time to psTime/TAI 363 outTime.tv_sec = time.tv_sec + leapseconds[NUM_LEAPSECOND_UPDATES - 1][1]; 364 outTime.tv_usec = time.tv_usec; 365 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 366 367 return outTime; 368 } 369 370 psTime psMJDToTime(double time) 371 { 372 psTime outTime; 373 double days = 0.0; 374 double seconds = 0.0; 375 376 CHECK_NEGATIVE_TIME(time, outTime); 377 378 // Modified Julian date conversion courtesy of Eugene Magnier 379 days = time - 40587.0; 380 381 // Convert to psTime/TAI 382 seconds = days * SEC_PER_DAY; 383 outTime.tv_usec = (seconds - (long)seconds) * 1000000.0; 384 outTime.tv_sec = seconds; 385 386 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 387 388 return outTime; 389 } 390 391 psTime psJDToTime(double time) 392 { 393 double days = 0.0; 394 double seconds = 0.0; 395 psTime outTime; 396 397 CHECK_NEGATIVE_TIME(time, outTime); 398 399 // Julian date conversion courtesy of Eugene Magnier 400 days = time - 2440587.5; 401 402 // Convert to psTime/TAI 403 seconds = days * SEC_PER_DAY; 404 outTime.tv_sec = seconds; 405 outTime.tv_usec = (seconds - (long)seconds) * 1000000.0; 406 407 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 408 409 return outTime; 410 } 411 412 psTime psTimevalToTime(struct timeval * time) 413 { 414 psTime outTime; 415 416 if (time == NULL) 417 { 418 psError(__func__, "Null value for timeval arg not allowed"); 419 return outTime; 420 } else if (time->tv_sec < 0) 421 { 422 psError(__func__, "Negative seconds are not allowed: %ld", time->tv_sec); 423 return outTime; 424 } else if (time->tv_usec < 0) 425 { 426 psError(__func__, "Negative microseconds are not allowed: %ld", time->tv_usec); 427 return outTime; 428 } 429 // Convert to psTime/TAI 430 outTime.tv_sec = time->tv_sec; 431 outTime.tv_usec = time->tv_usec; 432 433 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 434 435 return outTime; 436 } 437 438 psTime psTMToTime(struct tm * time) 439 { 440 int i; 441 int n; 442 int y; 443 int mon[] = { 444 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 445 }; 446 long epoch; 447 psTime outTime; 448 449 i = 0; 450 n = 0; 451 y = 0; 452 epoch = 0; 453 454 if (time == NULL) 455 { 456 psError(__func__, "Null value for tm arg not allowed"); 457 return outTime; 458 } else if (time->tm_year < 70) 459 { 460 psError(__func__, "Input times earlier than 1970 not allowed. Value: %d", time->tm_year + 1900); 461 return outTime; 462 } else if (time->tm_mon < 0 || time->tm_mon > 11) 463 { 464 psError(__func__, "Month must have a value from 0 to 11. Value: %d", time->tm_mon); 465 return outTime; 466 } else if (time->tm_mday < 1 || time->tm_mday > 31) 467 { 468 psError(__func__, "Day must have a value from 1 to 31. Value: %d", time->tm_mday); 469 return outTime; 470 } else if (time->tm_hour < 0 || time->tm_hour > 23) 471 { 472 psError(__func__, "Hour must have a value from 0 to 23. Value: %d", time->tm_hour); 473 return outTime; 474 } else if (time->tm_min < 0 || time->tm_min > 59) 475 { 476 psError(__func__, "Minute must have a value from 0 to 59. Value: %d", time->tm_min); 477 return outTime; 478 } else if (time->tm_sec < 0 || time->tm_sec > 59) 479 { 480 psError(__func__, "Second must have a value from 0 to 59. Value: %d", time->tm_sec); 481 return outTime; 482 } 483 484 n = time->tm_year + 1900 - 1; 485 epoch = (time->tm_year - 70) * SEC_PER_YEAR + ((n / 4 - n / 100 + n / 400) - 486 (1969 / 4 - 1969 / 100 + 1969 / 400)) * SEC_PER_DAY; 487 488 y = time->tm_year + 1900; 489 490 // Adjust for leap years 491 for (i = 0; i < time->tm_mon; i++) 492 { 493 epoch += mon[i] * SEC_PER_DAY; 494 if (i == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) { 495 epoch += SEC_PER_DAY; 496 } 497 } 498 499 // Add everything 500 epoch += (time->tm_mday - 1) * SEC_PER_DAY; 501 epoch += time->tm_hour * SEC_PER_HOUR + time->tm_min * SEC_PER_MINUTE + time->tm_sec; 502 503 // Create psTime 504 outTime.tv_usec = 0; 505 outTime.tv_sec = epoch; 506 507 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 508 509 return outTime; 510 } 454 outTime->usec = millisecond * 1000; 455 456 return outTime; 457 } 458 459 psTime* psTimevalToTime(struct timeval *time) 460 { 461 psTime *outTime = NULL; 462 463 // NULL error check 464 CHECK_NULL_TIME(time,NULL); 465 466 // Allocate psTime struct 467 ALLOC_TIME(outTime); 468 469 // Convert to psTime 470 outTime->sec = time->tv_sec; 471 outTime->usec = time->tv_usec; 472 473 return outTime; 474 } 475 476 psTime* psTMToTime(struct tm* time) 477 { 478 time_t localTimeInSeconds = 0; 479 time_t temp = 0; 480 struct tm *localTMTime = NULL; 481 psTime *outTime = NULL; 482 483 // NULL error check 484 CHECK_NULL_TIME(time,NULL); 485 486 // Allocate psTime struct 487 ALLOC_TIME(outTime); 488 489 // The mktime function returns seconds since last epoch in local time, so get local time and offset 490 localTimeInSeconds = mktime(time); 491 localTMTime = localtime(&temp); 492 493 // Convert to psTime 494 outTime->usec = 0; 495 outTime->sec = localTMTime->tm_gmtoff + localTimeInSeconds; 496 497 return outTime; 498 } 499 500 psTime* psTAIAdd(psTime *tai1, psTime *tai2) 501 { 502 psTime *outTime = NULL; 503 504 if(tai1->type != PS_TIME_TAI) { 505 psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type); 506 return NULL; 507 } 508 509 if(tai2->type != PS_TIME_TAI) { 510 psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type); 511 return NULL; 512 } 513 514 ALLOC_TIME(outTime); 515 516 outTime->sec = tai1->sec + tai2->sec; 517 outTime->usec = tai1->usec + tai2->usec; 518 519 // Increment seconds in case of microsecond overflow after addition 520 if(outTime->usec<tai1->usec || outTime->usec<tai2->usec) { 521 outTime->sec++; 522 } 523 524 return outTime; 525 } 526 527 psTime* psTAISub(psTime *tai1, psTime *tai2) 528 { 529 psTime *outTime = NULL; 530 531 if(tai1->type != PS_TIME_TAI) { 532 psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type); 533 return NULL; 534 } 535 536 if(tai2->type != PS_TIME_TAI) { 537 psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type); 538 return NULL; 539 } 540 541 ALLOC_TIME(outTime); 542 543 outTime->sec = tai1->sec - tai2->sec; 544 outTime->usec = tai1->usec - tai2->usec; 545 546 // Decrement seconds in case of microsecond underflow after subtraction 547 if(outTime->usec>tai1->usec || outTime->usec>tai2->usec) { 548 outTime->sec--; 549 } 550 551 return outTime; 552 } 553 554 psTime* psTAIDelta(psTime *tai1, psTime *tai2) 555 { 556 psTime *outTime = NULL; 557 558 if(tai1->type != PS_TIME_TAI) { 559 psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type); 560 return NULL; 561 } 562 563 if(tai2->type != PS_TIME_TAI) { 564 psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type); 565 return NULL; 566 } 567 568 ALLOC_TIME(outTime); 569 570 outTime->sec = tai1->sec - tai2->sec; 571 outTime->usec = tai1->usec - tai2->usec; 572 573 // Decrement seconds in case of microsecond underflow after subtraction 574 if(outTime->usec>tai1->usec || outTime->usec>tai2->usec) { 575 outTime->sec--; 576 } 577 578 outTime->sec = abs(outTime->sec); 579 580 581 return outTime; 582 } -
trunk/psLib/src/astro/psTime.h
r1529 r1614 1 2 1 /** @file psTime.h 3 2 * … … 7 6 * A collection of functions are required by psLib to manipulate time data. These functions primarily consist 8 7 * of conversions between specific time formats. PSLib currently uses the UNIX timeval time system as the 9 * base upon which International Atomic Time (TAI) time is calculated. All time conversion functions within 10 * psLib, except those noted, are calculated in terms of TAI time, which is approxinmately 32 seconds faster 11 * than UTC/timeval. 8 * base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI 9 * time varies over time due to the earth's rotation and the movement of the continental plates. It is 10 * currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates 11 * is given in the table below, which comes from: 12 * 13 * ftp://maia.usno.navy.mil/ser7/tai-utc.dat 14 * 15 * This table is placed into a static array and used by the psTime functions for conversions. 16 * 17 * 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + (MJD - 37300.) X 0.001296 S 18 * 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + (MJD - 37300.) X 0.001296 S 19 * 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + (MJD - 37665.) X 0.0011232S 20 * 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + (MJD - 37665.) X 0.0011232S 21 * 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + (MJD - 38761.) X 0.001296 S 22 * 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + (MJD - 38761.) X 0.001296 S 23 * 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + (MJD - 38761.) X 0.001296 S 24 * 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + (MJD - 38761.) X 0.001296 S 25 * 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + (MJD - 38761.) X 0.001296 S 26 * 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + (MJD - 38761.) X 0.001296 S 27 * 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + (MJD - 38761.) X 0.001296 S 28 * 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + (MJD - 39126.) X 0.002592 S 29 * 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + (MJD - 39126.) X 0.002592 S 30 * 1972 JAN 1 =JD 2441317.5 TAI-UTC= 10.0 S + (MJD - 41317.) X 0.0 S 31 * 1972 JUL 1 =JD 2441499.5 TAI-UTC= 11.0 S + (MJD - 41317.) X 0.0 S 32 * 1973 JAN 1 =JD 2441683.5 TAI-UTC= 12.0 S + (MJD - 41317.) X 0.0 S 33 * 1974 JAN 1 =JD 2442048.5 TAI-UTC= 13.0 S + (MJD - 41317.) X 0.0 S 34 * 1975 JAN 1 =JD 2442413.5 TAI-UTC= 14.0 S + (MJD - 41317.) X 0.0 S 35 * 1976 JAN 1 =JD 2442778.5 TAI-UTC= 15.0 S + (MJD - 41317.) X 0.0 S 36 * 1977 JAN 1 =JD 2443144.5 TAI-UTC= 16.0 S + (MJD - 41317.) X 0.0 S 37 * 1978 JAN 1 =JD 2443509.5 TAI-UTC= 17.0 S + (MJD - 41317.) X 0.0 S 38 * 1979 JAN 1 =JD 2443874.5 TAI-UTC= 18.0 S + (MJD - 41317.) X 0.0 S 39 * 1980 JAN 1 =JD 2444239.5 TAI-UTC= 19.0 S + (MJD - 41317.) X 0.0 S 40 * 1981 JUL 1 =JD 2444786.5 TAI-UTC= 20.0 S + (MJD - 41317.) X 0.0 S 41 * 1982 JUL 1 =JD 2445151.5 TAI-UTC= 21.0 S + (MJD - 41317.) X 0.0 S 42 * 1983 JUL 1 =JD 2445516.5 TAI-UTC= 22.0 S + (MJD - 41317.) X 0.0 S 43 * 1985 JUL 1 =JD 2446247.5 TAI-UTC= 23.0 S + (MJD - 41317.) X 0.0 S 44 * 1988 JAN 1 =JD 2447161.5 TAI-UTC= 24.0 S + (MJD - 41317.) X 0.0 S 45 * 1990 JAN 1 =JD 2447892.5 TAI-UTC= 25.0 S + (MJD - 41317.) X 0.0 S 46 * 1991 JAN 1 =JD 2448257.5 TAI-UTC= 26.0 S + (MJD - 41317.) X 0.0 S 47 * 1992 JUL 1 =JD 2448804.5 TAI-UTC= 27.0 S + (MJD - 41317.) X 0.0 S 48 * 1993 JUL 1 =JD 2449169.5 TAI-UTC= 28.0 S + (MJD - 41317.) X 0.0 S 49 * 1994 JUL 1 =JD 2449534.5 TAI-UTC= 29.0 S + (MJD - 41317.) X 0.0 S 50 * 1996 JAN 1 =JD 2450083.5 TAI-UTC= 30.0 S + (MJD - 41317.) X 0.0 S 51 * 1997 JUL 1 =JD 2450630.5 TAI-UTC= 31.0 S + (MJD - 41317.) X 0.0 S 52 * 1999 JAN 1 =JD 2451179.5 TAI-UTC= 32.0 S + (MJD - 41317.) X 0.0 S 12 53 * 13 54 * @author Ross Harman, MHPCC 14 55 * 15 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $16 * @date $Date: 2004-08- 13 22:08:51$56 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 57 * @date $Date: 2004-08-25 01:37:45 $ 17 58 * 18 59 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 31 72 /// @{ 32 73 33 /******************************************************************************/ 34 35 /* TYPE DEFINITIONS */ 36 37 /******************************************************************************/ 74 75 /** Time type. 76 * 77 * Enumeration for psTime types, TAI or UTC time. 78 */ 79 typedef enum { 80 PS_TIME_TAI, ///< Temps Atomique International (TAI) time (time with leapseconds). 81 PS_TIME_UTC, ///< Universal Time Coordinated (UTC) time (time without leapseconds). 82 } psTimeType; 38 83 39 84 /** Definition of psTime. 40 85 * 41 * The psTime struct is used by psLib to represent time values critical to 42 * astronomical calculations. This structure represents a time which is 43 * equivalent to TAI (International Atomic Time) and is measured in both 86 * The psTime struct is used by psLib to represent time values critical to 87 * astronomical calculations. This structure represents a time which is 88 * equivalent to TAI (International Atomic Time) and is measured in both 44 89 * seconds and microseconds. 45 90 */ 46 typedef struct timeval psTime; 47 48 /*****************************************************************************/ 49 50 /* FUNCTION PROTOTYPES */ 51 52 /*****************************************************************************/ 53 54 /** Get current TAI time. 55 * 56 * Gets current time from the system clock in correct TAI units. 57 * 58 * @return psTime: Struct with current time. 59 */ 60 61 psTime psTimeGetTime(void); 62 63 /** Convert psTime to ISO time in TAI units. 64 * 65 * Converts psTime to a null terminated string in the form of: 66 * YYYY/MM/DD,HH:MM:SS.SSS. This function assumes the input time already is 67 * in TAI time and does not add or subtract leapseconds. 91 typedef struct psTime 92 { 93 psS64 sec; ///< Seconds since epoch, Jan 1, 1970. 94 psU32 usec; ///< Microseconds since last second. 95 psTimeType type; ///< Type of time. 96 } 97 psTime; 98 99 /** Get current time. 100 * 101 * Gets current time from the system clock. User must specify the psTimeType (PS_TIME_TAI or PS_TIME_UTC) in 102 * the argument. 103 * 104 * @return psTime*: Struct with current time. 105 */ 106 psTime* psTimeGetTime( 107 psTimeType type ///< Type of time to get (UTC or TAI). 108 ); 109 110 111 /** Convert psTime to UTC or TAI time. 112 * 113 * Converts psTime to UTC or TAI time based on the psTimeType argument. 114 * 115 * @return psTime*: Pointer to psTime. 116 */ 117 psTime* psTimeConvert( 118 psTime *time, 119 psTimeType type 120 ); 121 122 /** Convert psTime to Local Mean Sidereal Time (LST). 123 * 124 * Converts psTime at the given longitude to LST time. If the input time is not in UTC format, then it is 125 * converted. 126 * 127 * @return double: LST Time. 128 */ 129 double psTimeToLST( 130 psTime *time, ///< psTime to be converted. 131 double longitude ///< Longitude. 132 ); 133 134 /** Convert Local Mean Sidereal Time (LST) to psTime. 135 * 136 * Converts LST time to psTime. 137 * 138 * @return psTime*: Pointer to psTime. 139 */ 140 psTime* psLSTToTime( 141 double time, ///< LST time to be converted. 142 double longitude ///< Longitude. 143 ); 144 145 /** Determine UT1 - UTC from table lookup. 146 * 147 * This function is necessary to for various SLALIB functions. 148 * 149 * @return double: Time difference. 150 */ 151 double psGetUT1Delta( 152 psTime *time ///< psTime to be looked up. 153 ); 154 155 /** Determine TAI - UTC from table lookup. 156 * 157 * This function is necessary to for various psTime functions. 158 * 159 * @return double: Time difference. 160 */ 161 double psGetTAIDelta( 162 psTime *time ///< psTime to be looked up. 163 ); 164 165 /** Determine polar coordinates at a given time. 166 * 167 * Determines the orientation of the polar axis at the given time. 168 * 169 * @return psSphere*: Spherical coordinates of Earth's polar axias. 170 */ 171 /*psSphere* psGetPoleCoords( 172 psTime *time ///< psTime determine polar orientation. 173 );*/ 174 175 /** Convert psTime to Julian date time. 176 * 177 * Converts psTime to Julian date (JD) time. This function does not add or subtract leapseconds. 178 * 179 * @return double: Julian Date (JD) time. 180 */ 181 double psTimeToJD( 182 psTime *time ///< Input time to be converted. 183 ); 184 /** Convert psTime to modified Julian date time. 185 * 186 * Converts psTime to modified Julian date (MJD) time. This function does not add or subtract leapseconds. 187 * 188 * @return double: Modified Julian Days (MJD) time. 189 */ 190 double psTimeToMJD( 191 psTime *time ///< Input time to be converted. 192 ); 193 194 /** Convert psTime to ISO8601 formatted string. 195 * 196 * Converts psTime to a null terminated string in the form of YYYY-MM-DDThh:mm:ss.sss. This function does not 197 * add or subtract leapseconds. 68 198 * 69 199 * @return char*: Pointer null terminated array of chars in ISO time. 70 200 */ 71 72 char *psTimeToISO( 73 psTime time ///< Input time to be converted. 74 ); 75 76 /** Convert psTime to UTC time. 77 * 78 * Converts psTime to UTC time in double precision floating point notation. 79 * The input to this must already be int TAI time. The result from this 80 * function is not in TAI units, but that of UTC, which does not contain 81 * leapseconds. 82 * 83 * @return psTime: UTC time psTime format. 84 */ 85 86 psTime psTimeToUTC( 87 psTime time ///< Input time to be converted. 88 ); 89 90 /** Convert psTime to modified Julian date time. 91 * 92 * Converts psTime to modified Julian date (MJD) time. This function assumes 93 * the input time already is in TAI time and does not add or subtract 94 * leapseconds. 95 * 96 * @return double: Modified Julian Days (MJD) time. 97 */ 98 double psTimeToMJD( 99 psTime time ///< Input time to be converted. 100 ); 101 102 /** Convert psTime to Julian date time. 103 * 104 * Converts psTime to Julian date (JD) time. This function assumes the input 105 * time already is in TAI time and does not add or subtract leapseconds. 106 * 107 * @return double: Julian Date (JD) time. 108 */ 109 double psTimeToJD( 110 psTime time ///< Input time to be converted. 201 char* psTimeToISO( 202 psTime *time ///< Input time to be converted. 111 203 ); 112 204 113 205 /** Convert psTime to timeval time. 114 206 * 115 * Converts psTime to timeval time. This function assumes the input time 116 * already is in TAI time and does not add or subtract leapseconds. 207 * Converts psTime to timeval time. This function does not add or subtract leapseconds. 117 208 * 118 209 * @return timeval: timeval struct time. 119 210 */ 120 211 struct timeval psTimeToTimeval( 121 psTime time ///< Input time to be converted.212 psTime *time ///< Input time to be converted. 122 213 ); 123 214 124 215 /** Convert psTime to tm time. 125 216 * 126 * Converts psTime to tm time. This function assumes the input time already is in TAI time and does not add or 127 * subtract leapseconds. 217 * Converts psTime to tm time. This function does not add or subtract leapseconds. 128 218 * 129 219 * @return tm: tm struct time. 130 220 */ 131 struct tm *psTimeToTM(132 psTime time ///< Input time to be converted.221 struct tm* psTimeToTM( 222 psTime *time ///< Input time to be converted. 133 223 ); 134 224 225 /** Convert JD to psTime. 226 * 227 * Converts JD time to psTime. This function does not add or subtract leapseconds. 228 * 229 * @return psTime: time. 230 */ 231 psTime* psJDToTime( 232 double time ///< Input time to be converted. 233 ); 234 235 /** Convert MJD to psTime. 236 * 237 * Converts MJD time to psTime. This function does not add or subtract leapseconds. 238 * 239 * @return psTime: time. 240 */ 241 psTime* psMJDToTime( 242 double time ///< Input time to be converted. 243 ); 244 135 245 /** Convert ISO to psTime. 136 246 * 137 * Converts ISO time to psTime. This function assumes the input time already 138 * is in TAI time and does not add or subtract leapseconds. 139 * 140 * @return psTime: time 141 */ 142 psTime psISOToTime( 247 * Converts ISO time to psTime. This function does not add or subtract leapseconds. 248 * 249 * @return psTime*: time 250 */ 251 psTime* psISOToTime( 143 252 char *time ///< Input time to be converted. 144 253 ); 145 254 146 /** Convert UTC to psTime.147 *148 * Converts UTC time to psTime. This function assumes the input time already149 * is in TAI time and add or subtracts the necessary leapseconds.150 *151 * @return psTime: time in TAI units.152 */153 psTime psUTCToTime(154 psTime time ///< Input time to be converted.155 );156 157 /** Convert MJD to psTime.158 *159 * Converts MJD time to psTime. This function assumes the input time already160 * is in TAI time and does not add or subtract leapseconds.161 *162 * @return psTime: time.163 */164 psTime psMJDToTime(165 double time ///< Input time to be converted.166 );167 168 /** Convert JD to psTime.169 *170 * Converts JD time to psTime. This function assumes the input time already171 * is in TAI time and does not add or subtract leapseconds.172 *173 * @return psTime: time.174 */175 psTime psJDToTime(176 double time ///< Input time to be converted.177 );178 179 255 /** Convert timeval to psTime. 180 256 * 181 * Converts timeval time to psTime. This function assumes the input time 182 * already is in TAI time and does not add or subtract leapseconds. 183 * 184 * @return psTime: time. 185 */ 186 psTime psTimevalToTime( 187 struct timeval *time ///< Input time to be converted. 257 * Converts timeval time to psTime. This function does not add or subtract leapseconds. 258 * 259 * @return psTime*: time. 260 */ 261 psTime* psTimevalToTime( 262 struct timeval *time ///< Input time to be converted. 188 263 ); 189 264 190 265 /** Convert tm time to psTime. 191 266 * 192 * Converts tm time to psTime. This function assumes the input time already 193 * is in TAI time and does not add or subtract leapseconds. 194 * 195 * @return psTime: time. 196 */ 197 psTime psTMToTime( 267 * Converts tm time to psTime. This function does not add or subtract leapseconds. 268 * 269 * @return psTime*: time. 270 */ 271 psTime* psTMToTime( 198 272 struct tm *time ///< Input time to be converted. 199 273 ); 200 274 275 /** Add two TAI times. 276 * 277 * Adds two TAI times. This function does not add or subtract leapseconds. 278 * 279 * @return psTime*: time. 280 */ 281 psTime* psTAIAdd( 282 psTime *tai1, ///< First TAI time. 283 psTime *tai2 ///< Second TAI time. 284 ); 285 286 /** Subtract two TAI times. 287 * 288 * Subtracts two TAI times. This function does not add or subtract leapseconds. 289 * 290 * @return psTime*: time. 291 */ 292 psTime* psTAISub( 293 psTime *tai1, ///< First TAI time. 294 psTime *tai2 ///< Second TAI time. 295 ); 296 297 298 /** Find delta of two TAI times. 299 * 300 * Finds the absolute difference of two TAI times. This function does not add or subtract leapseconds. 301 * 302 * @return psTime*: time. 303 */ 304 psTime* psTAIDelta( 305 psTime *tai1, ///< First TAI time. 306 psTime *tai2 ///< Second TAI time. 307 ); 201 308 /// @} 202 309 -
trunk/psLib/src/astronomy/psTime.c
r1598 r1614 1 2 1 /** @file psTime.c 3 2 * … … 7 6 * A collection of functions are required by psLib to manipulate time data. These functions primarily consist 8 7 * of conversions between specific time formats. PSLib currently uses the UNIX timeval time system as the 9 * base upon which International Atomic Time (TAI) time is calculated. TAI time varies over time due to the 10 * earth's rotation and the movement of the continental plates. It is currentls 32 seconds faster than 11 * UTC/timeval time. 8 * base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI 9 * time varies over time due to the earth's rotation and the movement of the continental plates. It is 10 * currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates 11 * is given in the table below, which comes from: 12 * 13 * ftp://maia.usno.navy.mil/ser7/tai-utc.dat 14 * 15 * This table is placed into a static array and used by the psTime functions for conversions. 16 * 17 * 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + (MJD - 37300.) X 0.001296 S 18 * 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + (MJD - 37300.) X 0.001296 S 19 * 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + (MJD - 37665.) X 0.0011232S 20 * 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + (MJD - 37665.) X 0.0011232S 21 * 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + (MJD - 38761.) X 0.001296 S 22 * 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + (MJD - 38761.) X 0.001296 S 23 * 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + (MJD - 38761.) X 0.001296 S 24 * 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + (MJD - 38761.) X 0.001296 S 25 * 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + (MJD - 38761.) X 0.001296 S 26 * 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + (MJD - 38761.) X 0.001296 S 27 * 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + (MJD - 38761.) X 0.001296 S 28 * 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + (MJD - 39126.) X 0.002592 S 29 * 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + (MJD - 39126.) X 0.002592 S 30 * 1972 JAN 1 =JD 2441317.5 TAI-UTC= 10.0 S + (MJD - 41317.) X 0.0 S 31 * 1972 JUL 1 =JD 2441499.5 TAI-UTC= 11.0 S + (MJD - 41317.) X 0.0 S 32 * 1973 JAN 1 =JD 2441683.5 TAI-UTC= 12.0 S + (MJD - 41317.) X 0.0 S 33 * 1974 JAN 1 =JD 2442048.5 TAI-UTC= 13.0 S + (MJD - 41317.) X 0.0 S 34 * 1975 JAN 1 =JD 2442413.5 TAI-UTC= 14.0 S + (MJD - 41317.) X 0.0 S 35 * 1976 JAN 1 =JD 2442778.5 TAI-UTC= 15.0 S + (MJD - 41317.) X 0.0 S 36 * 1977 JAN 1 =JD 2443144.5 TAI-UTC= 16.0 S + (MJD - 41317.) X 0.0 S 37 * 1978 JAN 1 =JD 2443509.5 TAI-UTC= 17.0 S + (MJD - 41317.) X 0.0 S 38 * 1979 JAN 1 =JD 2443874.5 TAI-UTC= 18.0 S + (MJD - 41317.) X 0.0 S 39 * 1980 JAN 1 =JD 2444239.5 TAI-UTC= 19.0 S + (MJD - 41317.) X 0.0 S 40 * 1981 JUL 1 =JD 2444786.5 TAI-UTC= 20.0 S + (MJD - 41317.) X 0.0 S 41 * 1982 JUL 1 =JD 2445151.5 TAI-UTC= 21.0 S + (MJD - 41317.) X 0.0 S 42 * 1983 JUL 1 =JD 2445516.5 TAI-UTC= 22.0 S + (MJD - 41317.) X 0.0 S 43 * 1985 JUL 1 =JD 2446247.5 TAI-UTC= 23.0 S + (MJD - 41317.) X 0.0 S 44 * 1988 JAN 1 =JD 2447161.5 TAI-UTC= 24.0 S + (MJD - 41317.) X 0.0 S 45 * 1990 JAN 1 =JD 2447892.5 TAI-UTC= 25.0 S + (MJD - 41317.) X 0.0 S 46 * 1991 JAN 1 =JD 2448257.5 TAI-UTC= 26.0 S + (MJD - 41317.) X 0.0 S 47 * 1992 JUL 1 =JD 2448804.5 TAI-UTC= 27.0 S + (MJD - 41317.) X 0.0 S 48 * 1993 JUL 1 =JD 2449169.5 TAI-UTC= 28.0 S + (MJD - 41317.) X 0.0 S 49 * 1994 JUL 1 =JD 2449534.5 TAI-UTC= 29.0 S + (MJD - 41317.) X 0.0 S 50 * 1996 JAN 1 =JD 2450083.5 TAI-UTC= 30.0 S + (MJD - 41317.) X 0.0 S 51 * 1997 JUL 1 =JD 2450630.5 TAI-UTC= 31.0 S + (MJD - 41317.) X 0.0 S 52 * 1999 JAN 1 =JD 2451179.5 TAI-UTC= 32.0 S + (MJD - 41317.) X 0.0 S 12 53 * 13 54 * @author Ross Harman, MHPCC 14 55 * 15 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $16 * @date $Date: 2004-08- 19 18:57:49$56 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 57 * @date $Date: 2004-08-25 01:37:34 $ 17 58 * 18 59 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 26 67 #include "psError.h" 27 68 #include "psMemory.h" 28 29 /******************************************************************************/ 30 /* DEFINE STATEMENTS */ 31 /******************************************************************************/ 32 /******************************************************************************/ 33 /* DEFINE STATEMENTS */ 34 /******************************************************************************/ 35 36 // None 37 38 /******************************************************************************/ 39 /* TYPE DEFINITIONS */ 40 /******************************************************************************/ 41 42 // None 43 44 /*****************************************************************************/ 45 /* GLOBAL VARIABLES */ 46 /*****************************************************************************/ 47 48 // None 49 50 /*****************************************************************************/ 51 /* FILE STATIC VARIABLES */ 52 /*****************************************************************************/ 53 54 // None 55 56 /*****************************************************************************/ 57 /* FUNCTION IMPLEMENTATION - LOCAL */ 58 /*****************************************************************************/ 59 60 /******************************************************************************/ 61 /* DEFINE STATEMENTS */ 62 /******************************************************************************/ 69 #include "psAbort.h" 70 63 71 64 72 /** Number of available leapsecond updates */ 65 #define NUM_ LEAPSECOND_UPDATES 2373 #define NUM_UPDATES 36 66 74 67 75 /** Maximum length of time string */ … … 83 91 #define USEC_PER_DAY 86400000000.0 84 92 85 /** Preprocessor macro to generate error for negative time instruct */86 #define CHECK_N EGATIVE_TIME_STRUCT(NAME,RETURN)\87 if( NAME.tv_sec < 0) {\88 psError(__func__,"N egative seconds are not allowed: %ld", NAME.tv_sec);\93 /** Preprocessor macro to check for null psTime struct */ 94 #define CHECK_NULL_TIME(TIME,RETURN) \ 95 if(TIME == NULL) { \ 96 psError(__func__,"NULL value not allowed"); \ 89 97 return RETURN; \ 90 } else if(NAME.tv_usec<0) { \ 91 psError(__func__,"Negative microseconds are not allowed: %ld", NAME.tv_usec); \ 92 return RETURN; \ 93 } 94 95 /** Preprocessor macro to generate error for negative time */ 96 #define CHECK_NEGATIVE_TIME(NAME,RETURN) \ 97 if(NAME < 0.0) { \ 98 psError(__func__,"Negative time is not allowed: %f", NAME); \ 99 return RETURN; \ 100 } \ 101 102 /* The table below comes from http://tycho.usno.navy.mil/leapsec.html, which reports the current state of 103 the TAI/UTC leapsecond conversion times. This table is placed into a two dimensional array and used by 104 the psTimeGetTime() function to calculate TAI time from UTC time. 105 106 1972 JAN 1 = JD 2441317.5 TAI-UTC = 10.0 107 1972 JUL 1 = JD 2441499.5 TAI-UTC = 11.0 108 1973 JAN 1 = JD 2441683.5 TAI-UTC = 12.0 109 1974 JAN 1 = JD 2442048.5 TAI-UTC = 13.0 110 1975 JAN 1 = JD 2442413.5 TAI-UTC = 14.0 111 1976 JAN 1 = JD 2442778.5 TAI-UTC = 15.0 112 1977 JAN 1 = JD 2443144.5 TAI-UTC = 16.0 113 1978 JAN 1 = JD 2443509.5 TAI-UTC = 17.0 114 1979 JAN 1 = JD 2443874.5 TAI-UTC = 18.0 115 1980 JAN 1 = JD 2444239.5 TAI-UTC = 19.0 116 1981 JUL 1 = JD 2444786.5 TAI-UTC = 20.0 117 1982 JUL 1 = JD 2445151.5 TAI-UTC = 21.0 118 1983 JUL 1 = JD 2445516.5 TAI-UTC = 22.0 119 1985 JUL 1 = JD 2446247.5 TAI-UTC = 23.0 120 1988 JAN 1 = JD 2447161.5 TAI-UTC = 24.0 121 1990 JAN 1 = JD 2447892.5 TAI-UTC = 25.0 122 1991 JAN 1 = JD 2448257.5 TAI-UTC = 26.0 123 1992 JUL 1 = JD 2448804.5 TAI-UTC = 27.0 124 1993 JUL 1 = JD 2449169.5 TAI-UTC = 28.0 125 1994 JUL 1 = JD 2449534.5 TAI-UTC = 29.0 126 1996 JAN 1 = JD 2450083.5 TAI-UTC = 30.0 127 1997 JUL 1 = JD 2450630.5 TAI-UTC = 31.0 128 1999 JAN 1 = JD 2451179.5 TAI-UTC = 32.0 98 } 99 100 /** Preprocessor macro to allocate psTime strict */ 101 #define ALLOC_TIME(TIME) \ 102 TIME = (psTime*)psAlloc(sizeof(psTime)); \ 103 if (TIME == NULL) { \ 104 psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); \ 105 } 106 107 /* 108 The table below comes from ftp://maia.usno.navy.mil/ser7/tai-utc.dat, which reports the current state of 109 the TAI/UTC leapsecond conversion times. 129 110 */ 130 static double leapseconds[NUM_LEAPSECOND_UPDATES][2] = { 131 {2441317.5, 10.0}, 132 {2441499.5, 11.0}, 133 {2441683.5, 12.0}, 134 {2442048.5, 13.0}, 135 {2442413.5, 14.0}, 136 {2442778.5, 15.0}, 137 {2443144.5, 16.0}, 138 {2443509.5, 17.0}, 139 {2443874.5, 18.0}, 140 {2444239.5, 19.0}, 141 {2444786.5, 20.0}, 142 {2445151.5, 21.0}, 143 {2445516.5, 22.0}, 144 {2446247.5, 23.0}, 145 {2447161.5, 24.0}, 146 {2447892.5, 25.0}, 147 {2448257.5, 26.0}, 148 {2448804.5, 27.0}, 149 {2449169.5, 28.0}, 150 {2449534.5, 29.0}, 151 {2450083.5, 30.0}, 152 {2450630.5, 31.0}, 153 {2451179.5, 32.0} 154 }; 155 156 psTime psTimeGetTime(void) 111 static double lsTable[NUM_UPDATES][4] = { 112 {2437300.5, 1.422818, 37300.0, 0.0012960}, 113 {2437512.5, 1.372818, 37300.0, 0.0012960}, 114 {2437665.5, 1.845858, 37665.0, 0.0011232}, 115 {2438334.5, 1.945858, 37665.0, 0.0011232}, 116 {2438395.5, 3.240130, 38761.0, 0.0012960}, 117 {2438486.5, 3.340130, 38761.0, 0.0012960}, 118 {2438639.5, 3.440130, 38761.0, 0.0012960}, 119 {2438761.5, 3.540130, 38761.0, 0.0012960}, 120 {2438820.5, 3.640130, 38761.0, 0.0012960}, 121 {2438942.5, 3.740130, 38761.0, 0.0012960}, 122 {2439004.5, 3.840130, 38761.0, 0.0012960}, 123 {2439126.5, 4.313170, 39126.0, 0.0025920}, 124 {2439887.5, 4.213170, 39126.0, 0.0025920}, 125 {2441317.5, 10.000000, 41317.0, 0.0000000}, 126 {2441499.5, 11.000000, 41317.0, 0.0000000}, 127 {2441683.5, 12.000000, 41317.0, 0.0000000}, 128 {2442048.5, 13.000000, 41317.0, 0.0000000}, 129 {2442413.5, 14.000000, 41317.0, 0.0000000}, 130 {2442778.5, 15.000000, 41317.0, 0.0000000}, 131 {2443144.5, 16.000000, 41317.0, 0.0000000}, 132 {2443509.5, 17.000000, 41317.0, 0.0000000}, 133 {2443874.5, 18.000000, 41317.0, 0.0000000}, 134 {2444239.5, 19.000000, 41317.0, 0.0000000}, 135 {2444786.5, 20.000000, 41317.0, 0.0000000}, 136 {2445151.5, 21.000000, 41317.0, 0.0000000}, 137 {2445516.5, 22.000000, 41317.0, 0.0000000}, 138 {2446247.5, 23.000000, 41317.0, 0.0000000}, 139 {2447161.5, 24.000000, 41317.0, 0.0000000}, 140 {2447892.5, 25.000000, 41317.0, 0.0000000}, 141 {2448257.5, 26.000000, 41317.0, 0.0000000}, 142 {2448804.5, 27.000000, 41317.0, 0.0000000}, 143 {2449169.5, 28.000000, 41317.0, 0.0000000}, 144 {2449534.5, 29.000000, 41317.0, 0.0000000}, 145 {2450083.5, 30.000000, 41317.0, 0.0000000}, 146 {2450630.5, 31.000000, 41317.0, 0.0000000}, 147 {2451179.5, 32.000000, 41317.0, 0.0000000} 148 }; 149 150 151 psTime* psTimeGetTime(psTimeType type) 157 152 { 158 153 struct timeval now; 159 psTime time;160 161 time.tv_sec = 0;162 time.tv_usec = 0;154 psTime *time = NULL; 155 156 // Allocate psTime struct 157 ALLOC_TIME(time); 163 158 164 159 if (gettimeofday(&now, (struct timezone *)0) == -1) { 165 160 psError(__func__, " : Line %d - Failed to get time", __LINE__); 166 return time; 167 } 161 return NULL; 162 } 163 168 164 // Convert timeval time to psTime 169 time.tv_sec = now.tv_sec; 170 time.tv_usec = now.tv_usec; 171 172 // Add most current leapseconds value to UTC time to get TAI time 173 time.tv_sec += leapseconds[NUM_LEAPSECOND_UPDATES - 1][1]; 165 time->sec = now.tv_sec; 166 time->usec = now.tv_usec; 167 time->type = type; 168 169 // Add most leapseconds to UTC time to get TAI time if necessary 170 if(type == PS_TIME_TAI) { 171 time->sec += psGetTAIDelta(time); 172 } 174 173 175 174 return time; 176 175 } 177 176 178 char *psTimeToISO(psTime time) 177 psTime* psTimeConvert(psTime *time, psTimeType type) 178 { 179 double delta = 0.0; 180 181 if(time->type == type) { 182 psError(__func__, " : Line %d - Time is already in the correct psTime format. Time type: %d", __LINE__, type); 183 return NULL; 184 } 185 186 delta = psGetTAIDelta(time); 187 188 if(type == PS_TIME_UTC) { 189 time->sec = time->sec - delta; // User wants UTC time. Remove leapseconds. 190 } else if(type == PS_TIME_TAI) { 191 time->sec = time->sec + delta; // User wants TAI time. Add leapseconds. 192 } else { 193 psError(__func__, " : Line %d - Invalid psTimeType: %d", __LINE__, type); 194 } 195 196 return time; 197 } 198 199 double psTimeToLST(psTime *time, double longitude) 200 { 201 double delta = 0; 202 203 return delta; 204 } 205 206 psTime* psLSTToTime(double time, double longitude) 207 { 208 psTime *outTime = NULL; 209 210 return outTime; 211 } 212 213 double psGetUT1Delta(psTime *time) 214 { 215 double delta = 0; 216 217 return delta; 218 } 219 220 double psGetTAIDelta(psTime *time) 221 { 222 int i = 0; 223 double delta = 0.0; 224 double jd = 0.0; 225 double mjd = 0.0; 226 227 // Determine Julian and modified Julian dates used in table lookup and time delta calculation 228 jd = psTimeToJD(time); 229 mjd = psTimeToMJD(time); 230 231 // Perform table lookup 232 if(jd < lsTable[0][1]) { // Times earlier than 1961 233 delta = 0.0; 234 } else if(jd > lsTable[NUM_UPDATES-1][1]) { // Times greater than latest table entry 235 delta = lsTable[NUM_UPDATES-1][1] + (mjd - lsTable[NUM_UPDATES-1][2]) * lsTable[NUM_UPDATES-1][3]; 236 } else { // All other times 237 for (i = 0; i<NUM_UPDATES-1; i++) { 238 if (jd>lsTable[i][0] && jd<lsTable[i+1][0]) { 239 delta = lsTable[i][1] + (mjd - lsTable[i][2]) * lsTable[i][3]; 240 } 241 } 242 } 243 244 return delta; 245 } 246 247 double psTimeToJD(psTime *time) 248 { 249 double jd = 0.0; 250 251 // NULL error check 252 CHECK_NULL_TIME(time,0.0); 253 254 // Julian date conversion courtesy of Eugene Magnier 255 if(time->sec < 0) { 256 jd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 2440587.5; // psTime earlier than epoch 257 } else { 258 jd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 2440587.5; // psTime greater than epoch 259 } 260 261 return jd; 262 } 263 264 double psTimeToMJD(psTime *time) 265 { 266 double mjd = 0.0; 267 268 // NULL error check 269 CHECK_NULL_TIME(time,0.0); 270 271 // Modified Julian date conversion courtesy of Eugene Magnier 272 if(time->sec < 0) { 273 mjd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 40587.0; // psTime earlier than epoch 274 } else { 275 mjd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 40587.0; // psTime greater than epoch 276 } 277 278 return mjd; 279 } 280 281 char* psTimeToISO(psTime *time) 179 282 { 180 283 int ms = 0; … … 184 287 time_t sec; 185 288 186 CHECK_NEGATIVE_TIME_STRUCT(time, NULL); 289 // NULL error check 290 CHECK_NULL_TIME(time,NULL); 187 291 188 292 tempString = psAlloc(MAX_TIME_STRING_LENGTH); 189 293 timeString = psAlloc(MAX_TIME_STRING_LENGTH); 190 294 191 // Converts psTime to YYYY/MM/DD,HH:MM:SS.SSS in string form 192 ms = time.tv_usec / 1000; 193 194 sec = time.tv_sec; 295 ms = time->usec / 1000; 296 sec = time->sec; 297 195 298 // tmTime variable is statically allocated, no need to free 196 299 tmTime = gmtime(&sec); 197 if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y/%m/%d,%H:%M:%S", tmTime)) { 300 301 // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form 302 if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) { 198 303 psError(__func__, " : Line %d - Failed strftime conversion", __LINE__); 199 304 } 200 305 201 if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3d ", tempString, ms) < 0) {306 if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) { 202 307 psError(__func__, " : Line %d - Failed snprintf conversion", __LINE__); 203 308 } … … 207 312 } 208 313 209 psTime psTimeToUTC(psTime time) 210 { 211 int i = 0; 212 double jd = 0.0; 213 double ls = 0.0; 214 double *jdTable = NULL; 215 psTime outTime; 216 217 CHECK_NEGATIVE_TIME_STRUCT(time, outTime); 218 219 // Find leapseconds to subtract from psTime to get UTC time 220 jd = psTimeToJD(time); 221 jdTable = leapseconds[0]; 222 for (i = 0; i < NUM_LEAPSECOND_UPDATES; i++, jdTable += 2) { 223 if (jd > *jdTable) { 224 ls = *(jdTable + 1); 225 } 226 } 227 228 outTime.tv_sec = time.tv_sec - ls; 229 outTime.tv_usec = time.tv_usec; 230 231 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 232 233 return outTime; 234 } 235 236 double psTimeToMJD(psTime time) 237 { 238 double mjd = 0.0; 239 240 CHECK_NEGATIVE_TIME_STRUCT(time, mjd); 241 242 // Modified Julian date conversion courtesy of Eugene Magnier 243 mjd = time.tv_sec / SEC_PER_DAY + time.tv_usec / USEC_PER_DAY + 40587.0; 244 245 return mjd; 246 } 247 248 double psTimeToJD(psTime time) 249 { 250 double jd = 0.0; 251 252 CHECK_NEGATIVE_TIME_STRUCT(time, jd); 253 254 // Julian date conversion courtesy of Eugene Magnier 255 jd = time.tv_sec / SEC_PER_DAY + time.tv_usec / USEC_PER_DAY + 2440587.5; 256 257 return jd; 258 } 259 260 struct timeval psTimeToTimeval(psTime time) 314 struct timeval psTimeToTimeval(psTime *time) 261 315 { 262 316 struct timeval timevalTime; 263 317 264 CHECK_NEGATIVE_TIME_STRUCT(time, timevalTime); 265 timevalTime.tv_sec = time.tv_sec; 266 timevalTime.tv_usec = time.tv_usec; 318 // NULL error check 319 CHECK_NULL_TIME(time,timevalTime); 320 321 timevalTime.tv_sec = time->sec; 322 timevalTime.tv_usec = time->usec; 267 323 268 324 return timevalTime; 269 325 } 270 326 271 struct tm *psTimeToTM(psTimetime)327 struct tm* psTimeToTM(psTime *time) 272 328 { 273 329 struct tm *tmTime = NULL; 274 330 time_t sec; 275 331 276 CHECK_NEGATIVE_TIME_STRUCT(time, tmTime); 277 sec = time.tv_sec; 332 sec = time->sec; 278 333 tmTime = gmtime(&sec); 279 334 … … 281 336 } 282 337 283 psTime psISOToTime(char *time) 338 psTime* psJDToTime(double time) 339 { 340 double days = 0.0; 341 double seconds = 0.0; 342 psTime *outTime = NULL; 343 344 // Allocate psTime struct 345 ALLOC_TIME(outTime); 346 347 // Julian date conversion courtesy of Eugene Magnier 348 days = time - 2440587.5; 349 seconds = days * SEC_PER_DAY; 350 if(seconds < 0.0) { 351 outTime->usec = (seconds - (long)seconds) * -1000000.0; // psTime earlier than epoch 352 } else { 353 outTime->usec = (seconds - (long)seconds) * 1000000.0; // psTime greater than epoch 354 } 355 outTime->sec = seconds; 356 357 return outTime; 358 } 359 360 psTime* psMJDToTime(double time) 361 { 362 double days = 0.0; 363 double seconds = 0.0; 364 psTime *outTime = NULL; 365 366 // Allocate psTime struct 367 ALLOC_TIME(outTime); 368 369 // Modified Julian date conversion courtesy of Eugene Magnier 370 days = time - 40587.0; 371 seconds = days * SEC_PER_DAY; 372 if(seconds < 0.0) { 373 outTime->usec = (seconds - (long)seconds) * -1000000.0; // psTime earlier than epoch 374 } else { 375 outTime->usec = (seconds - (long)seconds) * 1000000.0; // psTime greater than epoch 376 } 377 outTime->sec = seconds; 378 379 return outTime; 380 } 381 382 psTime* psISOToTime(char *time) 284 383 { 285 384 char tempString[MAX_TIME_STRING_LENGTH]; … … 292 391 int millisecond; 293 392 struct tm tmTime; 294 psTime outTime; 295 393 psTime *outTime = NULL; 394 395 // Preserve input string by creating duplicate 296 396 strncpy(tempString, time, MAX_TIME_STRING_LENGTH); 297 397 298 // Convert YYYY /MM/DD,HH:MM:SS.SSSin string form to tm time299 year = atoi(strtok(tempString, " /"));300 if (year < 1900) {301 psError(__func__, "Years less than 1900 not allowed. Value: %d", year);302 return outTime; 303 } 304 305 month = atoi(strtok(NULL, " /"));398 // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time 399 year = atoi(strtok(tempString, "-")); 400 if (year < 0) { 401 psError(__func__, "Years less than 0 not allowed. Value: %d", year); 402 return outTime; 403 } 404 405 month = atoi(strtok(NULL, "-")); 306 406 if (month < 1 || month > 12) { 307 407 psError(__func__, "Month must have a value from 1 to 12. Value: %d", month); … … 309 409 } 310 410 311 day = atoi(strtok(NULL, " ,"));411 day = atoi(strtok(NULL, "T")); 312 412 if (day < 1 || day > 31) { 313 413 psError(__func__, "Day must have a value from 1 to 31. Value: %d", day); … … 333 433 } 334 434 335 millisecond = atoi(strtok(NULL, " X"));435 millisecond = atoi(strtok(NULL, "Z")); 336 436 if (millisecond < 0 || millisecond > 1000) { 337 437 psError(__func__, "Millisecond must have a value from 0 to 999. Value: %d", millisecond); … … 347 447 tmTime.tm_isdst = -1; 348 448 449 // Allocate psTime struct 450 ALLOC_TIME(outTime) 451 349 452 // Convert tm time to psTime 350 453 outTime = psTMToTime(&tmTime); 351 outTime.tv_usec = millisecond * 1000; 352 353 return outTime; 354 } 355 356 psTime psUTCToTime(psTime time) 357 { 358 psTime outTime; 359 360 CHECK_NEGATIVE_TIME_STRUCT(time, outTime); 361 362 // Convert UTC time to psTime/TAI 363 outTime.tv_sec = time.tv_sec + leapseconds[NUM_LEAPSECOND_UPDATES - 1][1]; 364 outTime.tv_usec = time.tv_usec; 365 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 366 367 return outTime; 368 } 369 370 psTime psMJDToTime(double time) 371 { 372 psTime outTime; 373 double days = 0.0; 374 double seconds = 0.0; 375 376 CHECK_NEGATIVE_TIME(time, outTime); 377 378 // Modified Julian date conversion courtesy of Eugene Magnier 379 days = time - 40587.0; 380 381 // Convert to psTime/TAI 382 seconds = days * SEC_PER_DAY; 383 outTime.tv_usec = (seconds - (long)seconds) * 1000000.0; 384 outTime.tv_sec = seconds; 385 386 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 387 388 return outTime; 389 } 390 391 psTime psJDToTime(double time) 392 { 393 double days = 0.0; 394 double seconds = 0.0; 395 psTime outTime; 396 397 CHECK_NEGATIVE_TIME(time, outTime); 398 399 // Julian date conversion courtesy of Eugene Magnier 400 days = time - 2440587.5; 401 402 // Convert to psTime/TAI 403 seconds = days * SEC_PER_DAY; 404 outTime.tv_sec = seconds; 405 outTime.tv_usec = (seconds - (long)seconds) * 1000000.0; 406 407 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 408 409 return outTime; 410 } 411 412 psTime psTimevalToTime(struct timeval * time) 413 { 414 psTime outTime; 415 416 if (time == NULL) 417 { 418 psError(__func__, "Null value for timeval arg not allowed"); 419 return outTime; 420 } else if (time->tv_sec < 0) 421 { 422 psError(__func__, "Negative seconds are not allowed: %ld", time->tv_sec); 423 return outTime; 424 } else if (time->tv_usec < 0) 425 { 426 psError(__func__, "Negative microseconds are not allowed: %ld", time->tv_usec); 427 return outTime; 428 } 429 // Convert to psTime/TAI 430 outTime.tv_sec = time->tv_sec; 431 outTime.tv_usec = time->tv_usec; 432 433 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 434 435 return outTime; 436 } 437 438 psTime psTMToTime(struct tm * time) 439 { 440 int i; 441 int n; 442 int y; 443 int mon[] = { 444 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 445 }; 446 long epoch; 447 psTime outTime; 448 449 i = 0; 450 n = 0; 451 y = 0; 452 epoch = 0; 453 454 if (time == NULL) 455 { 456 psError(__func__, "Null value for tm arg not allowed"); 457 return outTime; 458 } else if (time->tm_year < 70) 459 { 460 psError(__func__, "Input times earlier than 1970 not allowed. Value: %d", time->tm_year + 1900); 461 return outTime; 462 } else if (time->tm_mon < 0 || time->tm_mon > 11) 463 { 464 psError(__func__, "Month must have a value from 0 to 11. Value: %d", time->tm_mon); 465 return outTime; 466 } else if (time->tm_mday < 1 || time->tm_mday > 31) 467 { 468 psError(__func__, "Day must have a value from 1 to 31. Value: %d", time->tm_mday); 469 return outTime; 470 } else if (time->tm_hour < 0 || time->tm_hour > 23) 471 { 472 psError(__func__, "Hour must have a value from 0 to 23. Value: %d", time->tm_hour); 473 return outTime; 474 } else if (time->tm_min < 0 || time->tm_min > 59) 475 { 476 psError(__func__, "Minute must have a value from 0 to 59. Value: %d", time->tm_min); 477 return outTime; 478 } else if (time->tm_sec < 0 || time->tm_sec > 59) 479 { 480 psError(__func__, "Second must have a value from 0 to 59. Value: %d", time->tm_sec); 481 return outTime; 482 } 483 484 n = time->tm_year + 1900 - 1; 485 epoch = (time->tm_year - 70) * SEC_PER_YEAR + ((n / 4 - n / 100 + n / 400) - 486 (1969 / 4 - 1969 / 100 + 1969 / 400)) * SEC_PER_DAY; 487 488 y = time->tm_year + 1900; 489 490 // Adjust for leap years 491 for (i = 0; i < time->tm_mon; i++) 492 { 493 epoch += mon[i] * SEC_PER_DAY; 494 if (i == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) { 495 epoch += SEC_PER_DAY; 496 } 497 } 498 499 // Add everything 500 epoch += (time->tm_mday - 1) * SEC_PER_DAY; 501 epoch += time->tm_hour * SEC_PER_HOUR + time->tm_min * SEC_PER_MINUTE + time->tm_sec; 502 503 // Create psTime 504 outTime.tv_usec = 0; 505 outTime.tv_sec = epoch; 506 507 CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime); 508 509 return outTime; 510 } 454 outTime->usec = millisecond * 1000; 455 456 return outTime; 457 } 458 459 psTime* psTimevalToTime(struct timeval *time) 460 { 461 psTime *outTime = NULL; 462 463 // NULL error check 464 CHECK_NULL_TIME(time,NULL); 465 466 // Allocate psTime struct 467 ALLOC_TIME(outTime); 468 469 // Convert to psTime 470 outTime->sec = time->tv_sec; 471 outTime->usec = time->tv_usec; 472 473 return outTime; 474 } 475 476 psTime* psTMToTime(struct tm* time) 477 { 478 time_t localTimeInSeconds = 0; 479 time_t temp = 0; 480 struct tm *localTMTime = NULL; 481 psTime *outTime = NULL; 482 483 // NULL error check 484 CHECK_NULL_TIME(time,NULL); 485 486 // Allocate psTime struct 487 ALLOC_TIME(outTime); 488 489 // The mktime function returns seconds since last epoch in local time, so get local time and offset 490 localTimeInSeconds = mktime(time); 491 localTMTime = localtime(&temp); 492 493 // Convert to psTime 494 outTime->usec = 0; 495 outTime->sec = localTMTime->tm_gmtoff + localTimeInSeconds; 496 497 return outTime; 498 } 499 500 psTime* psTAIAdd(psTime *tai1, psTime *tai2) 501 { 502 psTime *outTime = NULL; 503 504 if(tai1->type != PS_TIME_TAI) { 505 psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type); 506 return NULL; 507 } 508 509 if(tai2->type != PS_TIME_TAI) { 510 psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type); 511 return NULL; 512 } 513 514 ALLOC_TIME(outTime); 515 516 outTime->sec = tai1->sec + tai2->sec; 517 outTime->usec = tai1->usec + tai2->usec; 518 519 // Increment seconds in case of microsecond overflow after addition 520 if(outTime->usec<tai1->usec || outTime->usec<tai2->usec) { 521 outTime->sec++; 522 } 523 524 return outTime; 525 } 526 527 psTime* psTAISub(psTime *tai1, psTime *tai2) 528 { 529 psTime *outTime = NULL; 530 531 if(tai1->type != PS_TIME_TAI) { 532 psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type); 533 return NULL; 534 } 535 536 if(tai2->type != PS_TIME_TAI) { 537 psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type); 538 return NULL; 539 } 540 541 ALLOC_TIME(outTime); 542 543 outTime->sec = tai1->sec - tai2->sec; 544 outTime->usec = tai1->usec - tai2->usec; 545 546 // Decrement seconds in case of microsecond underflow after subtraction 547 if(outTime->usec>tai1->usec || outTime->usec>tai2->usec) { 548 outTime->sec--; 549 } 550 551 return outTime; 552 } 553 554 psTime* psTAIDelta(psTime *tai1, psTime *tai2) 555 { 556 psTime *outTime = NULL; 557 558 if(tai1->type != PS_TIME_TAI) { 559 psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type); 560 return NULL; 561 } 562 563 if(tai2->type != PS_TIME_TAI) { 564 psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type); 565 return NULL; 566 } 567 568 ALLOC_TIME(outTime); 569 570 outTime->sec = tai1->sec - tai2->sec; 571 outTime->usec = tai1->usec - tai2->usec; 572 573 // Decrement seconds in case of microsecond underflow after subtraction 574 if(outTime->usec>tai1->usec || outTime->usec>tai2->usec) { 575 outTime->sec--; 576 } 577 578 outTime->sec = abs(outTime->sec); 579 580 581 return outTime; 582 } -
trunk/psLib/src/astronomy/psTime.h
r1529 r1614 1 2 1 /** @file psTime.h 3 2 * … … 7 6 * A collection of functions are required by psLib to manipulate time data. These functions primarily consist 8 7 * of conversions between specific time formats. PSLib currently uses the UNIX timeval time system as the 9 * base upon which International Atomic Time (TAI) time is calculated. All time conversion functions within 10 * psLib, except those noted, are calculated in terms of TAI time, which is approxinmately 32 seconds faster 11 * than UTC/timeval. 8 * base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI 9 * time varies over time due to the earth's rotation and the movement of the continental plates. It is 10 * currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates 11 * is given in the table below, which comes from: 12 * 13 * ftp://maia.usno.navy.mil/ser7/tai-utc.dat 14 * 15 * This table is placed into a static array and used by the psTime functions for conversions. 16 * 17 * 1961 JAN 1 =JD 2437300.5 TAI-UTC= 1.4228180 S + (MJD - 37300.) X 0.001296 S 18 * 1961 AUG 1 =JD 2437512.5 TAI-UTC= 1.3728180 S + (MJD - 37300.) X 0.001296 S 19 * 1962 JAN 1 =JD 2437665.5 TAI-UTC= 1.8458580 S + (MJD - 37665.) X 0.0011232S 20 * 1963 NOV 1 =JD 2438334.5 TAI-UTC= 1.9458580 S + (MJD - 37665.) X 0.0011232S 21 * 1964 JAN 1 =JD 2438395.5 TAI-UTC= 3.2401300 S + (MJD - 38761.) X 0.001296 S 22 * 1964 APR 1 =JD 2438486.5 TAI-UTC= 3.3401300 S + (MJD - 38761.) X 0.001296 S 23 * 1964 SEP 1 =JD 2438639.5 TAI-UTC= 3.4401300 S + (MJD - 38761.) X 0.001296 S 24 * 1965 JAN 1 =JD 2438761.5 TAI-UTC= 3.5401300 S + (MJD - 38761.) X 0.001296 S 25 * 1965 MAR 1 =JD 2438820.5 TAI-UTC= 3.6401300 S + (MJD - 38761.) X 0.001296 S 26 * 1965 JUL 1 =JD 2438942.5 TAI-UTC= 3.7401300 S + (MJD - 38761.) X 0.001296 S 27 * 1965 SEP 1 =JD 2439004.5 TAI-UTC= 3.8401300 S + (MJD - 38761.) X 0.001296 S 28 * 1966 JAN 1 =JD 2439126.5 TAI-UTC= 4.3131700 S + (MJD - 39126.) X 0.002592 S 29 * 1968 FEB 1 =JD 2439887.5 TAI-UTC= 4.2131700 S + (MJD - 39126.) X 0.002592 S 30 * 1972 JAN 1 =JD 2441317.5 TAI-UTC= 10.0 S + (MJD - 41317.) X 0.0 S 31 * 1972 JUL 1 =JD 2441499.5 TAI-UTC= 11.0 S + (MJD - 41317.) X 0.0 S 32 * 1973 JAN 1 =JD 2441683.5 TAI-UTC= 12.0 S + (MJD - 41317.) X 0.0 S 33 * 1974 JAN 1 =JD 2442048.5 TAI-UTC= 13.0 S + (MJD - 41317.) X 0.0 S 34 * 1975 JAN 1 =JD 2442413.5 TAI-UTC= 14.0 S + (MJD - 41317.) X 0.0 S 35 * 1976 JAN 1 =JD 2442778.5 TAI-UTC= 15.0 S + (MJD - 41317.) X 0.0 S 36 * 1977 JAN 1 =JD 2443144.5 TAI-UTC= 16.0 S + (MJD - 41317.) X 0.0 S 37 * 1978 JAN 1 =JD 2443509.5 TAI-UTC= 17.0 S + (MJD - 41317.) X 0.0 S 38 * 1979 JAN 1 =JD 2443874.5 TAI-UTC= 18.0 S + (MJD - 41317.) X 0.0 S 39 * 1980 JAN 1 =JD 2444239.5 TAI-UTC= 19.0 S + (MJD - 41317.) X 0.0 S 40 * 1981 JUL 1 =JD 2444786.5 TAI-UTC= 20.0 S + (MJD - 41317.) X 0.0 S 41 * 1982 JUL 1 =JD 2445151.5 TAI-UTC= 21.0 S + (MJD - 41317.) X 0.0 S 42 * 1983 JUL 1 =JD 2445516.5 TAI-UTC= 22.0 S + (MJD - 41317.) X 0.0 S 43 * 1985 JUL 1 =JD 2446247.5 TAI-UTC= 23.0 S + (MJD - 41317.) X 0.0 S 44 * 1988 JAN 1 =JD 2447161.5 TAI-UTC= 24.0 S + (MJD - 41317.) X 0.0 S 45 * 1990 JAN 1 =JD 2447892.5 TAI-UTC= 25.0 S + (MJD - 41317.) X 0.0 S 46 * 1991 JAN 1 =JD 2448257.5 TAI-UTC= 26.0 S + (MJD - 41317.) X 0.0 S 47 * 1992 JUL 1 =JD 2448804.5 TAI-UTC= 27.0 S + (MJD - 41317.) X 0.0 S 48 * 1993 JUL 1 =JD 2449169.5 TAI-UTC= 28.0 S + (MJD - 41317.) X 0.0 S 49 * 1994 JUL 1 =JD 2449534.5 TAI-UTC= 29.0 S + (MJD - 41317.) X 0.0 S 50 * 1996 JAN 1 =JD 2450083.5 TAI-UTC= 30.0 S + (MJD - 41317.) X 0.0 S 51 * 1997 JUL 1 =JD 2450630.5 TAI-UTC= 31.0 S + (MJD - 41317.) X 0.0 S 52 * 1999 JAN 1 =JD 2451179.5 TAI-UTC= 32.0 S + (MJD - 41317.) X 0.0 S 12 53 * 13 54 * @author Ross Harman, MHPCC 14 55 * 15 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $16 * @date $Date: 2004-08- 13 22:08:51$56 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 57 * @date $Date: 2004-08-25 01:37:45 $ 17 58 * 18 59 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 31 72 /// @{ 32 73 33 /******************************************************************************/ 34 35 /* TYPE DEFINITIONS */ 36 37 /******************************************************************************/ 74 75 /** Time type. 76 * 77 * Enumeration for psTime types, TAI or UTC time. 78 */ 79 typedef enum { 80 PS_TIME_TAI, ///< Temps Atomique International (TAI) time (time with leapseconds). 81 PS_TIME_UTC, ///< Universal Time Coordinated (UTC) time (time without leapseconds). 82 } psTimeType; 38 83 39 84 /** Definition of psTime. 40 85 * 41 * The psTime struct is used by psLib to represent time values critical to 42 * astronomical calculations. This structure represents a time which is 43 * equivalent to TAI (International Atomic Time) and is measured in both 86 * The psTime struct is used by psLib to represent time values critical to 87 * astronomical calculations. This structure represents a time which is 88 * equivalent to TAI (International Atomic Time) and is measured in both 44 89 * seconds and microseconds. 45 90 */ 46 typedef struct timeval psTime; 47 48 /*****************************************************************************/ 49 50 /* FUNCTION PROTOTYPES */ 51 52 /*****************************************************************************/ 53 54 /** Get current TAI time. 55 * 56 * Gets current time from the system clock in correct TAI units. 57 * 58 * @return psTime: Struct with current time. 59 */ 60 61 psTime psTimeGetTime(void); 62 63 /** Convert psTime to ISO time in TAI units. 64 * 65 * Converts psTime to a null terminated string in the form of: 66 * YYYY/MM/DD,HH:MM:SS.SSS. This function assumes the input time already is 67 * in TAI time and does not add or subtract leapseconds. 91 typedef struct psTime 92 { 93 psS64 sec; ///< Seconds since epoch, Jan 1, 1970. 94 psU32 usec; ///< Microseconds since last second. 95 psTimeType type; ///< Type of time. 96 } 97 psTime; 98 99 /** Get current time. 100 * 101 * Gets current time from the system clock. User must specify the psTimeType (PS_TIME_TAI or PS_TIME_UTC) in 102 * the argument. 103 * 104 * @return psTime*: Struct with current time. 105 */ 106 psTime* psTimeGetTime( 107 psTimeType type ///< Type of time to get (UTC or TAI). 108 ); 109 110 111 /** Convert psTime to UTC or TAI time. 112 * 113 * Converts psTime to UTC or TAI time based on the psTimeType argument. 114 * 115 * @return psTime*: Pointer to psTime. 116 */ 117 psTime* psTimeConvert( 118 psTime *time, 119 psTimeType type 120 ); 121 122 /** Convert psTime to Local Mean Sidereal Time (LST). 123 * 124 * Converts psTime at the given longitude to LST time. If the input time is not in UTC format, then it is 125 * converted. 126 * 127 * @return double: LST Time. 128 */ 129 double psTimeToLST( 130 psTime *time, ///< psTime to be converted. 131 double longitude ///< Longitude. 132 ); 133 134 /** Convert Local Mean Sidereal Time (LST) to psTime. 135 * 136 * Converts LST time to psTime. 137 * 138 * @return psTime*: Pointer to psTime. 139 */ 140 psTime* psLSTToTime( 141 double time, ///< LST time to be converted. 142 double longitude ///< Longitude. 143 ); 144 145 /** Determine UT1 - UTC from table lookup. 146 * 147 * This function is necessary to for various SLALIB functions. 148 * 149 * @return double: Time difference. 150 */ 151 double psGetUT1Delta( 152 psTime *time ///< psTime to be looked up. 153 ); 154 155 /** Determine TAI - UTC from table lookup. 156 * 157 * This function is necessary to for various psTime functions. 158 * 159 * @return double: Time difference. 160 */ 161 double psGetTAIDelta( 162 psTime *time ///< psTime to be looked up. 163 ); 164 165 /** Determine polar coordinates at a given time. 166 * 167 * Determines the orientation of the polar axis at the given time. 168 * 169 * @return psSphere*: Spherical coordinates of Earth's polar axias. 170 */ 171 /*psSphere* psGetPoleCoords( 172 psTime *time ///< psTime determine polar orientation. 173 );*/ 174 175 /** Convert psTime to Julian date time. 176 * 177 * Converts psTime to Julian date (JD) time. This function does not add or subtract leapseconds. 178 * 179 * @return double: Julian Date (JD) time. 180 */ 181 double psTimeToJD( 182 psTime *time ///< Input time to be converted. 183 ); 184 /** Convert psTime to modified Julian date time. 185 * 186 * Converts psTime to modified Julian date (MJD) time. This function does not add or subtract leapseconds. 187 * 188 * @return double: Modified Julian Days (MJD) time. 189 */ 190 double psTimeToMJD( 191 psTime *time ///< Input time to be converted. 192 ); 193 194 /** Convert psTime to ISO8601 formatted string. 195 * 196 * Converts psTime to a null terminated string in the form of YYYY-MM-DDThh:mm:ss.sss. This function does not 197 * add or subtract leapseconds. 68 198 * 69 199 * @return char*: Pointer null terminated array of chars in ISO time. 70 200 */ 71 72 char *psTimeToISO( 73 psTime time ///< Input time to be converted. 74 ); 75 76 /** Convert psTime to UTC time. 77 * 78 * Converts psTime to UTC time in double precision floating point notation. 79 * The input to this must already be int TAI time. The result from this 80 * function is not in TAI units, but that of UTC, which does not contain 81 * leapseconds. 82 * 83 * @return psTime: UTC time psTime format. 84 */ 85 86 psTime psTimeToUTC( 87 psTime time ///< Input time to be converted. 88 ); 89 90 /** Convert psTime to modified Julian date time. 91 * 92 * Converts psTime to modified Julian date (MJD) time. This function assumes 93 * the input time already is in TAI time and does not add or subtract 94 * leapseconds. 95 * 96 * @return double: Modified Julian Days (MJD) time. 97 */ 98 double psTimeToMJD( 99 psTime time ///< Input time to be converted. 100 ); 101 102 /** Convert psTime to Julian date time. 103 * 104 * Converts psTime to Julian date (JD) time. This function assumes the input 105 * time already is in TAI time and does not add or subtract leapseconds. 106 * 107 * @return double: Julian Date (JD) time. 108 */ 109 double psTimeToJD( 110 psTime time ///< Input time to be converted. 201 char* psTimeToISO( 202 psTime *time ///< Input time to be converted. 111 203 ); 112 204 113 205 /** Convert psTime to timeval time. 114 206 * 115 * Converts psTime to timeval time. This function assumes the input time 116 * already is in TAI time and does not add or subtract leapseconds. 207 * Converts psTime to timeval time. This function does not add or subtract leapseconds. 117 208 * 118 209 * @return timeval: timeval struct time. 119 210 */ 120 211 struct timeval psTimeToTimeval( 121 psTime time ///< Input time to be converted.212 psTime *time ///< Input time to be converted. 122 213 ); 123 214 124 215 /** Convert psTime to tm time. 125 216 * 126 * Converts psTime to tm time. This function assumes the input time already is in TAI time and does not add or 127 * subtract leapseconds. 217 * Converts psTime to tm time. This function does not add or subtract leapseconds. 128 218 * 129 219 * @return tm: tm struct time. 130 220 */ 131 struct tm *psTimeToTM(132 psTime time ///< Input time to be converted.221 struct tm* psTimeToTM( 222 psTime *time ///< Input time to be converted. 133 223 ); 134 224 225 /** Convert JD to psTime. 226 * 227 * Converts JD time to psTime. This function does not add or subtract leapseconds. 228 * 229 * @return psTime: time. 230 */ 231 psTime* psJDToTime( 232 double time ///< Input time to be converted. 233 ); 234 235 /** Convert MJD to psTime. 236 * 237 * Converts MJD time to psTime. This function does not add or subtract leapseconds. 238 * 239 * @return psTime: time. 240 */ 241 psTime* psMJDToTime( 242 double time ///< Input time to be converted. 243 ); 244 135 245 /** Convert ISO to psTime. 136 246 * 137 * Converts ISO time to psTime. This function assumes the input time already 138 * is in TAI time and does not add or subtract leapseconds. 139 * 140 * @return psTime: time 141 */ 142 psTime psISOToTime( 247 * Converts ISO time to psTime. This function does not add or subtract leapseconds. 248 * 249 * @return psTime*: time 250 */ 251 psTime* psISOToTime( 143 252 char *time ///< Input time to be converted. 144 253 ); 145 254 146 /** Convert UTC to psTime.147 *148 * Converts UTC time to psTime. This function assumes the input time already149 * is in TAI time and add or subtracts the necessary leapseconds.150 *151 * @return psTime: time in TAI units.152 */153 psTime psUTCToTime(154 psTime time ///< Input time to be converted.155 );156 157 /** Convert MJD to psTime.158 *159 * Converts MJD time to psTime. This function assumes the input time already160 * is in TAI time and does not add or subtract leapseconds.161 *162 * @return psTime: time.163 */164 psTime psMJDToTime(165 double time ///< Input time to be converted.166 );167 168 /** Convert JD to psTime.169 *170 * Converts JD time to psTime. This function assumes the input time already171 * is in TAI time and does not add or subtract leapseconds.172 *173 * @return psTime: time.174 */175 psTime psJDToTime(176 double time ///< Input time to be converted.177 );178 179 255 /** Convert timeval to psTime. 180 256 * 181 * Converts timeval time to psTime. This function assumes the input time 182 * already is in TAI time and does not add or subtract leapseconds. 183 * 184 * @return psTime: time. 185 */ 186 psTime psTimevalToTime( 187 struct timeval *time ///< Input time to be converted. 257 * Converts timeval time to psTime. This function does not add or subtract leapseconds. 258 * 259 * @return psTime*: time. 260 */ 261 psTime* psTimevalToTime( 262 struct timeval *time ///< Input time to be converted. 188 263 ); 189 264 190 265 /** Convert tm time to psTime. 191 266 * 192 * Converts tm time to psTime. This function assumes the input time already 193 * is in TAI time and does not add or subtract leapseconds. 194 * 195 * @return psTime: time. 196 */ 197 psTime psTMToTime( 267 * Converts tm time to psTime. This function does not add or subtract leapseconds. 268 * 269 * @return psTime*: time. 270 */ 271 psTime* psTMToTime( 198 272 struct tm *time ///< Input time to be converted. 199 273 ); 200 274 275 /** Add two TAI times. 276 * 277 * Adds two TAI times. This function does not add or subtract leapseconds. 278 * 279 * @return psTime*: time. 280 */ 281 psTime* psTAIAdd( 282 psTime *tai1, ///< First TAI time. 283 psTime *tai2 ///< Second TAI time. 284 ); 285 286 /** Subtract two TAI times. 287 * 288 * Subtracts two TAI times. This function does not add or subtract leapseconds. 289 * 290 * @return psTime*: time. 291 */ 292 psTime* psTAISub( 293 psTime *tai1, ///< First TAI time. 294 psTime *tai2 ///< Second TAI time. 295 ); 296 297 298 /** Find delta of two TAI times. 299 * 300 * Finds the absolute difference of two TAI times. This function does not add or subtract leapseconds. 301 * 302 * @return psTime*: time. 303 */ 304 psTime* psTAIDelta( 305 psTime *tai1, ///< First TAI time. 306 psTime *tai2 ///< Second TAI time. 307 ); 201 308 /// @} 202 309
Note:
See TracChangeset
for help on using the changeset viewer.
