Commit 9abfea67dddb583ee55400af6857430c3e8f68a2
1 parent
89829f97
Add leap second handling to convert() and set() methods and add corresponding unit tests.
The convert() and set() methods now support time references given in the UTC time system. Using convert() one can now extract for example MJD in the UTC time system. All this needs still to be documented.
Showing
4 changed files
with
59 additions
and
22 deletions
include/GTime.hpp
| ... | ... | @@ -36,7 +36,7 @@ |
| 36 | 36 | /***********************************************************************//** |
| 37 | 37 | * @class GTime |
| 38 | 38 | * |
| 39 | - * @brief Handles times in a system independent way | |
| 39 | + * @brief Time class | |
| 40 | 40 | * |
| 41 | 41 | * The GTime class stores a time value in seconds in a GammaLib native time |
| 42 | 42 | * reference system. The GammaLib native time reference (i.e. time=0) is |
| ... | ... | @@ -68,8 +68,8 @@ public: |
| 68 | 68 | // Constructors and destructors |
| 69 | 69 | GTime(void); |
| 70 | 70 | GTime(const GTime& time); |
| 71 | - explicit GTime(const double& time, const std::string& unit = "sec"); | |
| 72 | - explicit GTime(const double& time, const GTimeReference& ref); | |
| 71 | + GTime(const double& time, const std::string& unit = "sec"); | |
| 72 | + GTime(const double& time, const GTimeReference& ref); | |
| 73 | 73 | virtual ~GTime(void); |
| 74 | 74 | |
| 75 | 75 | // Operators |
| ... | ... | @@ -104,7 +104,7 @@ protected: |
| 104 | 104 | int days_in_year(const int& year) const; |
| 105 | 105 | |
| 106 | 106 | // Protected data members |
| 107 | - double m_time; //!< Time in seconds in native reference | |
| 107 | + double m_time; //!< Time in seconds in native reference (TT) | |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | 110 | ... | ... |
pyext/GTime.i
| ... | ... | @@ -32,10 +32,7 @@ |
| 32 | 32 | /***********************************************************************//** |
| 33 | 33 | * @class GTime |
| 34 | 34 | * |
| 35 | - * @brief Class that handles times in a system independent way | |
| 36 | - * | |
| 37 | - * The GTime class stores a time value in seconds and its MJD reference in | |
| 38 | - * days. The time can be retrieved in any MJD reference. | |
| 35 | + * @brief Time class | |
| 39 | 36 | ***************************************************************************/ |
| 40 | 37 | class GTime : public GBase { |
| 41 | 38 | |
| ... | ... | @@ -43,13 +40,14 @@ public: |
| 43 | 40 | // Constructors and destructors |
| 44 | 41 | GTime(void); |
| 45 | 42 | GTime(const GTime& time); |
| 46 | - explicit GTime(const double& time, const std::string& unit = "sec"); | |
| 47 | - explicit GTime(const double& time, const GTimeReference& ref); | |
| 43 | + GTime(const double& time, const std::string& unit = "sec"); | |
| 44 | + GTime(const double& time, const GTimeReference& ref); | |
| 48 | 45 | virtual ~GTime(void); |
| 49 | 46 | |
| 50 | 47 | // Methods |
| 51 | 48 | void clear(void); |
| 52 | 49 | GTime* clone(void) const; |
| 50 | + std::string classname(void) const; | |
| 53 | 51 | double jd(void) const; |
| 54 | 52 | double mjd(void) const; |
| 55 | 53 | const double& secs(void) const; | ... | ... |
src/obs/GTime.cpp
| ... | ... | @@ -90,14 +90,14 @@ GTime::GTime(const GTime& time) |
| 90 | 90 | /***********************************************************************//** |
| 91 | 91 | * @brief Time constructor |
| 92 | 92 | * |
| 93 | - * @param[in] time Time value (seconds or days). | |
| 93 | + * @param[in] time Time value in TT (seconds or days). | |
| 94 | 94 | * @param[in] unit Time unit (default: "secs"). |
| 95 | 95 | * |
| 96 | 96 | * @exception GException::time_invalid_unit |
| 97 | 97 | * Invalid time unit specified. |
| 98 | 98 | * |
| 99 | 99 | * Constructs a GTime object by setting the time in the native reference |
| 100 | - * in units of seconds (default) or days. | |
| 100 | + * in the TT time system in units of seconds (default) or days. | |
| 101 | 101 | ***************************************************************************/ |
| 102 | 102 | GTime::GTime(const double& time, const std::string& unit) |
| 103 | 103 | { |
| ... | ... | @@ -296,9 +296,9 @@ std::string GTime::utc(void) const |
| 296 | 296 | // argument is given in the UTC system but upon start we're in the TAI |
| 297 | 297 | // system |
| 298 | 298 | double leaps = leap_seconds(mjd) * gammalib::sec2day; |
| 299 | - leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; | |
| 300 | - leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; | |
| 301 | - mjd -= leaps; | |
| 299 | + leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; | |
| 300 | + leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; | |
| 301 | + mjd -= leaps; | |
| 302 | 302 | |
| 303 | 303 | // Split in day and fraction |
| 304 | 304 | int day = (int)mjd; |
| ... | ... | @@ -367,13 +367,10 @@ std::string GTime::utc(void) const |
| 367 | 367 | * |
| 368 | 368 | * Convert the time from the native reference system into the specified |
| 369 | 369 | * reference system. |
| 370 | - * | |
| 371 | - * @todo Implement TT-UTC conversion if required. This requires | |
| 372 | - * implementation of leap seconds. | |
| 373 | 370 | ***************************************************************************/ |
| 374 | 371 | double GTime::convert(const GTimeReference& ref) const |
| 375 | 372 | { |
| 376 | - // Retrieve time in native reference (seconds) | |
| 373 | + // Retrieve time in native reference (TT in seconds) | |
| 377 | 374 | double time = m_time; |
| 378 | 375 | |
| 379 | 376 | // Compute time offset in seconds |
| ... | ... | @@ -382,6 +379,25 @@ double GTime::convert(const GTimeReference& ref) const |
| 382 | 379 | // Add time offset in seconds |
| 383 | 380 | time += offset; |
| 384 | 381 | |
| 382 | + // Subtract leap seconds in case that time is requested in UTC time | |
| 383 | + // system | |
| 384 | + if (gammalib::toupper(ref.timesys()) == "UTC") { | |
| 385 | + | |
| 386 | + // Get MJD in TAI time system | |
| 387 | + double mjd = this->mjd() - gammalib::tai2tt * gammalib::sec2day; | |
| 388 | + | |
| 389 | + // Get leap seconds (repeat is a kluge to converge as the | |
| 390 | + // argument is given in the UTC system but upon start we're in the TAI | |
| 391 | + // system | |
| 392 | + double leaps = leap_seconds(mjd); | |
| 393 | + leaps = leap_seconds(mjd - leaps * gammalib::sec2day); | |
| 394 | + leaps = leap_seconds(mjd - leaps * gammalib::sec2day); | |
| 395 | + | |
| 396 | + // Subtract leap seconds and TAI offset | |
| 397 | + time -= (leaps + gammalib::tai2tt); | |
| 398 | + | |
| 399 | + } // endif: UTC time system has been requested | |
| 400 | + | |
| 385 | 401 | // Convert to specified time unit |
| 386 | 402 | double to_unit = ref.unitseconds(); |
| 387 | 403 | if (to_unit != 1.0) { |
| ... | ... | @@ -556,9 +572,6 @@ void GTime::utc(const std::string& time) |
| 556 | 572 | * @param[in] ref Reference system. |
| 557 | 573 | * |
| 558 | 574 | * Set the time to a value given in a specific reference system. |
| 559 | - * | |
| 560 | - * @todo Implement TT-UTC conversion if required. This requires | |
| 561 | - * implementation of leap seconds. | |
| 562 | 575 | ***************************************************************************/ |
| 563 | 576 | void GTime::set(const double& time, const GTimeReference& ref) |
| 564 | 577 | { |
| ... | ... | @@ -571,6 +584,15 @@ void GTime::set(const double& time, const GTimeReference& ref) |
| 571 | 584 | // Subtract time offset in seconds |
| 572 | 585 | m_time -= offset; |
| 573 | 586 | |
| 587 | + // Add leap seconds in case that time was given in UTC time system | |
| 588 | + if (gammalib::toupper(ref.timesys()) == "UTC") { | |
| 589 | + | |
| 590 | + // Add leap seconds and offset between TAI and TT time system | |
| 591 | + m_time += leap_seconds(this->mjd()); | |
| 592 | + m_time += gammalib::tai2tt; | |
| 593 | + | |
| 594 | + } // endif: Time was given in UTC time system | |
| 595 | + | |
| 574 | 596 | // Return |
| 575 | 597 | return; |
| 576 | 598 | } | ... | ... |
test/test_GObservation.cpp
| ... | ... | @@ -557,6 +557,23 @@ void TestGObservation::test_time(void) |
| 557 | 557 | time.set(12.3, GTimeReference(0.0, "secs", "TT", "LOCAL")); |
| 558 | 558 | test_value(time.secs(), 12.3 - mjd_ref*86400.0); |
| 559 | 559 | |
| 560 | + // Test conversion to different time systems | |
| 561 | + time.utc("2005-10-08T14:30:25"); | |
| 562 | + test_value(time.convert(GTimeReference(0.0, "days", "TT", "LOCAL")), | |
| 563 | + 53651.60519889, 1.0e-6); | |
| 564 | + test_value(time.convert(GTimeReference(0.0, "days", "UTC", "LOCAL")), | |
| 565 | + 53651.60445602, 1.0e-6); | |
| 566 | + | |
| 567 | + // Test setting to different time systems | |
| 568 | + time.set(53651.60519889, GTimeReference(0.0, "days", "TT", "LOCAL")); | |
| 569 | + test_assert(time.utc() == "2005-10-08T14:30:25", | |
| 570 | + "GTime::utc(): 2005-10-08T14:30:25 expected, "+ | |
| 571 | + time.utc()+" found."); | |
| 572 | + time.set(53651.60445602, GTimeReference(0.0, "days", "UTC", "LOCAL")); | |
| 573 | + test_assert(time.utc() == "2005-10-08T14:30:25", | |
| 574 | + "GTime::utc(): 2005-10-08T14:30:25 expected, "+ | |
| 575 | + time.utc()+" found."); | |
| 576 | + | |
| 560 | 577 | // Test operators |
| 561 | 578 | GTime a(13.72); |
| 562 | 579 | GTime b(6.28); | ... | ... |