CommonTime.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 #include <limits>
40 #include <iomanip>
41 #include <cmath>
42 #include "CommonTime.hpp"
43 #include "MathBase.hpp"
44 #include "StringUtils.hpp"
45 
46 namespace gnsstk
47 {
48  std::shared_ptr<TimeSystemConverter> CommonTime::tsConv;
49 
50  // 'julian day' of earliest epoch expressible by CommonTime; 1/1/4713 B.C.
51  const long CommonTime::BEGIN_LIMIT_JDAY = 0L;
52  // 'julian day' of latest 'julian day' expressible by CommonTime,
53  // 1/1/4713 A.D.
54  const long CommonTime::END_LIMIT_JDAY = 3442448L;
55 
56  // earliest representable CommonTime
57  const CommonTime
59  // latest representable CommonTime
60  const CommonTime
62 
63  const double CommonTime::eps = 4.*std::numeric_limits<double>::epsilon();
64 
65 
67  : m_day( right.m_day ), m_msod( right.m_msod ), m_fsod( right.m_fsod ),
68  m_timeSystem( right.m_timeSystem )
69  {}
70 
72  {
73  m_day = right.m_day;
74  m_msod = right.m_msod;
75  m_fsod = right.m_fsod;
76  m_timeSystem = right.m_timeSystem;
77  return *this;
78  }
79 
80 
81  //FUTURE DEPRECATION
82  //ALL COMMONTIME ACCESSOR/MUTATOR METHODS ARE SET FOR FUTURE DEPRECATION (PRIVATIZATION)
83  //Accessor/Mutator methods should only be used by TimeTag classes and not made public,
84  //therefore these methods will be deprecated in a future release.
85 
86  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
88  long sod,
89  double fsod,
90  TimeSystem timeSystem )
91  {
92  // Use temp variables so that we don't modify our
93  // data members until we know these values are good.
94  if( day < BEGIN_LIMIT_JDAY || day > END_LIMIT_JDAY )
95  {
96  InvalidParameter ip( "Invalid day: "
98  GNSSTK_THROW( ip );
99  }
100 
101  if( sod < 0 || sod >= SEC_PER_DAY )
102  {
103  InvalidParameter ip( "Invalid seconds of day: "
104  + StringUtils::asString( sod ) );
105  GNSSTK_THROW( ip );
106  }
107 
108  if( fsod < 0.0 || fsod >= 1 )
109  {
110  InvalidParameter ip( "Invalid fractional-seconds: "
111  + StringUtils::asString( fsod ) );
112  GNSSTK_THROW( ip );
113  }
114 
115  // get the number of milliseconds in the fractional seconds argument
116  long msec = static_cast<long>( fsod * MS_PER_SEC );
117 
118  // subtract whole milliseconds to obtain the "fractional milliseconds"
119  fsod -= static_cast<double>( msec ) * SEC_PER_MS;
120 
121  m_day = day;
122  m_msod = sod * MS_PER_SEC + msec;
123  m_fsod = fsod;
124 
125  m_timeSystem = timeSystem;
126 
127  return *this;
128  }
129 
130  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
132  double sod,
133  TimeSystem timeSystem )
134  {
135  // separate whole and fractional seconds, then use set()
136  long sec = static_cast<long>( sod );
137  sod -= sec;
138 
139  return set( day, sec, sod, timeSystem );
140  }
141 
142  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
144  TimeSystem timeSystem )
145  {
146  // separate whole and fractional days
147  long lday = static_cast<long>( day );
148  double sec = ( day - lday ) * SEC_PER_DAY;
149  return set( lday, sec, timeSystem );
150  }
151 
152  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
154  long msod,
155  double fsod,
156  TimeSystem timeSystem )
157  {
158  if( day < BEGIN_LIMIT_JDAY || day > END_LIMIT_JDAY )
159  {
160  InvalidParameter ip( "Invalid day: "
161  + StringUtils::asString( day ) );
162  GNSSTK_THROW( ip );
163  }
164 
165  if( msod < 0 || msod >= MS_PER_DAY )
166  {
167  InvalidParameter ip( "Invalid milliseconds of day: "
168  + StringUtils::asString( msod ) );
169  GNSSTK_THROW( ip );
170  }
171 
172  if( fsod < 0.0 || fsod >= SEC_PER_MS )
173  {
174  InvalidParameter ip( "Invalid fractional-milliseconds: "
175  + StringUtils::asString( fsod ) );
176  GNSSTK_THROW( ip );
177  }
178 
179  m_day = day;
180  m_msod = msod;
181  m_fsod = fsod;
182 
183  m_timeSystem = timeSystem;
184 
185  return *this;
186  }
187 
188 
189  bool CommonTime ::
191  {
192  double offs;
193  bool rv = conv->getOffset(m_timeSystem, timeSystem, *this, offs);
194  if (rv)
195  {
196  operator-=(offs);
197  m_timeSystem = timeSystem;
198  }
199  return rv;
200  }
201 
202 
203  bool CommonTime ::
205  {
206  if (!tsConv)
207  return false;
208  return changeTimeSystem(timeSystem, tsConv.get());
209  }
210 
211 
212  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
213  void CommonTime::get( long& day,
214  long& sod,
215  double& fsod,
216  TimeSystem& timeSystem ) const
217  {
218  day = m_day;
219  sod = m_msod / MS_PER_SEC;
220  long msec = m_msod - sod * MS_PER_SEC; // m_msod % MS_PER_SEC
221  fsod = static_cast<double>( msec ) * SEC_PER_MS + m_fsod;
222  timeSystem = m_timeSystem;
223  }
224 
225  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
226  void CommonTime::get( long& day,
227  long& sod,
228  double& fsod ) const
229  {
230  TimeSystem ts;
231  CommonTime::get( day, sod, fsod, ts );
232  }
233 
234  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
235  void CommonTime::get( long& day,
236  double& sod,
237  TimeSystem& timeSystem ) const
238  {
239  day = m_day;
240  sod = (double)m_msod / MS_PER_SEC + m_fsod;
241  timeSystem = m_timeSystem;
242  }
243 
244  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
245  void CommonTime::get( long& day,
246  double& sod ) const
247  {
248  TimeSystem ts;
249  CommonTime::get( day, sod, ts );
250  }
251 
252  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
253  void CommonTime::get( double& day,
254  TimeSystem& timeSystem ) const
255  {
256  // convert everything to days
257  day = static_cast<double>( m_day ) +
258  static_cast<double>( m_msod ) / MS_PER_DAY +
260  timeSystem = m_timeSystem;
261  }
262 
263  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
264  void CommonTime::get( double& day ) const
265  {
266  TimeSystem ts;
267  CommonTime::get( day, ts );
268  }
269 
270  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
271  double CommonTime::getDays() const
272  {
273  double day;
274  get( day );
275  return day;
276  }
277 
278  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
280  {
281  long day;
282  double sod;
283  get( day, sod );
284  return sod;
285  }
286 
287  //METHOD SET FOR FUTURE DEPRECATION (PRIVATIZATION)
289  {
290  return m_timeSystem;
291  }
292 
293  double CommonTime::operator-( const CommonTime& right ) const
294  {
295  // Any (wildcard) type exception allowed, otherwise must be
296  // same time systems
297  if ( (m_timeSystem != TimeSystem::Any &&
298  right.m_timeSystem != TimeSystem::Any) &&
299  m_timeSystem != right.m_timeSystem )
300  {
301  InvalidRequest ir("CommonTime objects not in same time system, cannot be differenced");
302  GNSSTK_THROW( ir );
303  }
304 
305  return( SEC_PER_DAY * static_cast<double>( m_day - right.m_day ) +
306  SEC_PER_MS * static_cast<double>( m_msod - right.m_msod ) +
307  m_fsod - right.m_fsod ) ;
308  }
309 
310  CommonTime CommonTime::operator+( double sec ) const
311  {
312  return CommonTime( *this ).addSeconds( sec );
313  }
314 
315  CommonTime CommonTime::operator-( double sec ) const
316  {
317  return CommonTime( *this ).addSeconds( -sec );
318  }
319 
321  {
322  addSeconds( sec );
323  return *this;
324  }
325 
327  {
328  addSeconds( -sec );
329  return *this;
330  }
331 
333  {
334  long days = 0, ms = 0;
335 
336  if ( ABS(seconds) >= SEC_PER_DAY )
337  {
338  days = static_cast<long>( seconds * DAY_PER_SEC );
339  seconds -= days * SEC_PER_DAY;
340  }
341 
342  if ( ABS(seconds) >= SEC_PER_MS )
343  {
344  ms = static_cast<long>( seconds * MS_PER_SEC );
345  seconds -= static_cast<double>( ms ) / MS_PER_SEC;
346  }
347 
348  add( days, ms, seconds );
349  return *this;
350  }
351 
353  {
354  long days( 0 );
355  if( ABS( seconds ) > SEC_PER_DAY )
356  {
357  days = seconds / SEC_PER_DAY;
358  seconds -= days * SEC_PER_DAY; // seconds %= SEC_PER_DAY
359  }
360  add( days, seconds * MS_PER_SEC, 0. );
361 
362  return *this;
363  }
364 
366  {
367  add( days, 0, 0.0 );
368  return *this;
369  }
370 
372  {
373  add( 0, msec, 0.0 );
374  return *this;
375  }
376 
377  bool CommonTime::operator==( const CommonTime& right ) const
378  {
379  // Any (wildcard) type exception allowed, otherwise must be
380  // same time systems
381  if ((m_timeSystem != TimeSystem::Any &&
382  right.m_timeSystem != TimeSystem::Any) &&
383  m_timeSystem != right.m_timeSystem)
384  return false;
385 
386  return (m_day == right.m_day &&
387  m_msod == right.m_msod &&
388  fabs(m_fsod-right.m_fsod) < eps );
389  }
390 
391  bool CommonTime::operator!=( const CommonTime& right ) const
392  {
393  return !operator==(right);
394  }
395 
396  bool CommonTime::operator<( const CommonTime& right ) const
397  {
398  // Any (wildcard) type exception allowed, otherwise must be
399  // same time systems
400  if ((m_timeSystem != TimeSystem::Any &&
401  right.m_timeSystem != TimeSystem::Any) &&
402  m_timeSystem != right.m_timeSystem)
403  {
404  InvalidRequest ir(
405  "CommonTime objects not in same time system, cannot be compared: " +
408  GNSSTK_THROW( ir );
409  }
410 
411  if (m_day < right.m_day)
412  return true;
413  if (m_day > right.m_day)
414  return false;
415 
416  if (m_msod < right.m_msod)
417  return true;
418  if (m_msod > right.m_msod)
419  return false;
420 
421  if (m_fsod < right.m_fsod)
422  return true;
423 
424  return false;
425  }
426 
427  bool CommonTime::operator>( const CommonTime& right ) const
428  {
429  return !operator <=(right);
430  }
431 
432  bool CommonTime::operator<=( const CommonTime& right ) const
433  {
434  return (operator<(right) || operator==(right));
435  }
436 
437  bool CommonTime::operator>=( const CommonTime& right ) const
438  {
439  return !operator<(right);
440  }
441 
442  std::string CommonTime::asString() const
443  {
444  using namespace std;
445  ostringstream oss;
446  oss << setfill('0')
447  << setw(7) << m_day << " "
448  << setw(8) << m_msod << " "
449  << fixed << setprecision(15) << setw(17) << m_fsod
451  return oss.str();
452  }
453 
454 
455  bool CommonTime::add( long days,
456  long msod,
457  double fsod )
458  {
459  m_day += days;
460  m_msod += msod;
461  m_fsod += fsod;
462 
463  return normalize();
464  }
465 
467  {
468  std::numeric_limits<double> eps;
469 
470  if( ABS( m_fsod ) >= SEC_PER_MS - eps.epsilon() ) // allow for machine rounding errors
471  {
472  long ms = static_cast<long>( (m_fsod + eps.epsilon()) * MS_PER_SEC ); // again
473  m_msod += ms;
474  m_fsod -= static_cast<double>( ms ) * SEC_PER_MS;
475  }
476 
477  if( ABS( m_msod ) >= MS_PER_DAY )
478  {
479  long day = m_msod / MS_PER_DAY;
480  m_day += day;
481  m_msod -= day * MS_PER_DAY;
482  }
483 
484  if( ABS(m_fsod) < 1e-15 )
485  {
486  m_fsod = 0.0;
487  }
488 
489  if( m_fsod < 0 )
490  {
491  m_fsod += SEC_PER_MS;
492  --m_msod;
493  }
494 
495  if( m_msod < 0 )
496  {
498  --m_day;
499  }
500 
501  // byte logic to repair fixed-point math
502  if ( m_fsod >= static_cast<double>(0.999) )
503  m_fsod -= static_cast<double>(0.999);
504 
505  return ( ( m_day >= BEGIN_LIMIT_JDAY ) &&
506  ( m_day < END_LIMIT_JDAY ) );
507  }
508 
509  std::ostream& operator<<(std::ostream& o, const CommonTime& ct)
510  {
511  o << ct.asString();
512  return o;
513  }
514 
515 } // namespace
gnsstk::CommonTime::operator<
bool operator<(const CommonTime &right) const
Definition: CommonTime.cpp:396
gnsstk::CommonTime::eps
static const GNSSTK_EXPORT double eps
Default tolerance for time equality in days.
Definition: CommonTime.hpp:107
gnsstk::CommonTime::addSeconds
CommonTime & addSeconds(double seconds)
Definition: CommonTime.cpp:332
gnsstk::CommonTime::add
bool add(long days, long msod, double fsod)
Definition: CommonTime.cpp:455
example6.day
day
Definition: example6.py:66
gnsstk::CommonTime::setInternal
CommonTime & setInternal(long day=0, long msod=0, double fsod=0.0, TimeSystem timeSys=TimeSystem::Unknown)
Definition: CommonTime.cpp:153
StringUtils.hpp
gnsstk::CommonTime::tsConv
static GNSSTK_EXPORT std::shared_ptr< TimeSystemConverter > tsConv
Definition: CommonTime.hpp:406
gnsstk::SEC_PER_DAY
const long SEC_PER_DAY
Seconds per day.
Definition: TimeConstants.hpp:63
gnsstk::MS_PER_DAY
const long MS_PER_DAY
Milliseconds in a day.
Definition: TimeConstants.hpp:73
gnsstk::CommonTime::normalize
bool normalize()
Definition: CommonTime.cpp:466
gnsstk::CommonTime::BEGIN_LIMIT_JDAY
static const GNSSTK_EXPORT long BEGIN_LIMIT_JDAY
Definition: CommonTime.hpp:95
gnsstk::CommonTime::operator>=
bool operator>=(const CommonTime &right) const
Definition: CommonTime.cpp:437
gnsstk::CommonTime::m_msod
long m_msod
milliseconds-of-day 0 <= val < 86400000
Definition: CommonTime.hpp:438
gnsstk::TimeSystem::Any
@ Any
wildcard; allows comparison with any other type
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::SEC_PER_MS
const double SEC_PER_MS
Seconds per millisecond.
Definition: TimeConstants.hpp:70
gnsstk::CommonTime::operator!=
bool operator!=(const CommonTime &right) const
Definition: CommonTime.cpp:391
gnsstk::CommonTime::BEGINNING_OF_TIME
static const GNSSTK_EXPORT CommonTime BEGINNING_OF_TIME
earliest representable CommonTime
Definition: CommonTime.hpp:102
gnsstk::CommonTime::CommonTime
CommonTime(TimeSystem timeSystem=TimeSystem::Unknown)
Definition: CommonTime.hpp:120
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::CommonTime::operator-=
CommonTime & operator-=(double seconds)
Definition: CommonTime.cpp:326
gnsstk::CommonTime::getSecondOfDay
double getSecondOfDay() const
Obtain the seconds of day (ignoring the day).
Definition: CommonTime.cpp:279
gnsstk::TimeSystemConverter
Definition: TimeSystemConverter.hpp:58
gnsstk::CommonTime::operator+=
CommonTime & operator+=(double seconds)
Definition: CommonTime.cpp:320
gnsstk::CommonTime::END_OF_TIME
static const GNSSTK_EXPORT CommonTime END_OF_TIME
latest representable CommonTime
Definition: CommonTime.hpp:104
gnsstk::MS_PER_SEC
const long MS_PER_SEC
Milliseconds in a second.
Definition: TimeConstants.hpp:68
gnsstk::CommonTime::operator==
bool operator==(const CommonTime &right) const
Definition: CommonTime.cpp:377
gnsstk::CommonTime::getDays
double getDays() const
Obtain the time, in days, including the fraction of a day.
Definition: CommonTime.cpp:271
gnsstk::CommonTime::m_day
long m_day
Definition: CommonTime.hpp:437
gnsstk::operator<<
std::ostream & operator<<(std::ostream &s, const ObsEpoch &oe) noexcept
Definition: ObsEpochMap.cpp:54
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::TimeSystem
TimeSystem
Definition of various time systems.
Definition: TimeSystem.hpp:51
gnsstk::CommonTime::operator<=
bool operator<=(const CommonTime &right) const
Definition: CommonTime.cpp:432
gnsstk::CommonTime::get
void get(long &day, long &sod, double &fsod, TimeSystem &timeSystem) const
Definition: CommonTime.cpp:213
gnsstk::TimeSystemConverter::getOffset
virtual bool getOffset(TimeSystem fromSys, TimeSystem toSys, const CommonTime &t, double &offs)=0
ABS
#define ABS(x)
Definition: MathBase.hpp:73
gnsstk::CommonTime::END_LIMIT_JDAY
static const GNSSTK_EXPORT long END_LIMIT_JDAY
Definition: CommonTime.hpp:99
gnsstk::CommonTime::m_timeSystem
TimeSystem m_timeSystem
time frame (system representation) of the data
Definition: CommonTime.hpp:441
example6.sod
sod
Definition: example6.py:103
gnsstk::CommonTime::getTimeSystem
TimeSystem getTimeSystem() const
Obtain time system info (enum).
Definition: CommonTime.cpp:288
gnsstk::CommonTime::addMilliseconds
CommonTime & addMilliseconds(long ms)
Definition: CommonTime.cpp:371
CommonTime.hpp
std
Definition: Angle.hpp:142
gnsstk::DAY_PER_SEC
const double DAY_PER_SEC
Days per second.
Definition: TimeConstants.hpp:65
gnsstk::CommonTime::m_fsod
double m_fsod
fractional seconds-of-day 0 <= val < 0.001
Definition: CommonTime.hpp:439
gnsstk::CommonTime::operator+
CommonTime operator+(double seconds) const
Definition: CommonTime.cpp:310
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::CommonTime::operator-
double operator-(const CommonTime &right) const
Definition: CommonTime.cpp:293
gnsstk::CommonTime::changeTimeSystem
bool changeTimeSystem(TimeSystem timeSystem, TimeSystemConverter *conv)
Definition: CommonTime.cpp:190
MathBase.hpp
gnsstk::CommonTime::operator=
CommonTime & operator=(const CommonTime &right)
Definition: CommonTime.cpp:71
gnsstk::CommonTime::asString
std::string asString() const
Definition: CommonTime.cpp:442
gnsstk::CommonTime::addDays
CommonTime & addDays(long days)
Definition: CommonTime.cpp:365
gnsstk::CommonTime::operator>
bool operator>(const CommonTime &right) const
Definition: CommonTime.cpp:427
gnsstk::CommonTime::set
CommonTime & set(long day, long sod, double fsod=0.0, TimeSystem timeSystem=TimeSystem::Unknown)
Definition: CommonTime.cpp:87


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:38