Changeset 1247 for trunk/psLib/src/astronomy/psTime.c
- Timestamp:
- Jul 20, 2004, 3:29:33 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/astronomy/psTime.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astronomy/psTime.c
r1223 r1247 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1. 1$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-07- 15 19:02:13 $14 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-07-21 01:29:33 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 24 24 25 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 26 28 27 29 #include "psTime.h" 28 30 #include "psError.h" 31 #define PS_ALLOW_MALLOC 32 #include "psMemory.h" 29 33 30 34 /******************************************************************************/ … … 32 36 /******************************************************************************/ 33 37 34 // Number of available leapsecond updates 35 #define NUM_LEAPSECOND_UPDATES 23 38 /** Preprocessor macro to generate error for negative time in struct */ 39 #define CHECK_NEGATIVE_TIME_STRUCT(NAME,RETURN) \ 40 if(NAME.tv_sec < 0) { \ 41 psError(__func__,"Negative seconds are not allowed: %ld", NAME.tv_sec); \ 42 return RETURN; \ 43 } else if(NAME.tv_usec<0) { \ 44 psError(__func__,"Negative microseconds are not allowed: %ld", NAME.tv_usec); \ 45 return RETURN; \ 46 } 47 48 /** Preprocessor macro to generate error for negative time */ 49 #define CHECK_NEGATIVE_TIME(NAME,RETURN) \ 50 if(NAME < 0.0) { \ 51 psError(__func__,"Negative time is not allowed: %f", NAME); \ 52 return RETURN; \ 53 } \ 36 54 37 55 /******************************************************************************/ … … 55 73 the psTimeGetTime() function to calculate TAI time from UTC time. 56 74 57 1972 JAN 1 =JD 2441317.5 TAI-UTC=10.058 1972 JUL 1 =JD 2441499.5 TAI-UTC=11.059 1973 JAN 1 =JD 2441683.5 TAI-UTC=12.060 1974 JAN 1 =JD 2442048.5 TAI-UTC=13.061 1975 JAN 1 =JD 2442413.5 TAI-UTC=14.062 1976 JAN 1 =JD 2442778.5 TAI-UTC=15.063 1977 JAN 1 =JD 2443144.5 TAI-UTC=16.064 1978 JAN 1 =JD 2443509.5 TAI-UTC=17.065 1979 JAN 1 =JD 2443874.5 TAI-UTC=18.066 1980 JAN 1 =JD 2444239.5 TAI-UTC=19.067 1981 JUL 1 =JD 2444786.5 TAI-UTC=20.068 1982 JUL 1 =JD 2445151.5 TAI-UTC=21.069 1983 JUL 1 =JD 2445516.5 TAI-UTC=22.070 1985 JUL 1 =JD 2446247.5 TAI-UTC=23.071 1988 JAN 1 =JD 2447161.5 TAI-UTC=24.072 1990 JAN 1 =JD 2447892.5 TAI-UTC=25.073 1991 JAN 1 =JD 2448257.5 TAI-UTC=26.074 1992 JUL 1 =JD 2448804.5 TAI-UTC=27.075 1993 JUL 1 =JD 2449169.5 TAI-UTC=28.076 1994 JUL 1 =JD 2449534.5 TAI-UTC=29.077 1996 JAN 1 =JD 2450083.5 TAI-UTC=30.078 1997 JUL 1 =JD 2450630.5 TAI-UTC=31.079 1999 JAN 1 =JD 2451179.5 TAI-UTC=32.075 1972 JAN 1 = JD 2441317.5 TAI-UTC = 10.0 76 1972 JUL 1 = JD 2441499.5 TAI-UTC = 11.0 77 1973 JAN 1 = JD 2441683.5 TAI-UTC = 12.0 78 1974 JAN 1 = JD 2442048.5 TAI-UTC = 13.0 79 1975 JAN 1 = JD 2442413.5 TAI-UTC = 14.0 80 1976 JAN 1 = JD 2442778.5 TAI-UTC = 15.0 81 1977 JAN 1 = JD 2443144.5 TAI-UTC = 16.0 82 1978 JAN 1 = JD 2443509.5 TAI-UTC = 17.0 83 1979 JAN 1 = JD 2443874.5 TAI-UTC = 18.0 84 1980 JAN 1 = JD 2444239.5 TAI-UTC = 19.0 85 1981 JUL 1 = JD 2444786.5 TAI-UTC = 20.0 86 1982 JUL 1 = JD 2445151.5 TAI-UTC = 21.0 87 1983 JUL 1 = JD 2445516.5 TAI-UTC = 22.0 88 1985 JUL 1 = JD 2446247.5 TAI-UTC = 23.0 89 1988 JAN 1 = JD 2447161.5 TAI-UTC = 24.0 90 1990 JAN 1 = JD 2447892.5 TAI-UTC = 25.0 91 1991 JAN 1 = JD 2448257.5 TAI-UTC = 26.0 92 1992 JUL 1 = JD 2448804.5 TAI-UTC = 27.0 93 1993 JUL 1 = JD 2449169.5 TAI-UTC = 28.0 94 1994 JUL 1 = JD 2449534.5 TAI-UTC = 29.0 95 1996 JAN 1 = JD 2450083.5 TAI-UTC = 30.0 96 1997 JUL 1 = JD 2450630.5 TAI-UTC = 31.0 97 1999 JAN 1 = JD 2451179.5 TAI-UTC = 32.0 80 98 */ 81 99 82 // Julian date of leapsecond update and current total number of leapseconds forthat date100 // Table for Julian date of leapsecond update and current total number of leapseconds at that date 83 101 static double leapseconds[NUM_LEAPSECOND_UPDATES][2] = 84 102 { … … 135 153 time.tv_usec = now.tv_usec; 136 154 137 // Add last known leapsecondsto UTC time to get TAI time155 // Add most current leapseconds value to UTC time to get TAI time 138 156 time.tv_sec += leapseconds[NUM_LEAPSECOND_UPDATES][1]; 139 157 … … 143 161 char* psTimeToISO(psTime time) 144 162 { 145 struct tm *tm; 146 tm = localtime (&time.tv_sec); 147 printf("%d\n", tm->tm_sec); 148 return NULL; 149 } 163 int ms = 0; 164 char *timeString = NULL; 165 char *tempString = NULL; 166 struct tm *tmTime = NULL; 167 168 CHECK_NEGATIVE_TIME_STRUCT(time,NULL); 169 170 tempString = psAlloc(MAX_TIME_STRING_LENGTH); 171 timeString = psAlloc(MAX_TIME_STRING_LENGTH); 172 173 // Converts psTime to YYYY/MM/DD,HH:MM:SS.SSS in string form 174 ms = time.tv_usec/1000; 175 tmTime = gmtime(&time.tv_sec); 176 if(!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y/%m/%d,%H:%M:%S", tmTime)) { 177 psError(__func__, " : Line %d - Failed strftime conversion", __LINE__); 178 } 179 180 if(snprintf(timeString,MAX_TIME_STRING_LENGTH,"%s.%3.3d", tempString, ms) < 0) { 181 psError(__func__, " : Line %d - Failed snprintf conversion", __LINE__); 182 } 183 psFree(tempString); 184 free(tmTime); 185 186 return timeString; 187 } 188 189 psTime psTimeToUTC(psTime time) 190 { 191 int i = 0; 192 double jd = 0.0; 193 double ls = 0.0; 194 double *jdTable = NULL; 195 psTime outTime; 196 197 CHECK_NEGATIVE_TIME_STRUCT(time,outTime); 198 199 // Find leapseconds to subtract from psTime to get UTC time 200 jd = psTimeToJD(time); 201 jdTable = leapseconds[0]; 202 for(i=0; i<NUM_LEAPSECOND_UPDATES; i++, jdTable+=2) { 203 if(jd > *jdTable) { 204 ls = *(jdTable + 1); 205 } 206 } 207 208 outTime.tv_sec = time.tv_sec - ls; 209 outTime.tv_usec = time.tv_usec; 210 211 CHECK_NEGATIVE_TIME_STRUCT(outTime,outTime); 212 213 return outTime; 214 } 215 216 double psTimeToMJD(psTime time) 217 { 218 double mjd = 0.0; 219 220 CHECK_NEGATIVE_TIME_STRUCT(time,mjd); 221 222 // Modified Julian date conversion courtesy of Eugene Magnier 223 mjd = time.tv_sec/SEC_PER_DAY + time.tv_usec/USEC_PER_DAY + 40587.0; 224 225 return mjd; 226 } 227 228 double psTimeToJD(psTime time) 229 { 230 double jd = 0.0; 231 232 CHECK_NEGATIVE_TIME_STRUCT(time,jd); 233 234 // Julian date conversion courtesy of Eugene Magnier 235 jd = time.tv_sec/SEC_PER_DAY + time.tv_usec/USEC_PER_DAY + 2440587.5; 236 237 return jd; 238 } 239 240 struct timeval psTimeToTimeval(psTime time) 241 { 242 struct timeval timevalTime; 243 244 CHECK_NEGATIVE_TIME_STRUCT(time,timevalTime); 245 timevalTime.tv_sec = time.tv_sec; 246 timevalTime.tv_usec = time.tv_usec; 247 248 return timevalTime; 249 } 250 251 struct tm* psTimeToTM(psTime time) 252 { 253 struct tm *tmTime = NULL; 254 255 CHECK_NEGATIVE_TIME_STRUCT(time,tmTime); 256 tmTime = gmtime(&time.tv_sec); 257 258 return tmTime; 259 } 260 261 psTime psISOToTime(char *time) 262 { 263 char tempString[MAX_TIME_STRING_LENGTH]; 264 int month; 265 int day; 266 int year; 267 int hour; 268 int minute; 269 int second; 270 int millisecond; 271 struct tm tmTime; 272 psTime outTime; 273 274 strncpy(tempString, time, MAX_TIME_STRING_LENGTH); 275 276 // Convert YYYY/MM/DD,HH:MM:SS.SSS in string form to tm time 277 year = atoi(strtok(tempString, "/")); 278 if(year < 0) { 279 psError(__func__,"Years less than 1900 not allowed. Value: %d", year); 280 } 281 282 month = atoi(strtok(tempString, "/")); 283 if(month<1 || month>12) { 284 psError(__func__,"Month must have a value from 0 to 11. Value: %d", month); 285 } 286 287 day = atoi(strtok(tempString, ",")); 288 if(day<1 || day>31) { 289 psError(__func__,"Day must have a value from 1 to 31. Value: %d", day); 290 } 291 292 hour = atoi(strtok(tempString, ":")); 293 if(hour<0 || hour>23) { 294 psError(__func__,"Hour must have a value from 0 to 23. Value: %d", hour); 295 } 296 297 second = atoi(strtok(tempString, ".")); 298 if(second<0 || second>60) { 299 psError(__func__,"Second must have a value from 0 to 59. Value: %d", second); 300 } 301 302 millisecond = atoi(strtok(tempString, "X")); 303 if(millisecond<0 || millisecond>1000) { 304 psError(__func__,"Second must have a value from 0 to 999. Value: %d", millisecond); 305 } 306 307 tmTime.tm_year = year - 1900; 308 tmTime.tm_mon = month - 1; 309 tmTime.tm_mday = day; 310 tmTime.tm_hour = hour; 311 tmTime.tm_min = minute; 312 tmTime.tm_sec = second; 313 314 // Convert tm time to psTime 315 outTime = psTMToTime(&tmTime); 316 outTime.tv_usec = millisecond*1000; 317 318 return outTime; 319 } 320 321 psTime psUTCToTime(psTime time) 322 { 323 psTime outTime; 324 325 CHECK_NEGATIVE_TIME_STRUCT(time,outTime); 326 327 // Convert UTC time to psTime/TAI 328 outTime.tv_sec = time.tv_sec + leapseconds[NUM_LEAPSECOND_UPDATES][1]; 329 ; 330 outTime.tv_usec = time.tv_usec; 331 CHECK_NEGATIVE_TIME_STRUCT(outTime,outTime); 332 333 return time; 334 } 335 336 psTime psMJDToTime(double time) 337 { 338 psTime outTime; 339 double days = 0.0; 340 double seconds = 0.0; 341 342 CHECK_NEGATIVE_TIME(time,outTime); 343 344 // Modified Julian date conversion courtesy of Eugene Magnier 345 days = time - 40587.0; 346 347 // Convert to psTime/TAI 348 seconds = days*SEC_PER_DAY; 349 outTime.tv_usec = (seconds -(long)seconds)*1000000.0; 350 outTime.tv_sec = seconds; 351 352 CHECK_NEGATIVE_TIME_STRUCT(outTime,outTime); 353 354 return outTime; 355 } 356 357 psTime psJDToTime(double time) 358 { 359 double days = 0.0; 360 double seconds = 0.0; 361 psTime outTime; 362 363 CHECK_NEGATIVE_TIME(time,outTime); 364 365 // Julian date conversion courtesy of Eugene Magnier 366 days = time - 2440587.5; 367 368 // Convert to psTime/TAI 369 seconds = days*SEC_PER_DAY; 370 outTime.tv_sec = seconds; 371 outTime.tv_usec = (seconds -(long)seconds)*1000000.0; 372 373 CHECK_NEGATIVE_TIME_STRUCT(outTime,outTime); 374 375 return outTime; 376 } 377 378 psTime psTimevalToTime(struct timeval *time) 379 { 380 psTime outTime; 381 if(time == NULL) 382 { 383 psError(__func__,"Null value for timeval arg not allowed"); 384 return outTime; 385 } else if(time->tv_sec < 0) 386 { 387 psError(__func__,"Negative seconds are not allowed: %ld", time->tv_sec); 388 return outTime; 389 } else if(time->tv_usec<0) 390 { 391 psError(__func__,"Negative microseconds are not allowed: %ld", time->tv_usec); 392 return outTime; 393 } 394 395 // Convert to psTime/TAI 396 outTime.tv_sec = time->tv_sec; 397 outTime.tv_usec = time->tv_usec; 398 399 CHECK_NEGATIVE_TIME_STRUCT(outTime,outTime); 400 401 return outTime; 402 } 403 404 405 psTime psTMToTime(struct tm *time) 406 { 407 int i; 408 int m; 409 int n; 410 int y; 411 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 412 long epoch; 413 psTime outTime; 414 415 i= 0; 416 m = 0; 417 n = 0; 418 y = 0; 419 epoch = 0; 420 421 if(time == NULL) 422 { 423 psError(__func__,"Null value for tm arg not allowed"); 424 return outTime; 425 } else if(time->tm_year < 70) 426 { 427 psError(__func__,"Input times earlier than 1970 not allowed"); 428 return outTime; 429 } 430 431 n = time->tm_year + 1900 - 1; 432 epoch = (time->tm_year - 70) * SEC_PER_YEAR + ((n/4 - n/100 + n/400) - 433 (1969/4 - 1969/100 + 1969/400)) * SEC_PER_DAY; 434 435 y = time->tm_year + 1900; 436 437 for(i = 0; i < time->tm_mon; i++) 438 { 439 epoch += mon [m] * SEC_PER_DAY; 440 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) { 441 epoch += SEC_PER_DAY; 442 } 443 444 if(++m > 11) { 445 m = 0; 446 y++; 447 } 448 } 449 450 epoch += (time->tm_mday - 1) * SEC_PER_DAY; 451 epoch += time->tm_hour *SEC_PER_HOUR + time->tm_min * SEC_PER_MINUTE + time->tm_sec; 452 453 outTime.tv_usec = 0; 454 outTime.tv_sec = epoch; 455 456 return outTime; 457 }
Note:
See TracChangeset
for help on using the changeset viewer.
