From 9abfea67dddb583ee55400af6857430c3e8f68a2 Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Sun, 12 Oct 2014 23:11:11 +0200 Subject: [PATCH] Add leap second handling to convert() and set() methods and add corresponding unit tests. --- include/GTime.hpp | 8 ++++---- pyext/GTime.i | 10 ++++------ src/obs/GTime.cpp | 46 ++++++++++++++++++++++++++++++++++------------ test/test_GObservation.cpp | 17 +++++++++++++++++ 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/include/GTime.hpp b/include/GTime.hpp index e628998..0030841 100644 --- a/include/GTime.hpp +++ b/include/GTime.hpp @@ -36,7 +36,7 @@ /***********************************************************************//** * @class GTime * - * @brief Handles times in a system independent way + * @brief Time class * * The GTime class stores a time value in seconds in a GammaLib native time * reference system. The GammaLib native time reference (i.e. time=0) is @@ -68,8 +68,8 @@ public: // Constructors and destructors GTime(void); GTime(const GTime& time); - explicit GTime(const double& time, const std::string& unit = "sec"); - explicit GTime(const double& time, const GTimeReference& ref); + GTime(const double& time, const std::string& unit = "sec"); + GTime(const double& time, const GTimeReference& ref); virtual ~GTime(void); // Operators @@ -104,7 +104,7 @@ protected: int days_in_year(const int& year) const; // Protected data members - double m_time; //!< Time in seconds in native reference + double m_time; //!< Time in seconds in native reference (TT) }; diff --git a/pyext/GTime.i b/pyext/GTime.i index 72b6cfb..42ed13c 100644 --- a/pyext/GTime.i +++ b/pyext/GTime.i @@ -32,10 +32,7 @@ /***********************************************************************//** * @class GTime * - * @brief Class that handles times in a system independent way - * - * The GTime class stores a time value in seconds and its MJD reference in - * days. The time can be retrieved in any MJD reference. + * @brief Time class ***************************************************************************/ class GTime : public GBase { @@ -43,13 +40,14 @@ public: // Constructors and destructors GTime(void); GTime(const GTime& time); - explicit GTime(const double& time, const std::string& unit = "sec"); - explicit GTime(const double& time, const GTimeReference& ref); + GTime(const double& time, const std::string& unit = "sec"); + GTime(const double& time, const GTimeReference& ref); virtual ~GTime(void); // Methods void clear(void); GTime* clone(void) const; + std::string classname(void) const; double jd(void) const; double mjd(void) const; const double& secs(void) const; diff --git a/src/obs/GTime.cpp b/src/obs/GTime.cpp index 090dfb8..dd48a7d 100644 --- a/src/obs/GTime.cpp +++ b/src/obs/GTime.cpp @@ -90,14 +90,14 @@ GTime::GTime(const GTime& time) /***********************************************************************//** * @brief Time constructor * - * @param[in] time Time value (seconds or days). + * @param[in] time Time value in TT (seconds or days). * @param[in] unit Time unit (default: "secs"). * * @exception GException::time_invalid_unit * Invalid time unit specified. * * Constructs a GTime object by setting the time in the native reference - * in units of seconds (default) or days. + * in the TT time system in units of seconds (default) or days. ***************************************************************************/ GTime::GTime(const double& time, const std::string& unit) { @@ -296,9 +296,9 @@ std::string GTime::utc(void) const // argument is given in the UTC system but upon start we're in the TAI // system double leaps = leap_seconds(mjd) * gammalib::sec2day; - leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; - leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; - mjd -= leaps; + leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; + leaps = leap_seconds(mjd - leaps) * gammalib::sec2day; + mjd -= leaps; // Split in day and fraction int day = (int)mjd; @@ -367,13 +367,10 @@ std::string GTime::utc(void) const * * Convert the time from the native reference system into the specified * reference system. - * - * @todo Implement TT-UTC conversion if required. This requires - * implementation of leap seconds. ***************************************************************************/ double GTime::convert(const GTimeReference& ref) const { - // Retrieve time in native reference (seconds) + // Retrieve time in native reference (TT in seconds) double time = m_time; // Compute time offset in seconds @@ -382,6 +379,25 @@ double GTime::convert(const GTimeReference& ref) const // Add time offset in seconds time += offset; + // Subtract leap seconds in case that time is requested in UTC time + // system + if (gammalib::toupper(ref.timesys()) == "UTC") { + + // Get MJD in TAI time system + double mjd = this->mjd() - gammalib::tai2tt * gammalib::sec2day; + + // Get leap seconds (repeat is a kluge to converge as the + // argument is given in the UTC system but upon start we're in the TAI + // system + double leaps = leap_seconds(mjd); + leaps = leap_seconds(mjd - leaps * gammalib::sec2day); + leaps = leap_seconds(mjd - leaps * gammalib::sec2day); + + // Subtract leap seconds and TAI offset + time -= (leaps + gammalib::tai2tt); + + } // endif: UTC time system has been requested + // Convert to specified time unit double to_unit = ref.unitseconds(); if (to_unit != 1.0) { @@ -556,9 +572,6 @@ void GTime::utc(const std::string& time) * @param[in] ref Reference system. * * Set the time to a value given in a specific reference system. - * - * @todo Implement TT-UTC conversion if required. This requires - * implementation of leap seconds. ***************************************************************************/ void GTime::set(const double& time, const GTimeReference& ref) { @@ -571,6 +584,15 @@ void GTime::set(const double& time, const GTimeReference& ref) // Subtract time offset in seconds m_time -= offset; + // Add leap seconds in case that time was given in UTC time system + if (gammalib::toupper(ref.timesys()) == "UTC") { + + // Add leap seconds and offset between TAI and TT time system + m_time += leap_seconds(this->mjd()); + m_time += gammalib::tai2tt; + + } // endif: Time was given in UTC time system + // Return return; } diff --git a/test/test_GObservation.cpp b/test/test_GObservation.cpp index 693892a..1217844 100644 --- a/test/test_GObservation.cpp +++ b/test/test_GObservation.cpp @@ -557,6 +557,23 @@ void TestGObservation::test_time(void) time.set(12.3, GTimeReference(0.0, "secs", "TT", "LOCAL")); test_value(time.secs(), 12.3 - mjd_ref*86400.0); + // Test conversion to different time systems + time.utc("2005-10-08T14:30:25"); + test_value(time.convert(GTimeReference(0.0, "days", "TT", "LOCAL")), + 53651.60519889, 1.0e-6); + test_value(time.convert(GTimeReference(0.0, "days", "UTC", "LOCAL")), + 53651.60445602, 1.0e-6); + + // Test setting to different time systems + time.set(53651.60519889, GTimeReference(0.0, "days", "TT", "LOCAL")); + test_assert(time.utc() == "2005-10-08T14:30:25", + "GTime::utc(): 2005-10-08T14:30:25 expected, "+ + time.utc()+" found."); + time.set(53651.60445602, GTimeReference(0.0, "days", "UTC", "LOCAL")); + test_assert(time.utc() == "2005-10-08T14:30:25", + "GTime::utc(): 2005-10-08T14:30:25 expected, "+ + time.utc()+" found."); + // Test operators GTime a(13.72); GTime b(6.28); -- libgit2 0.21.4