- Timestamp:
- Mar 5, 2009, 11:13:29 AM (17 years ago)
- Location:
- branches/cnb_branches/cnb_branch_20090215
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psLib/src/astro/psTime.c (modified) (88 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/cnb_branches/cnb_branch_20090215
-
branches/cnb_branches/cnb_branch_20090215/psLib/src/astro/psTime.c
r20595 r23197 9 9 * 10 10 * @author Ross Harman, MHPCC 11 * @author Paul Price, IfA 11 12 * 12 * @version $Revision: 1.117 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2008-11-09 00:30:07 $ 14 * 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 13 * Copyright 2004-2009 Institute for Astronomy, University of Hawaii 16 14 */ 17 15 18 16 #ifdef HAVE_CONFIG_H 19 # include "config.h"17 #include "config.h" 20 18 #endif 21 19 … … 39 37 #include "psAssert.h" 40 38 41 #define MAX_STRING_LENGTH 256 42 43 /** Sidereal angular conversion from seconds to radians for GMST in seconds (i.e. pi/(180*240)) */ 44 #define S2R (7.272205216643039903848711535369e-5) 45 46 /** Two times pi with double precision accuracy */ 47 #define TWOPI (2.0*M_PI) 48 49 /** Conversion from radians to degrees */ 50 #define R2DEG = (180.0/M_PI) 51 52 /** Maximum length of time string */ 53 #define MAX_TIME_STRING_LENGTH 256 54 55 /** Seconds per minute */ 56 #define SEC_PER_MINUTE 60.0 57 58 /** Seconds per hour */ 59 #define SEC_PER_HOUR (60.0*SEC_PER_MINUTE) 60 61 /** Seconds per day */ 62 #define SEC_PER_DAY (24.0*SEC_PER_HOUR) 63 64 /** Seconds per year */ 65 #define SEC_PER_YEAR (365.0*SEC_PER_DAY) 66 67 /** Microseconds per day */ 68 #define NSEC_PER_DAY 86400000000000.0 69 70 // Time config file path 71 static char *timeConfig = NULL; 72 73 /** Time metadata read from config file */ 74 static psMetadata *timeMetadata = NULL; 75 76 // Offset to convert terrestrial time(TT) to international atomic time(TAI) 77 #define TAI_TT_OFFSET_SECONDS 32 78 #define TAI_TT_OFFSET_NANOSECONDS 184000000 79 80 // Offset from converting to MJD 81 #define MJD_EPOCH_OFFSET 40587.0 82 83 // Offset for converting to JD 84 #define JD_EPOCH_OFFSET 2440587.5 85 86 // Offset of year 0000 from epoch 87 #define YEAR_0000_SEC -62125920000 88 89 // Offset of year 9999 from epoch 90 #define YEAR_9999_SEC 253202544000 39 40 #define S2R (M_PI / (180.0 * 240.0)) /// Sidereal conversion: GMST in seconds to radians 41 #define R2DEG = (180.0/M_PI) /// Conversion from radians to degrees 42 #define MAX_STRING_LENGTH 256 /// Maximum length of string 43 #define MAX_TIME_STRING_LENGTH 30 /// Maximum length of time string: 1234-67-90T23:56:89.123456789 44 #define SEC_PER_MINUTE 60.0 /// Seconds per minute 45 #define SEC_PER_HOUR (60.0*SEC_PER_MINUTE) /// Seconds per hour 46 #define SEC_PER_DAY (24.0*SEC_PER_HOUR) /// Seconds per day 47 #define SEC_PER_YEAR (365.0*SEC_PER_DAY) /// Seconds per year 48 #define NSEC_PER_DAY (SEC_PER_DAY * 1000000000.0) /// Nanoseconds per day 49 50 #define MJD_EPOCH_OFFSET 40587.0 // Offset from converting to MJD 51 #define JD_EPOCH_OFFSET 2440587.5 // Offset for converting to JD 52 #define YEAR_0000_SEC -62125920000 // Offset of year 0000 from epoch 53 #define YEAR_9999_SEC 253202544000 // Offset of year 9999 from epoch 54 55 // Offset to convert terrestrial time (TT) to international atomic time (TAI) 56 #define TAI_TT_OFFSET_SECONDS 32 57 #define TAI_TT_OFFSET_NANOSECONDS 184000000 58 59 60 // Static global variables 61 static char *timeConfig = NULL; // Time config file path 62 static psMetadata *timeMetadata = NULL; // Time metadata read from config file 63 static int isoDecimals = 6; // Number of decimals to use in a string by psTimeToISO 64 91 65 92 66 /** Static function prototypes */ 93 67 static char *cleanString(char *inString, int sLen); 94 68 static char* getToken(char **inString, char *delimiter, psParseErrorType *status); 95 static psTime*convertTimeTAIUTC(psTime* time);96 static psTime*convertTimeUTCTAI(psTime* time);97 static psTime*convertTimeTAITT(psTime* time);98 static psTime*convertTimeTTTAI(psTime* time);99 static psTime*convertTimeUTCUT1(psTime* time);100 101 static bool p_psTimeInit(const char *fileName);69 static bool convertTimeTAIUTC(psTime* time); 70 static bool convertTimeUTCTAI(psTime* time); 71 static bool convertTimeTAITT(psTime* time); 72 static bool convertTimeTTTAI(psTime* time); 73 static bool convertTimeUTCUT1(psTime* time); 74 75 static bool timeInit(const char *fileName); 102 76 103 77 /** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null 104 78 * terminated copy of the original input string. */ 105 static char *cleanString(char *inString, 106 int sLen) 107 { 108 char *ptrB = NULL; 109 char *ptrE = NULL; 110 char *cleaned = NULL; 111 112 ptrB = inString; 79 static char *cleanString(char *inString,// Input string 80 int sLen // Length of string 81 ) 82 { 83 char *ptrB = inString; // Pointer to start 113 84 114 85 // Skip over leading # or whitespace 115 while (isspace(*ptrB) || *ptrB =='#') {86 while (isspace(*ptrB) || *ptrB == '#') { 116 87 ptrB++; 117 88 } 118 89 119 90 // Skip over trailing whitespace, null terminators, and # characters 120 ptrE = inString + sLen - 1;121 while (isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {91 char *ptrE = inString + sLen - 1; // Pointer to end 92 while (isspace(*ptrE) || *ptrE == '\0' || *ptrE == '#') { 122 93 ptrE--; 123 94 } … … 127 98 128 99 // Adds '\0' to end of string and +1 to sLen 129 cleaned = psStringNCopy(ptrB, sLen); 130 131 return cleaned; 100 return psStringNCopy(ptrB, sLen); 132 101 } 133 102 134 103 /** Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location 135 104 * the beginning of the string. Tokens are newly allocated null terminated strings. */ 136 static char* getToken(char **inString, 137 char *delimiter, 138 psParseErrorType *status) 139 { 140 char *cleanToken = NULL; 141 int sLen = 0; 142 105 static char* getToken(char **inString, // Input string 106 char *delimiter, // Delimiter 107 psParseErrorType *status // Parsing status, returned 108 ) 109 { 143 110 // Skip over leading whitespace 144 while (isspace(**inString)) {111 while (isspace(**inString)) { 145 112 (*inString)++; 146 113 } 147 114 148 // Length of token, not including delimiter 149 sLen = strcspn(*inString, delimiter); 150 151 if(sLen) { 152 115 int sLen = strcspn(*inString, delimiter); // Length of token, not including delimiter 116 char *cleanToken = NULL; // Token, cleaned of delimiters 117 if (sLen) { 153 118 // Create new, cleaned, and null terminated token 154 119 cleanToken = cleanString(*inString, sLen); 155 120 156 121 // Move to end of token 157 // (*inString) += (sLen+1);158 122 (*inString) += sLen; 159 123 if (**inString != '\0' ) { 160 124 (*inString)++; 161 125 } 162 163 } else if(**inString!='\0' && sLen==0) { 126 } else if (**inString != '\0' && sLen == 0) { 164 127 *status = PS_PARSE_ERROR_GENERAL; 165 128 } … … 210 173 211 174 // Check if psTime tables are already loaded 212 if (!p_psTimeInit(p_psTimeConfigFilename(NULL))) {175 if (!timeInit(p_psTimeConfigFilename(NULL))) { 213 176 *status = PS_LOOKUP_ERROR; 214 177 return NAN; … … 225 188 226 189 // Check if table not a metadata item 227 if (tableMetadataItem == NULL) {190 if (tableMetadataItem == NULL) { 228 191 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 229 192 tableName); … … 239 202 240 203 // Check if index within to/from range 241 if (index >= table->validFrom ) {242 if (index <= table->validTo) {204 if (index >= table->validFrom ) { 205 if (index <= table->validTo) { 243 206 // Attempt to interpolate table 244 207 result = psLookupTableInterpolate(table, index, column); 245 208 *status = PS_LOOKUP_SUCCESS; 246 if (!isnan(result)) {209 if (!isnan(result)) { 247 210 break; 248 211 } … … 258 221 } 259 222 260 bool p_psTimeInit(const char *fileName)223 static bool timeInit(const char *fileName) 261 224 { 262 225 psS32 numLines = 0; … … 270 233 char *tableName = NULL; 271 234 char *tableFormat = NULL; 272 char *fullTableName = NULL;273 psS32 i = 0;274 psS32 j = 0;275 235 psS32 numTables = 0; 276 236 psU32 nFail = 0; … … 283 243 char metadataTableNames[4][MAX_STRING_LENGTH] = {"daily", "eopc", "finals", "tai"}; 284 244 285 // Check if the p_psTimeInit has already been ran286 if (timeMetadata != NULL) {245 // Check if the timeInit has already been run 246 if (timeMetadata) { 287 247 return true; 288 248 } 289 249 250 // All memory allocated below is "persistent" 290 251 // XXX this is not thread safe as the persistence setting is global 291 const bool initialPersistence = 292 p_psMemAllocatePersistent(true); // All memory allocated below is "persistent" 252 const bool initialPersistence = p_psMemAllocatePersistent(true); // Initial setting of persistence 293 253 294 254 // Read config file 295 255 timeMetadata = psMetadataConfigRead(timeMetadata, &nFail, fileName, true); 296 if(timeMetadata == NULL) { 256 if (!timeMetadata) { 257 psError(PS_ERR_IO, false, "Unable to read time configuration file %s", fileName); 297 258 return false; 298 } else if(nFail != 0) { 259 } else if (nFail != 0) { 260 psError(PS_ERR_IO, false, "Failed to parse %d lines reading time configuration file %s", 261 nFail, fileName); 299 262 return false; 300 263 } … … 302 265 // Get number of tables 303 266 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.n"); 304 if (metadataItem == NULL) {267 if (metadataItem == NULL) { 305 268 p_psMemAllocatePersistent(initialPersistence); 306 269 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 312 275 // Get lower range of tables 313 276 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.from"); 314 if (metadataItem == NULL) {277 if (metadataItem == NULL) { 315 278 p_psMemAllocatePersistent(initialPersistence); 316 279 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 319 282 } 320 283 tablesFrom = psVectorCopy(tablesFrom, metadataItem->data.V, PS_TYPE_F64); 321 if (tablesFrom->n != numTables) {284 if (tablesFrom->n != numTables) { 322 285 p_psMemAllocatePersistent(initialPersistence); 323 286 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Incorrect vector size. Size: %ld, Expected %d."), tablesFrom->n, numTables); … … 328 291 // Get upper range of tables 329 292 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.to"); 330 if (metadataItem == NULL) {293 if (metadataItem == NULL) { 331 294 p_psMemAllocatePersistent(initialPersistence); 332 295 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 336 299 } 337 300 tablesTo = psVectorCopy(tablesTo, metadataItem->data.V, PS_TYPE_F64); 338 if (tablesTo->n != numTables) {301 if (tablesTo->n != numTables) { 339 302 p_psMemAllocatePersistent(initialPersistence); 340 303 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Incorrect vector size. Size: %ld, Expected %d."), tablesTo->n, numTables); … … 346 309 // Get index columns for the tables 347 310 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.index"); 348 if (metadataItem == NULL) {311 if (metadataItem == NULL) { 349 312 p_psMemAllocatePersistent(initialPersistence); 350 313 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Failed find '%s' in time metadata."), … … 355 318 } 356 319 tablesIndex = psVectorCopy(tablesIndex, metadataItem->data.V, PS_TYPE_S32); 357 if (tablesIndex->n != numTables) {320 if (tablesIndex->n != numTables) { 358 321 p_psMemAllocatePersistent(initialPersistence); 359 322 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Incorrect vector size. Size: %ld, Expected %d."),tablesIndex->n,numTables); … … 366 329 // Get path to time data files 367 330 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.dir"); 368 if (metadataItem == NULL) {331 if (metadataItem == NULL) { 369 332 p_psMemAllocatePersistent(initialPersistence); 370 333 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 379 342 // Table file names 380 343 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.files"); 381 if (metadataItem == NULL) {344 if (metadataItem == NULL) { 382 345 p_psMemAllocatePersistent(initialPersistence); 383 346 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 394 357 // Get table format strings 395 358 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.format"); 396 if (metadataItem == NULL) {359 if (metadataItem == NULL) { 397 360 p_psMemAllocatePersistent(initialPersistence); 398 361 psError(PS_ERR_BAD_PARAMETER_VALUE,true, _("Failed find '%s' in time metadata."), … … 411 374 bool no_problem = true; // True if we've detected no errors 412 375 namesPtr = tableNames; 413 while((tableName=getToken(&namesPtr, " ", &status)) != NULL) { 414 415 // Form path with table name, adding one to length for last '/' that may not occur 416 // in string in cong file 417 fullTableName = (char*)psAlloc(strlen(tableDir)+strlen(tableName)+1+1); 418 419 // Old strings may come back from psAlloc(), so set initial position to EOL 420 fullTableName[0]='\0'; 421 strcat(fullTableName, tableDir); 422 strcat(fullTableName, "/"); 423 strcat(fullTableName, tableName); 376 int i; // Iterator 377 for (i = 0; (tableName = getToken(&namesPtr, " ", &status)) != NULL; i++) { 378 psString fullTableName = NULL; // Full path for table 379 psStringAppend(&fullTableName, "%s/%s", tableDir, tableName); 424 380 425 381 // Get table format 426 tableFormat = getToken(&formatPtr, ",",&status);427 if (tableFormat == NULL) {428 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem,_("Failed find '%s' in time metadata."),382 tableFormat = getToken(&formatPtr, ",", &status); 383 if (!tableFormat) { 384 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, _("Failed find '%s' in time metadata."), 429 385 "psLib.time.tables.format"); 430 386 no_problem = false; … … 432 388 433 389 // Create and read table 434 if (i < numTables) {390 if (i < numTables) { 435 391 table = psLookupTableAlloc(fullTableName, (const char*)tableFormat, tablesIndex->data.S32[i]); 436 392 numLines = psLookupTableRead(table); 437 393 } else { 438 394 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, 439 _("Incorrect number of table files entered. Found: %d. Expected: %d."), i +1, numTables);395 _("Incorrect number of table files entered. Found: %d. Expected: %d."), i + 1, numTables); 440 396 no_problem = false; 441 397 } … … 443 399 // Place tables into metadata slightly altered names as keys to create consistent naming conventions 444 400 foundTable = false; 445 for (j=0; j<numTables; j++) {401 for (int j = 0; j < numTables; j++) { 446 402 metadataNamesPtr = strstr(tableName, metadataTableNames[j]); 447 if (metadataNamesPtr != NULL) {403 if (metadataNamesPtr != NULL) { 448 404 psMetadataAdd(timeMetadata, PS_LIST_TAIL, strcat(metadataTableNames[j], "Table"), 449 405 PS_DATA_LOOKUPTABLE, NULL, table); 450 406 foundTable = true; 451 } else if (foundTable==false && j==numTables-1) {407 } else if (foundTable == false && j == numTables - 1) { 452 408 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, 453 409 _("Incorrect number of table files entered. Found: %d. Expected: %d."), j, numTables); … … 460 416 psFree(tableFormat); 461 417 psFree(table); 462 i++;463 418 } 464 419 465 420 p_psMemAllocatePersistent(initialPersistence); 466 421 467 if(numTables != i) { 468 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, _("Incorrect number of table files entered. Found: %d. Expected: %d."), i, numTables); 422 if (numTables != i) { 423 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, 424 _("Incorrect number of table files entered. Found: %d. Expected: %d."), 425 i, numTables); 469 426 } 470 427 … … 481 438 bool p_psTimeFinalize(void) 482 439 { 483 if (timeMetadata != NULL) {440 if (timeMetadata != NULL) { 484 441 psFree(timeMetadata); 485 442 timeMetadata = NULL; … … 496 453 psTime* psTimeAlloc(psTimeType type) 497 454 { 498 psTime *outTime = NULL;499 500 455 // Error checks 501 if(type!=PS_TIME_TAI && type!=PS_TIME_UTC && type!=PS_TIME_UT1 && 502 type!=PS_TIME_TT) { 503 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 504 _("Specified type, %d, is not supported."), 505 type); 506 return NULL; 456 switch (type) { 457 case PS_TIME_TAI: 458 case PS_TIME_UTC: 459 case PS_TIME_UT1: 460 case PS_TIME_TT: 461 // No action 462 break; 463 default: 464 // Since we can never return NULL from an allocator 465 psAbort("Specified type, %d, is not supported.", type); 507 466 } 508 467 509 468 // Allocate memory for structure 510 outTime = (psTime*)psAlloc(sizeof(psTime));469 psTime *outTime = psAlloc(sizeof(psTime)); 511 470 psMemSetDeallocator(outTime, (psFreeFunc)timeFree); 471 512 472 // Initialize members 513 473 outTime->sec = 0; … … 522 482 bool psMemCheckTime(psPtr ptr) 523 483 { 524 return ( psMemGetDeallocator(ptr) == (psFreeFunc)timeFree);484 return (psMemGetDeallocator(ptr) == (psFreeFunc)timeFree); 525 485 } 526 486 … … 528 488 psTime* psTimeGetNow(psTimeType type) 529 489 { 530 struct timeval now;531 psTime *time = NULL;532 533 // Allocate psTime struct534 time = psTimeAlloc(type);535 536 // Verify time structure allocated537 if(time == NULL) {538 return NULL;539 }540 541 490 // Get the system time 542 // if (gettimeofday(&now, (struct timezone *)0) == -1) {491 struct timeval now; // Current time 543 492 if (gettimeofday(&now, 0) == -1) { 544 493 psError(PS_ERR_OS_CALL_FAILED, true, … … 547 496 } 548 497 498 // Allocate psTime struct 499 psTime *time = psTimeAlloc(type); // Container for current time 500 549 501 // Convert timeval time to psTime 550 502 time->sec = now.tv_sec; 551 time->nsec = now.tv_usec *1000;503 time->nsec = now.tv_usec * 1000; 552 504 553 505 // Add most leapseconds to UTC time to get TAI time if necessary 554 if (type == PS_TIME_TAI) {506 if (type == PS_TIME_TAI) { 555 507 time->sec += p_psTimeGetTAIDelta(time); 556 508 } … … 559 511 } 560 512 561 static psTime*convertTimeTAIUTC(psTime* time)513 static bool convertTimeTAIUTC(psTime* time) 562 514 { 563 515 psF64 deltaTAI = 0.0; … … 575 527 576 528 // Check for underflow in nsec 577 if (deltaNsec > time->nsec) {529 if (deltaNsec > time->nsec) { 578 530 // Borrow second 579 531 time->nsec += 1e9; … … 585 537 586 538 // Check for overflow in nsec 587 if (time->nsec >= 1e9) {539 if (time->nsec >= 1e9) { 588 540 time->nsec -= 1e9; 589 541 time->sec++; … … 595 547 // Check if leapsecond present in delta 596 548 deltaUTC = p_psTimeGetTAIDelta(time); 597 if (fabs(deltaTAI-deltaUTC) >= 1.0) {549 if (fabs(deltaTAI-deltaUTC) >= 1.0) { 598 550 time->sec++; 599 551 } 600 552 601 return t ime;602 } 603 604 static psTime*convertTimeUTCTAI(psTime* time)553 return true; 554 } 555 556 static bool convertTimeUTCTAI(psTime* time) 605 557 { 606 558 psF64 delta = 0.0; … … 621 573 622 574 // Check for overflow in nsec 623 if (time->nsec >= 1e9) {575 if (time->nsec >= 1e9) { 624 576 time->nsec -= 1e9; 625 577 time->sec++; … … 629 581 time->type = PS_TIME_TAI; 630 582 631 //XXX: Set leapseconds to TRUE 632 // time->leapsecond = true; 633 return time; 634 } 635 636 static psTime* convertTimeTAITT(psTime* time) 583 return true; 584 } 585 586 static bool convertTimeTAITT(psTime* time) 637 587 { 638 588 // Add TT offset … … 641 591 642 592 // Check for overflow in nsec 643 if (time->nsec >= 1e9) {593 if (time->nsec >= 1e9) { 644 594 time->nsec -= 1e9; 645 595 time->sec++; … … 649 599 time->type = PS_TIME_TT; 650 600 651 return t ime;652 } 653 654 static psTime*convertTimeTTTAI(psTime* time)601 return true; 602 } 603 604 static bool convertTimeTTTAI(psTime* time) 655 605 { 656 606 // Subtract TT offset … … 658 608 659 609 // Check for nsec underflow 660 if (TAI_TT_OFFSET_NANOSECONDS > time->nsec) {610 if (TAI_TT_OFFSET_NANOSECONDS > time->nsec) { 661 611 // Borrow second 662 612 time->sec--; … … 666 616 667 617 // Check for overflow in nsec 668 if (time->nsec >= 1e9) {618 if (time->nsec >= 1e9) { 669 619 time->nsec -= 1e9; 670 620 time->sec++; … … 674 624 time->type = PS_TIME_TAI; 675 625 676 return t ime;677 } 678 679 static psTime*convertTimeUTCUT1(psTime* time)626 return true; 627 } 628 629 static bool convertTimeUTCUT1(psTime* time) 680 630 { 681 631 psS64 ut1utc = 0; … … 685 635 686 636 // Since UTC is within 0.9 sec of UT1 then nsec member is the member affected 687 if ((ut1utc < 0) && (abs(ut1utc) > time->nsec)) {637 if ((ut1utc < 0) && (abs(ut1utc) > time->nsec)) { 688 638 // Borrow from sec 689 639 time->sec--; 690 if (time->leapsecond) {640 if (time->leapsecond) { 691 641 time->leapsecond = false; 692 642 } else { … … 699 649 700 650 // Check for overflow in nsec 701 if (time->nsec >= 1e9) {651 if (time->nsec >= 1e9) { 702 652 time->nsec -= 1e9; 703 653 time->sec++; 704 if (time->leapsecond) {654 if (time->leapsecond) { 705 655 time->leapsecond = false; 706 656 time->sec--; … … 713 663 time->type = PS_TIME_UT1; 714 664 715 return time; 716 } 717 718 psTime* psTimeConvert(psTime *time, 719 psTimeType type) 665 return true; 666 } 667 668 bool psTimeConvert(psTime *time, psTimeType type) 720 669 { 721 670 // Error checks 722 PS_ASSERT_PTR_NON_NULL(time,NULL); 723 PS_ASSERT_INT_WITHIN_RANGE(time->nsec,0,(psU32)((1e9)-1), NULL); 724 725 // If the input type is UT1 then return time and generate error message 726 if(time->type == PS_TIME_UT1) { 727 psError(PS_ERR_BAD_PARAMETER_VALUE,true,"Cannot convert from UT1 time type"); 728 return NULL; 729 } 730 731 // If the time to convert to is the same as psTime the return time 671 PS_ASSERT_PTR_NON_NULL(time, false); 672 PS_ASSERT_INT_WITHIN_RANGE(time->nsec, 0, (psU32)((1e9)-1), false); 673 674 if (time->type == PS_TIME_UT1) { 675 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot convert from UT1 time type"); 676 return false; 677 } 732 678 if (time->type == type) { 733 return time; 734 } 735 736 // Convert from TAI to UTC, TT, UT1 737 if(time->type == PS_TIME_TAI) { 738 // Convert from TAI to UTC 739 if(type == PS_TIME_UTC) { 740 time = convertTimeTAIUTC(time); 741 // Convert from TAI to TT 742 } else if(type == PS_TIME_TT) { 743 time = convertTimeTAITT(time); 744 // Convert from TAI to UT1 745 } else if(type == PS_TIME_UT1) { 746 // Convert to UTC first 747 time = convertTimeTAIUTC(time); 748 // Convert UTC to UT1 749 time = convertTimeUTCUT1(time); 750 // Convert from TAI to unknown time type 751 } else { 679 // No action required 680 return true; 681 } 682 683 switch (time->type) { 684 case PS_TIME_TAI: 685 switch (type) { 686 case PS_TIME_UTC: 687 return convertTimeTAIUTC(time); 688 case PS_TIME_TT: 689 return convertTimeTAITT(time); 690 case PS_TIME_UT1: 691 convertTimeTAIUTC(time); 692 return convertTimeUTCUT1(time); 693 default: 694 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is not supported."), type); 695 return false; 696 } 697 break; 698 case PS_TIME_TT: 699 switch (type) { 700 case PS_TIME_UTC: 701 convertTimeTTTAI(time); 702 return convertTimeTAIUTC(time); 703 case PS_TIME_TAI: 704 return convertTimeTTTAI(time); 705 case PS_TIME_UT1: 706 convertTimeTTTAI(time); 707 convertTimeTAIUTC(time); 708 return convertTimeUTCUT1(time); 709 default: 752 710 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is not supported."), type); 753 711 return NULL; 754 712 } 755 // Convert from TT to TAI, UTC, UT1 756 } else if(time->type == PS_TIME_TT) { 757 // Convert from TT to UTC 758 if(type == PS_TIME_UTC) { 759 // Convert to TAI time first 760 time = convertTimeTTTAI(time); 761 // Convert from TAI to UTC 762 time = convertTimeTAIUTC(time); 763 // Convert from TT to TAI 764 } else if(type == PS_TIME_TAI) { 765 time = convertTimeTTTAI(time); 766 // Convert from TT to UT1 767 } else if(type == PS_TIME_UT1) { 768 // Convert to UTC first 769 // Convert to TAI time first 770 time = convertTimeTTTAI(time); 771 // Convert from TAI to UTC 772 time = convertTimeTAIUTC(time); 773 // Convert from UTC to UT1 774 time = convertTimeUTCUT1(time); 775 // Convert from TT to unknown time type 776 } else { 713 break; 714 case PS_TIME_UTC: 715 switch (type) { 716 case PS_TIME_TAI: 717 return convertTimeUTCTAI(time); 718 case PS_TIME_TT: 719 convertTimeUTCTAI(time); 720 return convertTimeTAITT(time); 721 case PS_TIME_UT1: 722 return convertTimeUTCUT1(time); 723 default: 777 724 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is not supported."), type); 778 725 return NULL; 779 726 } 780 // Convert from UTC to TAI, TT, UT1 781 } else if(time->type == PS_TIME_UTC) { 782 // Convert UTC to TAI 783 if(type == PS_TIME_TAI) { 784 time = convertTimeUTCTAI(time); 785 // Convert UTC to TT 786 } else if(type == PS_TIME_TT) { 787 // Convert to TAI time first 788 time = convertTimeUTCTAI(time); 789 // Convert TAI to TT 790 time = convertTimeTAITT(time); 791 // Convert UTC to UT1 792 } else if(type == PS_TIME_UT1) { 793 time = convertTimeUTCUT1(time); 794 // Convert UTC to unknown time type 795 } else { 796 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is not supported."), type); 797 return NULL; 798 } 799 // Convert unknown time type 800 } else { 727 break; 728 default: 801 729 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is not supported."), time->type); 802 730 return NULL; 803 731 } 804 732 805 return time; 733 psAbort("Should never reach here."); 734 return false; 806 735 } 807 736 … … 831 760 832 761 // Verify input time is not in UT1 seconds 833 if (time->type == PS_TIME_UT1) {762 if (time->type == PS_TIME_UT1) { 834 763 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Specified type, %d, is incorrect."),time->type); 835 764 return NAN; … … 841 770 tdtTime->nsec = time->nsec; 842 771 tdtTime->leapsecond = time->leapsecond; 843 tdtTime =psTimeConvert(tdtTime,PS_TIME_TT);772 psTimeConvert(tdtTime,PS_TIME_TT); 844 773 845 774 // Determine time reference to UT1 … … 848 777 ut1Time->nsec = time->nsec; 849 778 ut1Time->leapsecond = time->leapsecond; 850 ut1Time =psTimeConvert(ut1Time,PS_TIME_UT1);779 psTimeConvert(ut1Time,PS_TIME_UT1); 851 780 852 781 // Calculate UT1 as Julian Centuries since J2000.0 … … 864 793 // Calculate Greenwich Mean Sidereal Time (GMST) in radians. 865 794 // Equation set up to minimize multiplications. 866 gmstRad = fracDays *TWOPI867 + (const1+const2*tu+t*(const3+t*(const4+t*(const5+const6*t))))*S2R;795 gmstRad = fracDays * 2 * M_PI + 796 (const1 + const2 * tu + t * (const3 + t * (const4 + t * (const5 + const6 * t)))) * S2R; 868 797 869 798 // Place GMST between 0 and 2*pi 870 gmstRad = fmod(gmstRad, TWOPI);799 gmstRad = fmod(gmstRad, 2 * M_PI); 871 800 872 801 // Calculate Local Mean Sidereal Time (LMST) in radians … … 899 828 900 829 // Check for invalid bulletin specified 901 if ((bulletin != PS_IERS_A) && (bulletin != PS_IERS_B)) {830 if ((bulletin != PS_IERS_A) && (bulletin != PS_IERS_B)) { 902 831 psError(PS_ERR_BAD_PARAMETER_VALUE,true,"Invalid bulletin specified %d",bulletin); 903 832 return NAN; … … 905 834 906 835 // Check if psTime tables are already loaded 907 if (!p_psTimeInit(p_psTimeConfigFilename(NULL))) {836 if (!timeInit(p_psTimeConfigFilename(NULL))) { 908 837 psError(PS_ERR_UNKNOWN, true, "failed to init time tables."); 909 838 return NAN; … … 911 840 912 841 // Set lookup table column based on Bullentin 913 if (bulletin == PS_IERS_A) {842 if (bulletin == PS_IERS_A) { 914 843 tableColumn = 3; 915 844 } else { … … 922 851 923 852 // Value could not be found through table lookup and interpolation 924 if (status == PS_LOOKUP_PAST_TOP) {853 if (status == PS_LOOKUP_PAST_TOP) { 925 854 926 855 // Date too early for tables. Get default time delta value from metadata, and issue warning. … … 929 858 // Lookup value from time metadata loaded from pslib.config 930 859 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.dut"); 931 if (tableMetadataItem == NULL) {860 if (tableMetadataItem == NULL) { 932 861 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 933 862 "psLib.time.before.dut"); … … 936 865 result = tableMetadataItem->data.F64; 937 866 938 } else if (status == PS_LOOKUP_PAST_BOTTOM) {867 } else if (status == PS_LOOKUP_PAST_BOTTOM) { 939 868 /* Date too late for tables. Issue warning and use following formulae for predicting 940 869 ahead of the most recent available table entry. … … 949 878 // Lookup values to calculate prediction 950 879 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.dut"); 951 if (tableMetadataItem == NULL) {880 if (tableMetadataItem == NULL) { 952 881 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 953 882 "psLib.time.predict.dut"); … … 958 887 959 888 // Calculate predication of future UT1-UTC 960 t = 2000.0 + (mjd - 51544.03)/365.2422; 961 dut2ut1 = 0.022*sin(TWOPI*t) - 0.012*cos(TWOPI*t) - 0.006*sin(4.0*M_PI*t) + 0.007*cos(4.0*M_PI*t); 962 result = dut->data.F64[0] + dut->data.F64[1]*(mjd - dut->data.F64[2]) - dut2ut1; 963 964 } else if(status != PS_LOOKUP_SUCCESS) { 889 t = 2000.0 + (mjd - 51544.03) / 365.2422; 890 dut2ut1 = 0.022 * sin(2 * M_PI * t) - 0.012 * cos(2 * M_PI * t) - 891 0.006 * sin(4.0 * M_PI * t) + 0.007 * cos(4.0 * M_PI * t); 892 result = dut->data.F64[0] + dut->data.F64[1] * (mjd - dut->data.F64[2]) - dut2ut1; 893 894 } else if (status != PS_LOOKUP_SUCCESS) { 965 895 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed time table interpolation.")); 966 896 return NAN; … … 1044 974 *out = *time; 1045 975 if (out->type != PS_TIME_UT1) { 1046 out =psTimeConvert(out, PS_TIME_UT1);976 psTimeConvert(out, PS_TIME_UT1); 1047 977 } 1048 978 //see if corrections include seconds or just nano-seconds … … 1086 1016 PS_ASSERT_INT_WITHIN_RANGE(time->nsec,0,(psU32)((1e9)-1),NULL); 1087 1017 1088 if (time->type != PS_TIME_TAI) {1018 if (time->type != PS_TIME_TAI) { 1089 1019 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is incorrect."), time->type); 1090 1020 return NULL; … … 1092 1022 1093 1023 // Check if psTime tables are already loaded 1094 if (!p_psTimeInit(p_psTimeConfigFilename(NULL))) {1024 if (!timeInit(p_psTimeConfigFilename(NULL))) { 1095 1025 psError(PS_ERR_UNKNOWN, true, "failed to init time tables."); 1096 1026 return NULL; … … 1105 1035 1106 1036 // Value could not be found through table lookup and interpolation 1107 if (xStatus==PS_LOOKUP_PAST_TOP && yStatus==PS_LOOKUP_PAST_TOP) {1037 if (xStatus==PS_LOOKUP_PAST_TOP && yStatus==PS_LOOKUP_PAST_TOP) { 1108 1038 1109 1039 // Date too earlier for tables. Get default polar coodinate values from metadata, and issue warning. … … 1117 1047 1118 1048 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.xp"); 1119 if (tableMetadataItem == NULL) {1049 if (tableMetadataItem == NULL) { 1120 1050 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 1121 1051 _("Failed find '%s' in time metadata."), "psLib.time.before.xp"); … … 1125 1055 1126 1056 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.yp"); 1127 if (tableMetadataItem == NULL) {1057 if (tableMetadataItem == NULL) { 1128 1058 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "psLib.time.before.yp"); 1129 1059 return NULL; … … 1131 1061 y = tableMetadataItem->data.F64; 1132 1062 1133 } else if (xStatus==PS_LOOKUP_PAST_BOTTOM && yStatus==PS_LOOKUP_PAST_BOTTOM) {1063 } else if (xStatus==PS_LOOKUP_PAST_BOTTOM && yStatus==PS_LOOKUP_PAST_BOTTOM) { 1134 1064 1135 1065 /* Date too late for tables. Issue warning and use following formulae for predicting … … 1154 1084 // Get predicted MJD 1155 1085 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.mjd"); 1156 if (tableMetadataItem == NULL) {1086 if (tableMetadataItem == NULL) { 1157 1087 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 1158 1088 "psLib.time.predict.mjd"); … … 1163 1093 // Get xp 1164 1094 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.xp"); 1165 if (tableMetadataItem == NULL) {1095 if (tableMetadataItem == NULL) { 1166 1096 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "psLib.time.predict.xp"); 1167 1097 return NULL; … … 1172 1102 // Get yp 1173 1103 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.yp"); 1174 if (tableMetadataItem == NULL) {1104 if (tableMetadataItem == NULL) { 1175 1105 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "psLib.time.predict.yp"); 1176 1106 return NULL; … … 1180 1110 1181 1111 // Calculate "a" and "c" constants 1182 a = TWOPI*(mjd - mjdPred)/365.25;1183 c = TWOPI*(mjd - mjdPred)/435.0;1112 a = 2 * M_PI * (mjd - mjdPred) / 365.25; 1113 c = 2 * M_PI * (mjd - mjdPred) / 435.0; 1184 1114 1185 1115 // Calculate x and y polar coordinates … … 1196 1126 yp->data.F64[4]*sin(c); 1197 1127 1198 } else if (xStatus!=PS_LOOKUP_SUCCESS || yStatus!=PS_LOOKUP_SUCCESS) {1128 } else if (xStatus!=PS_LOOKUP_SUCCESS || yStatus!=PS_LOOKUP_SUCCESS) { 1199 1129 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed time table interpolation.")); 1200 1130 return NULL; … … 1226 1156 1227 1157 // Check if psTime tables are loaded/loadable 1228 if (! p_psTimeInit(p_psTimeConfigFilename(NULL))) {1158 if (!timeInit(p_psTimeConfigFilename(NULL))) { 1229 1159 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."), 1230 1160 p_psTimeConfigFilename(NULL)); … … 1234 1164 // Get table from metadata 1235 1165 tableMetadataItem = psMetadataLookup(timeMetadata, "taiTable"); 1236 if (tableMetadataItem == NULL) {1166 if (tableMetadataItem == NULL) { 1237 1167 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "taiTable"); 1238 1168 return NAN; … … 1242 1172 1243 1173 // Determine Julian and modified Julian dates used in table lookup and time delta calculation 1244 if (time->sec < 0) {1174 if (time->sec < 0) { 1245 1175 // psTime earlier than epoch 1246 1176 jd = time->sec / SEC_PER_DAY - time->nsec / NSEC_PER_DAY + JD_EPOCH_OFFSET; … … 1253 1183 1254 1184 // Set ceiling of the julian date to the last entry in the lookup table 1255 if (table->validTo < jd) {1185 if (table->validTo < jd) { 1256 1186 jd = table->validTo; 1257 1187 } … … 1261 1191 1262 1192 // Check for successful interpolation 1263 if (results == NULL) {1193 if (results == NULL) { 1264 1194 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed time table interpolation.")); 1265 1195 return NAN; … … 1272 1202 1273 1203 // If const3 not equal to zero solve for difference else floor of const1 1274 if (fabs(const3-0.0) > FLT_EPSILON) {1204 if (fabs(const3-0.0) > FLT_EPSILON) { 1275 1205 out = const1 + (mjd - const2) * const3; 1276 1206 } else { … … 1306 1236 1307 1237 // Verify time is UTC type 1308 if (utc->type != PS_TIME_UTC) {1238 if (utc->type != PS_TIME_UTC) { 1309 1239 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Specified type, %d, is incorrect."),utc->type); 1310 1240 return false; … … 1316 1246 1317 1247 // Check the absolute difference between the two times for leapsecond 1318 if (psTimeLeapSecondDelta(utc,prevUtc) >= 1.0) {1248 if (psTimeLeapSecondDelta(utc,prevUtc) >= 1.0) { 1319 1249 returnValue = true; 1320 1250 } else { … … 1330 1260 double psTimeToJD(const psTime *time) 1331 1261 { 1332 psF64 jd = NAN;1333 1334 1262 // Error checks 1335 1263 PS_ASSERT_PTR_NON_NULL(time,NAN); 1336 1264 PS_ASSERT_INT_WITHIN_RANGE(time->nsec,0,(psU32)((1e9)-1),NAN); 1337 1265 1266 // ADD says that this formula works only for PS_TIME_TAI, so adding the following: 1338 1267 psTime *time2 = psTimeCopy(time); 1339 //XXX: ADD says that this formula works only for PS_TIME_TAI, so adding the following: 1340 if (time->type == PS_TIME_UTC || time->type == PS_TIME_TT) { 1341 time2 = psTimeConvert(time2, PS_TIME_TAI); 1342 } 1343 1344 // Julian date conversion 1345 if(time2->sec < 0) { 1268 psTimeConvert(time2, PS_TIME_TAI); 1269 1270 double jd; // Julian date, to return 1271 if (time2->sec < 0) { 1346 1272 // psTime earlier than epoch 1347 1273 jd = time2->sec / SEC_PER_DAY - time2->nsec / NSEC_PER_DAY + JD_EPOCH_OFFSET; … … 1350 1276 jd = time2->sec / SEC_PER_DAY + time2->nsec / NSEC_PER_DAY + JD_EPOCH_OFFSET; 1351 1277 } 1352 1353 1278 psFree(time2); 1279 1354 1280 return jd; 1355 1281 } … … 1357 1283 double psTimeToMJD(const psTime *time) 1358 1284 { 1359 psF64 mjd = NAN;1360 1361 1285 // Error checks 1362 1286 PS_ASSERT_PTR_NON_NULL(time,NAN); 1363 1287 PS_ASSERT_INT_WITHIN_RANGE(time->nsec,0,(psU32)((1e9)-1),NAN); 1288 1289 // ADD says that this formula works only for PS_TIME_TAI, so adding the following: 1364 1290 psTime *time2 = psTimeCopy(time); 1365 //XXX: ADD says that this formula works only for PS_TIME_TAI, so adding the following: 1366 if (time->type == PS_TIME_UTC || time->type == PS_TIME_TT) { 1367 time2 = psTimeConvert(time2, PS_TIME_TAI); 1368 } 1369 1370 // Modified Julian date conversion 1371 if(time2->sec < 0) { 1291 psTimeConvert(time2, PS_TIME_TAI); 1292 1293 double mjd; // Modified Julian Date, to return 1294 if (time2->sec < 0) { 1372 1295 // psTime earlier than epoch 1373 1296 mjd = time2->sec / SEC_PER_DAY - time2->nsec / NSEC_PER_DAY + MJD_EPOCH_OFFSET; … … 1377 1300 } 1378 1301 psFree(time2); 1302 1379 1303 return mjd; 1380 1304 } 1381 1305 1382 psString psTimeToISO(const psTime *time) 1383 { 1384 psS32 ds = 0; 1385 char *timeString = NULL;1386 char *tempString = NULL;1387 1306 1307 // Format a time as a string, allowing for a specified number of decimals for the seconds field 1308 static psString timeToString(const psTime *time, // Time to format as string 1309 int decimals // Number of decimals to permit for seconds 1310 ) 1311 { 1388 1312 // Error checks 1389 PS_ASSERT_PTR_NON_NULL(time,NULL); 1390 PS_ASSERT_INT_WITHIN_RANGE(time->nsec,0,(psU32)((1e9)-1),NULL); 1391 1392 // Check valid year range 1393 if ((time->sec) < ((psS64)YEAR_0000_SEC) || (time->sec) > ((psS64)YEAR_9999_SEC)) { 1394 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Error: %s, %" PRId64 ", is out of range. Must be between %" PRId64 " and %" PRId64 ".", "time->sec", time->sec, ((psS64)YEAR_0000_SEC), ((psS64)YEAR_9999_SEC)); 1395 return NULL; 1396 } 1397 1398 PS_ASSERT_S64_WITHIN_RANGE(time->sec, (psS64)YEAR_0000_SEC, (psS64)YEAR_9999_SEC, NULL); 1399 1400 // Allocate temp strings 1401 tempString = psAlloc(MAX_TIME_STRING_LENGTH); 1402 timeString = psAlloc(MAX_TIME_STRING_LENGTH); 1403 1404 // Convert nanoseconds to decaseconds 1405 ds = time->nsec / 100000000; 1406 1407 // tmTime variable is statically allocated, no need to free 1408 struct tm *tmTime = psTimeToTM(time); 1409 1410 // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form 1411 if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) { 1313 PS_ASSERT_PTR_NON_NULL(time, NULL); 1314 PS_ASSERT_INT_WITHIN_RANGE(time->nsec, 0, (psU32)((1e9)-1), NULL); 1315 if (time->sec < YEAR_0000_SEC || time->sec > YEAR_9999_SEC) { 1316 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 1317 "Time (%" PRId64 " sec) is not between year 0000 or 9999.\n", time->sec); 1318 return NULL; 1319 } 1320 PS_ASSERT_INT_WITHIN_RANGE(decimals, 0, 9, NULL); 1321 1322 struct tm *tmTime = psTimeToTM(time); // Unix time structure 1323 1324 // Convert psTime to YYYY-MM-DDThh:mm:ss in string form 1325 psString string = psStringAlloc(MAX_TIME_STRING_LENGTH); // Time string 1326 if (!strftime(string, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) { 1412 1327 psError(PS_ERR_OS_CALL_FAILED, true, _("Failed to convert a time via strftime function.")); 1413 1328 return NULL; … … 1416 1331 1417 1332 // Check if time is UTC and leapsecond 1418 if (((time->type==PS_TIME_UTC)||(time->type==PS_TIME_UT1)) && (time->leapsecond)) {1333 if ((time->type == PS_TIME_UTC || time->type == PS_TIME_UT1) && time->leapsecond) { 1419 1334 // Modify second to be 60 1420 tempString[17] = '6'; 1421 tempString[18] = '0'; 1422 } 1423 1424 // Create string with milliseconds 1425 if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%1d", tempString, ds) < 0) { 1426 psError(PS_ERR_OS_CALL_FAILED, true, _("Failed to append millisecond to time string with snprintf function.")); 1427 return NULL; 1428 } 1429 psFree(tempString); 1430 1431 return timeString; 1335 string[17] = '6'; 1336 string[18] = '0'; 1337 } 1338 1339 // Add in the nanoseconds 1340 if (decimals > 0) { 1341 int partial = round((double)time->nsec / pow(10.0, 9 - decimals)); // Partial part 1342 psString format = NULL; // Format for printing partial part 1343 psStringAppend(&format, ".%%0%dd", decimals); 1344 psStringAppend(&string, format, partial); 1345 psFree(format); 1346 } 1347 1348 return string; 1349 } 1350 1351 psString psTimeToString(const psTime *time, int decimals) 1352 { 1353 return timeToString(time, decimals); 1354 } 1355 1356 1357 int psTimeSetISODecimals(int num) 1358 { 1359 int temp = isoDecimals; // Current value, to return 1360 isoDecimals = num; 1361 return temp; 1362 } 1363 1364 int psTimeGetISODecimals(void) 1365 { 1366 return isoDecimals; 1367 } 1368 1369 psString psTimeToISO(const psTime *time) 1370 { 1371 return timeToString(time, isoDecimals); 1432 1372 } 1433 1373 … … 1487 1427 days = jd - 2440587.5; 1488 1428 seconds = days * SEC_PER_DAY; 1489 if (seconds < 0.0) {1429 if (seconds < 0.0) { 1490 1430 outTime->nsec = (seconds - (psS64)seconds) * -1000000000.0; // psTime earlier than epoch 1491 1431 } else { … … 1513 1453 seconds = days * SEC_PER_DAY; 1514 1454 1515 if (seconds < 0.0) {1455 if (seconds < 0.0) { 1516 1456 outTime->nsec = (seconds - (psS64)seconds) * -1000000000.0; // psTime earlier than epoch 1517 1457 } else { … … 1701 1641 1702 1642 // Make month in range 3..14 (treat Jan & Feb as months 13..14 of prev year) 1703 if ( month <= 2 )1643 if ( month <= 2 ) 1704 1644 { 1705 1645 temp = (14 - month) / 12; … … 1707 1647 year -= temp; 1708 1648 month += 12 * temp; 1709 } else if (month > 14)1649 } else if (month > 14) 1710 1650 { 1711 1651 temp = (month - 3) / 12; … … 1775 1715 } 1776 1716 1777 time->nsec += fractionalSeconds * 1 e9;1717 time->nsec += fractionalSeconds * 1.0e9L; 1778 1718 return time; 1779 1719 } … … 1812 1752 1813 1753 // Convert time to TAI if necessary, but without changing input arguments 1814 if (time->type == PS_TIME_UTC) {1754 if (time->type == PS_TIME_UTC) { 1815 1755 tempTime = psTimeAlloc(PS_TIME_UTC); 1816 1756 tempTime->sec = time->sec; 1817 1757 tempTime->nsec = time->nsec; 1818 tempTime =psTimeConvert(tempTime, PS_TIME_TAI);1758 psTimeConvert(tempTime, PS_TIME_TAI); 1819 1759 outTime = psTimeAlloc(PS_TIME_TAI); 1820 1760 } else { … … 1833 1773 1834 1774 // Convert result to same time type as input 1835 if (time->type == PS_TIME_UTC) {1836 outTime =psTimeConvert(outTime, PS_TIME_UTC);1775 if (time->type == PS_TIME_UTC) { 1776 psTimeConvert(outTime, PS_TIME_UTC); 1837 1777 } 1838 1778 … … 1858 1798 1859 1799 // Verify both times of the same type 1860 if (time1->type != time2->type) {1800 if (time1->type != time2->type) { 1861 1801 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Specified type, %d, is incorrect."),time1->type); 1862 1802 return NAN; … … 1864 1804 1865 1805 // Convert time to TAI if necessary, but without changing input arguments 1866 if (time1->type == PS_TIME_UTC) {1806 if (time1->type == PS_TIME_UTC) { 1867 1807 tempTime1 = psTimeAlloc(PS_TIME_UTC); 1868 1808 tempTime1->sec = time1->sec; 1869 1809 tempTime1->nsec = time1->nsec; 1870 tempTime1 =psTimeConvert(tempTime1, PS_TIME_TAI);1810 psTimeConvert(tempTime1, PS_TIME_TAI); 1871 1811 } else { 1872 1812 tempTime1 = psMemIncrRefCounter((psTime*)time1); 1873 1813 } 1874 if (time2->type == PS_TIME_UTC) {1814 if (time2->type == PS_TIME_UTC) { 1875 1815 tempTime2 = psTimeAlloc(PS_TIME_UTC); 1876 1816 tempTime2->sec = time2->sec; 1877 1817 tempTime2->nsec = time2->nsec; 1878 tempTime2 =psTimeConvert(tempTime2, PS_TIME_TAI);1818 psTimeConvert(tempTime2, PS_TIME_TAI); 1879 1819 } else { 1880 1820 tempTime2 = psMemIncrRefCounter((psTime*)time2);
Note:
See TracChangeset
for help on using the changeset viewer.
