// Find the appropriate time system correction object in the collection for the // given time systems, and dump it to a string and return that string. string Rinex3EphemerisStore::dumpTimeSystemCorrection( const TimeSystem fromSys, const TimeSystem toSys) const { string msg; ostringstream oss; oss << "Convert from " << fromSys.asString() << " to " << toSys.asString() << " : "; if(toSys == fromSys) { oss << "time systems are the same"; return oss.str(); } // look up the TimeSystemCorr in list, and dump it map<string, TimeSystemCorrection>::const_iterator it; for(it = mapTimeCorr.begin(); it != mapTimeCorr.end(); ++it) { if(it->second.isConverterFor(fromSys, toSys)) { it->second.dump(oss); return oss.str(); } } oss << "conversion not found!"; return oss.str(); }
// Utility routine for getXvt and addEphemeris to convert time systems. // Convert ttag to the target time system, using the first appropriate correction // in the list, and return it. If no correction is found, ttag is unchanged and // an exception is thrown. CommonTime Rinex3EphemerisStore::correctTimeSystem(const CommonTime ttag, const TimeSystem targetSys) const { CommonTime toReturn(ttag); TimeSystem fromSys(ttag.getTimeSystem()); // is a conversion necessary? if(fromSys == targetSys) return toReturn; // first correct for leap seconds const CivilTime civt(ttag); double dt = TimeSystem::Correction(fromSys, targetSys, civt.year, civt.month, civt.day); toReturn += dt; toReturn.setTimeSystem(targetSys); // the corrected timetag: now only the system, not the value, matters toReturn.setTimeSystem(targetSys); // look up the TimeSystemCorr in list, and do the conversion map<string, TimeSystemCorrection>::const_iterator it; for(it = mapTimeCorr.begin(); it != mapTimeCorr.end(); ++it) { if(it->second.isConverterFor(fromSys, targetSys)) { dt = it->second.Correction(ttag); toReturn += dt; return toReturn; } } // failure InvalidRequest e("Unable to convert time systems from " + ttag.getTimeSystem().asString() + " to " + targetSys.asString()); GPSTK_THROW(e); return toReturn; // never reached, satisfy some compilers }
// Compute the conversion (in seconds) from one time system (inTS) to another // (outTS), given the year and month of the time to be converted. // Result is to be added to the first time (inTS) to yield the converted (outTS), // that is t(outTS) = t(inTS) + correction(inTS,outTS). // NB. the caller must not forget to change to outTS after adding this correction. // @param TimeSystem inTS, input system // @param TimeSystem outTS, output system // @param int year, year of the time to be converted. // @param int month, month (1-12) of the time to be converted. // @return double dt, correction (sec) to be added to t(in) to yield t(out). // @throw if input system(s) are invalid or Unknown. double TimeSystem::Correction(const TimeSystem& inTS, const TimeSystem& outTS, const int year, const int month, const double day) { double dt(0.0); // identity if(inTS == outTS) return dt; // cannot convert unknowns if(inTS == Unknown || outTS == Unknown) { Exception e("Cannot compute correction for TimeSystem::Unknown"); GPSTK_THROW(e); } // compute TT-TDB here; ref Astronomical Almanac B7 double TDBmTT(0.0); if(inTS == TDB || outTS == TDB) { int iday = int(day); long jday = convertCalendarToJD(year, month, iday) ; double frac(day-iday); double TJ2000(jday-2451545.5+frac); // t-J2000 // 0.0001657 sec * sin(357.53 + 0.98560028 * TJ2000 deg) frac = ::fmod(0.017201969994578 * TJ2000, 6.2831853071796); TDBmTT = 0.0001657 * ::sin(6.240075674 + frac); // 0.000022 sec * sin(246.11 + 0.90251792 * TJ2000 deg) frac = ::fmod(0.015751909262251 * TJ2000, 6.2831853071796); TDBmTT += 0.000022 * ::sin(4.295429822 + frac); } // ----------------------------------------------------------- // conversions: first convert inTS->TAI ... // TAI = GPS + 19s // TAI = UTC + getLeapSeconds() // TAI = TT - 32.184s if(inTS == GPS || // GPS -> TAI inTS == GAL) // GAL -> TAI dt = 19.; else if(inTS == UTC || // UTC -> TAI inTS == BDT || // BDT -> TAI // TD is this right? inTS == GLO) // GLO -> TAI dt = getLeapSeconds(year, month, day); //else if(inTS == BDT) // BDT -> TAI // RINEX 3.02 seems to say this // dt = 34.; else if(inTS == TAI) // TAI ; else if(inTS == TT) // TT -> TAI dt = -32.184; else if(inTS == TDB) // TDB -> TAI dt = -32.184 + TDBmTT; else { // other Exception e("Invalid input TimeSystem " + inTS.asString()); GPSTK_THROW(e); } // ----------------------------------------------------------- // ... then convert TAI->outTS // GPS = TAI - 19s // UTC = TAI - getLeapSeconds() // TT = TAI + 32.184s if(outTS == GPS || // TAI -> GPS outTS == GAL) // TAI -> GAL dt -= 19.; else if(outTS == UTC || // TAI -> UTC outTS == BDT || // TAI -> BDT outTS == GLO) // TAI -> GLO dt -= getLeapSeconds(year, month, day); //else if(outTS == BDT) // TAI -> BDT // dt -= 34.; else if(outTS == TAI) // TAI ; else if(outTS == TT) // TAI -> TT dt += 32.184; else if(outTS == TDB) // TAI -> TDB dt += 32.184 - TDBmTT; else if(outTS == GAL) // TD dt = 0.0; else { // other Exception e("Invalid output TimeSystem " + outTS.asString()); GPSTK_THROW(e); } return dt; }