00001 #pragma ident "$Id: CommonTime.cpp 2965 2011-11-03 11:25:57Z martenstrom $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CommonTime.hpp"
00028 #include "TimeConstants.hpp"
00029
00030 #include "MathBase.hpp"
00031 #include "StringUtils.hpp"
00032
00033 namespace gpstk
00034 {
00035
00036 const long CommonTime::BEGIN_LIMIT_JDAY = 0;
00037
00038
00039 const long CommonTime::END_LIMIT_JDAY = 3442448;
00040
00041
00042 const CommonTime
00043 CommonTime::BEGINNING_OF_TIME( CommonTime::BEGIN_LIMIT_JDAY, 0, 0.0 );
00044
00045 const CommonTime
00046 CommonTime::END_OF_TIME( CommonTime::END_LIMIT_JDAY, 0, 0.0 ) ;
00047
00048 CommonTime::CommonTime( const CommonTime& right )
00049 throw()
00050 : m_day( right.m_day ), m_msod( right.m_msod ), m_fsod( right.m_fsod )
00051 {}
00052
00053 CommonTime& CommonTime::operator=( const CommonTime& right )
00054 throw()
00055 {
00056 m_day = right.m_day;
00057 m_msod = right.m_msod;
00058 m_fsod = right.m_fsod;
00059 return *this;
00060 }
00061
00062 CommonTime& CommonTime::set( long day,
00063 long sod,
00064 double fsod )
00065 throw( gpstk::InvalidParameter )
00066 {
00067
00068
00069 if( day < BEGIN_LIMIT_JDAY || day > END_LIMIT_JDAY )
00070 {
00071 gpstk::InvalidParameter ip( "Invalid day: "
00072 + gpstk::StringUtils::asString( day ) );
00073 GPSTK_THROW( ip );
00074 }
00075
00076 if( sod < 0 || sod >= SEC_PER_DAY )
00077 {
00078 gpstk::InvalidParameter ip( "Invalid seconds of day: "
00079 + gpstk::StringUtils::asString( sod ) );
00080 GPSTK_THROW( ip );
00081 }
00082
00083 if( fsod < 0.0 || fsod >= 1 )
00084 {
00085 gpstk::InvalidParameter ip( "Invalid fractional-seconds: "
00086 + gpstk::StringUtils::asString( fsod ) );
00087 GPSTK_THROW( ip );
00088 }
00089
00090
00091 long msec = static_cast<long>( fsod * MS_PER_SEC );
00092
00093
00094 fsod -= static_cast<double>( msec ) * SEC_PER_MS;
00095
00096 m_day = day;
00097 m_msod = sod * MS_PER_SEC + msec;
00098 m_fsod = fsod;
00099
00100 return *this;
00101 }
00102
00103 CommonTime& CommonTime::set( long day,
00104 double sod )
00105 throw( gpstk::InvalidParameter )
00106 {
00107
00108 long sec = static_cast<long>( sod );
00109 sod -= sec;
00110
00111 return set( day, sec, sod );
00112 }
00113
00114 CommonTime& CommonTime::set( double day = 0.0 )
00115 throw( gpstk::InvalidParameter )
00116 {
00117
00118 long lday = static_cast<long>( day );
00119 double sec = ( day - lday ) * SEC_PER_DAY;
00120 return set( lday, sec );
00121 }
00122
00123 CommonTime& CommonTime::setInternal( long day,
00124 long msod,
00125 double fsod )
00126 throw( gpstk::InvalidParameter )
00127 {
00128 if( day < BEGIN_LIMIT_JDAY || day > END_LIMIT_JDAY )
00129 {
00130 gpstk::InvalidParameter ip( "Invalid day: "
00131 + gpstk::StringUtils::asString( day ) );
00132 GPSTK_THROW( ip );
00133 }
00134
00135 if( msod < 0 || msod >= MS_PER_DAY )
00136 {
00137 gpstk::InvalidParameter ip( "Invalid milliseconds of day: "
00138 + gpstk::StringUtils::asString( msod ) );
00139 GPSTK_THROW( ip );
00140 }
00141
00142 if( fsod < 0.0 || fsod >= SEC_PER_MS )
00143 {
00144 gpstk::InvalidParameter ip( "Invalid fractional-milliseconds: "
00145 + gpstk::StringUtils::asString( fsod ) );
00146 GPSTK_THROW( ip );
00147 }
00148
00149 m_day = day;
00150 m_msod = msod;
00151 m_fsod = fsod;
00152
00153 return *this;
00154 }
00155
00156 void CommonTime::get( long& day,
00157 long& sod,
00158 double& fsod ) const
00159 throw()
00160 {
00161 day = m_day;
00162 sod = m_msod / MS_PER_SEC;
00163 long msec = m_msod - sod * MS_PER_SEC;
00164 fsod = static_cast<double>( msec ) * SEC_PER_MS + m_fsod;
00165 }
00166
00167 void CommonTime::get( long& day,
00168 double& sod ) const
00169 throw()
00170 {
00171 day = m_day;
00172 sod = (double)m_msod / MS_PER_SEC + m_fsod;
00173 }
00174
00175 void CommonTime::get( double& day ) const
00176 throw()
00177 {
00178
00179 day = static_cast<double>( m_day ) +
00180 static_cast<double>( m_msod ) / MS_PER_DAY +
00181 m_fsod / SEC_PER_DAY;
00182 }
00183
00184 double CommonTime::getDays() const
00185 throw()
00186 {
00187 double day;
00188 get( day );
00189 return day;
00190 }
00191
00192 double CommonTime::getSecondOfDay() const
00193 throw()
00194 {
00195 long day;
00196 double sod;
00197 get( day, sod );
00198 return sod;
00199 }
00200
00201 double CommonTime::operator-( const CommonTime& right ) const
00202 throw()
00203 {
00204 return ( SEC_PER_DAY * static_cast<double>( m_day - right.m_day ) +
00205 SEC_PER_MS * static_cast<double>( m_msod - right.m_msod ) +
00206 m_fsod - right.m_fsod ) ;
00207 }
00208
00209 CommonTime CommonTime::operator+( double sec ) const
00210 throw( gpstk::InvalidRequest )
00211 {
00212 return CommonTime( *this ).addSeconds( sec );
00213 }
00214
00215 CommonTime CommonTime::operator-( double sec ) const
00216 throw( gpstk::InvalidRequest )
00217 {
00218 return CommonTime( *this ).addSeconds( -sec );
00219 }
00220
00221 CommonTime& CommonTime::operator+=( double sec )
00222 throw( gpstk::InvalidRequest )
00223 {
00224 addSeconds( sec );
00225 return *this;
00226 }
00227
00228 CommonTime& CommonTime::operator-=( double sec )
00229 throw( gpstk::InvalidRequest )
00230 {
00231 addSeconds( -sec );
00232 return *this;
00233 }
00234
00235 CommonTime& CommonTime::addSeconds( double seconds )
00236 throw( InvalidRequest )
00237 {
00238 long days=0, ms=0;
00239 if ( ABS(seconds) >= SEC_PER_DAY )
00240 {
00241 days = static_cast<long>( seconds * DAY_PER_SEC );
00242 seconds -= days * SEC_PER_DAY;
00243 }
00244
00245 if ( ABS(seconds) >= SEC_PER_MS )
00246 {
00247 ms = static_cast<long>( seconds * MS_PER_SEC );
00248 seconds -= static_cast<double>( ms ) / MS_PER_SEC;
00249 }
00250
00251 add(days, ms, seconds);
00252 return *this;
00253 }
00254
00255 CommonTime& CommonTime::addSeconds( long seconds )
00256 throw( gpstk::InvalidRequest )
00257 {
00258 long days( 0 );
00259 if( ABS( seconds ) > SEC_PER_DAY )
00260 {
00261 days = seconds / SEC_PER_DAY;
00262 seconds -= days * SEC_PER_DAY;
00263 }
00264 add( days, seconds * MS_PER_SEC, 0. );
00265
00266
00267
00268
00269
00270
00271 return *this;
00272 }
00273
00274 CommonTime& CommonTime::addDays( long days )
00275 throw( gpstk::InvalidRequest )
00276 {
00277 add( days, 0, 0.0 );
00278 return *this;
00279 }
00280
00281 CommonTime& CommonTime::addMilliseconds( long msec )
00282 throw( InvalidRequest )
00283 {
00284 add( 0, msec, 0.0 );
00285 return *this;
00286 }
00287
00288 bool CommonTime::operator==( const CommonTime& right ) const
00289 throw()
00290 {
00291 return (m_day == right.m_day &&
00292 m_msod == right.m_msod &&
00293 m_fsod == right.m_fsod );
00294 }
00295
00296 bool CommonTime::operator!=( const CommonTime& right ) const
00297 throw()
00298 {
00299 return !operator==(right);
00300 }
00301
00302 bool CommonTime::operator<( const CommonTime& right ) const
00303 throw()
00304 {
00305 if (m_day < right.m_day)
00306 return true;
00307 if (m_day > right.m_day)
00308 return false;
00309
00310 if (m_msod < right.m_msod)
00311 return true;
00312 if (m_msod > right.m_msod)
00313 return false;
00314
00315 if (m_fsod < right.m_fsod)
00316 return true;
00317
00318 return false;
00319 }
00320
00321 bool CommonTime::operator>( const CommonTime& right ) const
00322 throw()
00323 {
00324 return !operator <=(right);
00325 }
00326
00327 bool CommonTime::operator<=( const CommonTime& right ) const
00328 throw()
00329 {
00330 return (operator<(right) || operator==(right));
00331 }
00332
00333 bool CommonTime::operator>=( const CommonTime& right ) const
00334 throw()
00335 {
00336 return !operator<(right);
00337 }
00338
00339 std::string CommonTime::asString() const
00340 throw()
00341 {
00342 using namespace std;
00343 ostringstream oss;
00344 oss << setfill('0')
00345 << setw(7) << m_day << " "
00346 << setw(8) << m_msod << " "
00347 << fixed << setprecision(15) << setw(17) << m_fsod;
00348 return oss.str();
00349 }
00350
00352 bool CommonTime::add( long days,
00353 long msod,
00354 double fsod )
00355 throw()
00356 {
00357 m_day += days;
00358 m_msod += msod;
00359 m_fsod += fsod;
00360 return normalize();
00361 }
00362
00363 bool CommonTime::normalize()
00364 throw()
00365 {
00366 if( ABS( m_fsod ) >= SEC_PER_MS )
00367 {
00368 long ms = static_cast<long>( m_fsod * MS_PER_SEC );
00369 m_msod += ms;
00370 m_fsod -= static_cast<double>( ms ) * SEC_PER_MS;
00371 }
00372
00373 if( ABS( m_msod ) >= MS_PER_DAY )
00374 {
00375 long day = m_msod / MS_PER_DAY;
00376 m_day += day;
00377 m_msod -= day * MS_PER_DAY;
00378 }
00379
00380 if( ABS(m_fsod) < 1e-15 )
00381 {
00382 m_fsod = 0.0;
00383 }
00384
00385 if( m_fsod < 0 )
00386 {
00387 m_fsod += SEC_PER_MS;
00388 --m_msod;
00389 }
00390
00391 if( m_msod < 0 )
00392 {
00393 m_msod = m_msod + MS_PER_DAY;
00394 --m_day;
00395 }
00396
00397 return ( ( m_day >= BEGIN_LIMIT_JDAY ) &&
00398 ( m_day < END_LIMIT_JDAY ) );
00399 }
00400
00401 std::ostream& operator<<(std::ostream& o, const CommonTime& ct)
00402 {
00403 o << ct.asString();
00404 return o;
00405 }
00406
00407 }