Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

Time.h

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////////////////////////
00002 /*! \file Time.h
00003 *  \brief Encapsulation of the Time object, the global time instance, and time functions.
00004 *  \author $Author: cakinli $
00005 *  \version $Revision: 1.1.1.1 $
00006 *  \date    $Date: 2005/04/26 17:41:01 $
00007 *//////////////////////////////////////////////////////////////////////////////////////////////////
00008 /* \todo Finish implementing the rest of the time representatins.
00009 */
00010 //////////////////////////////////////////////////////////////////////////////////////////////////
00011 
00012 #ifndef __SSF_TIME_H__
00013 #define __SSF_TIME_H__
00014 #include <time.h>
00015 #include <sys/time.h>
00016 #include <math.h>
00017 #include <iostream>
00018 #include <iomanip>
00019 
00020 #include "MathUtils.h"
00021 
00022 //
00023 // If <time.h> didn't define timegm()...
00024 #if !defined(timegm)
00025 //
00026 // ... Then declare a function that emulates timegm(). This function doesn't
00027 // have public documentation (doxygen) because we don't want anybody to call
00028 // it explicitly.  When people call timegm(), we'll redefine it as a 
00029 // mktime_from_utc() call only where necessary.
00030 time_t mktime_from_utc(struct tm *t);
00031 #define timegm(T) mktime_from_utc(T)
00032 #endif
00033 
00034 namespace O_SESSAME {
00035 //////////////////////////////////////////////////////////////////////////////////////////////////
00036 /*! @defgroup Utilies Utilities
00037 * The Utilities are the collection of classes and function that can provide miscellaneous functionality 
00038 * to assist with the spacecraft simulation. This includes a time object, plotting, timing of execution 
00039 * speed, interface to lower-level software and operating system components and general math functions.
00040 *
00041 * \par Extension Points:
00042 *       Any other operating system calls should be encapsulated in a utility class/function to 
00043 * ease the use of the tool/call and help promote cross-platform compatability. This may include 
00044 * file storage and retrieval functions, communications protocols, or database interoperability.
00045 */
00046 
00047 /*! @defgroup TimeUtils Time Utilities
00048 * \ingroup Utilities
00049 * @{
00050 */
00051 typedef double ssfSeconds;      /*< Simulation representation of seconds \ingroup Utilities*/
00052 typedef double ssfJulianDate;   /*< Simulation representation of Julian Dates \ingroup Utilities */
00053 
00054 #define TIME_PRECISION 15       /*< Precision of time output when outputting seconds */
00055 /*! @} */
00056 
00057 class ssfTime;
00058 
00059 /*! \brief Simulation Time object
00060 * \ingroup TimeUtils
00061 *
00062 *  ssfTime is used to encapsulate a representation of time and provide the 
00063 *       functionality for converting between different time representations (ie
00064 *       Mean Solar, Sidereal, Julian Date, etc.) The ssfTime object includes both 
00065 *       a stored time, as well as an epoch that the time can be measured from.
00066 * \par Example:
00067 * \code
00068 * ssfTime simTime;
00069 * ssfSeconds integrationTime = 10;
00070 * simTime.Set(integrationTime);
00071 * 
00072 * ssfTime nowTime(Now());
00073 * \endcode
00074 */
00075 class ssfTime
00076 {
00077 public:
00078     /*! \brief Default constructor. Initializes the time to 0 seconds. */
00079     ssfTime()                           
00080         {Set(ssfSeconds(0)); SetEpoch(ssfSeconds(0));};
00081     /*! \brief Constructor creates a time object as a copy of a time struct.
00082         * @param _Time tm struct to be copied as the time object.
00083         */
00084     ssfTime(tm _Time)                   
00085         {Set(_Time);};
00086     /*! \brief Constructor creates a time object as a copy of a timeval struct.
00087         *
00088         *  
00089         *struct timeval {
00090         *     long    tv_sec;         // seconds
00091         *     long    tv_usec;        // and microseconds
00092         *    };
00093         * @param _Time timeval struct to be copied as the time object.
00094         */
00095     ssfTime(timeval _Time)                      
00096         {Set(_Time);};
00097     /*! \brief Constructor creates time object based on number of seconds.
00098         * @param _Time number of seconds to set the time object to.
00099         */
00100     ssfTime(ssfSeconds _Time)           
00101         {Set(_Time);};
00102     
00103     /*! \brief Constructor creates time object based on a calendar date.
00104         * @param year 4-digit year (must be between 1900-2100)
00105         * @param month numeric month (1-12)
00106         * @param day day of the month (1-31)
00107         * @param hour hour in 24-hour format (0-23)
00108         * @param minute minutes of the hour (0-59)
00109         * @param seconds seconds of the minute (0-59.9999999999)
00110         */
00111     ssfTime(int year, int month, int day, int hour, int minute, double seconds)         
00112         {Set(year, month, day, hour, minute, seconds);};
00113     
00114     /*! \brief Set the ssfTime object to a specified time struct.
00115         * @param _newTime the time to store in a tm struct
00116         */
00117     void Set(tm _newTime)               
00118         {Set(static_cast<ssfSeconds>(timegm(&_newTime)));};
00119     
00120     /*! \brief Set the time object as a copy of a timeval struct.
00121         *
00122         *  
00123         * struct timeval {
00124         *     long    tv_sec;         // seconds
00125         *     long    tv_usec;        // and microseconds
00126         *     };
00127         * @param _Time timeval struct to set the time object.
00128         */
00129     void Set(timeval _Time)                     
00130         {Set(_Time.tv_sec + _Time.tv_usec/1000000.);};
00131         
00132     /*! \brief Set the ssfTime object to a specified time in seconds.
00133         * 
00134         * @param _newTime the time to store
00135         */
00136     void Set(ssfSeconds _newTime)       
00137         {m_StoredTime = _newTime;};
00138     
00139     /*! \brief Set the ssfTime object to a specified Julian Date.
00140         * @param _newJD Julian Date to set.
00141         */
00142     void SetJulianDate(ssfJulianDate _newJD);
00143         
00144     /*! \brief Set the Epoch to a specified Julian Date.
00145         * @param _newJD Julian Date to set.
00146         */
00147     void SetEpochJulianDate(ssfJulianDate _newJD);
00148     
00149     /*! \brief Set the ssfTime object based on a calendar date.
00150         * @param year 4-digit year (must be between 1900-2100)
00151         * @param month numeric month (1-12)
00152         * @param day day of the month (1-31)
00153         * @param hour hour in 24-hour format (0-23)
00154         * @param minute minutes of the hour (0-59)
00155         * @param seconds seconds of the minute (0-59.9999999999)
00156         */
00157     void Set(int year, int month, int day, int hour, int minute, double seconds);
00158         
00159     /*! \brief Set the current time after epoch.
00160         * @param _timeAfter time (in seconds) after epoch
00161         */
00162     void SetTimeAfterEpoch(ssfSeconds _timeAfter)       
00163         {Set(m_EpochTime + _timeAfter);}; 
00164     
00165     /*! \brief Set the epoch time 
00166         * @param _newEpochTime new Epoch (seconds)
00167         */
00168     void SetEpoch(ssfSeconds _newEpochTime)     
00169         {m_EpochTime = _newEpochTime;};
00170     
00171     /*! \brief Set the epoch time 
00172         * @param _newEpochTime new Epoch (tm struct)
00173         */
00174     void SetEpoch(tm _newEpochTime)     
00175         {SetEpoch(static_cast<ssfSeconds>(timegm(&_newEpochTime)));};
00176         
00177     /*! \brief Set the epoch time from a timeval struct.
00178         *
00179         *  
00180         * struct timeval {
00181         *     long    tv_sec;         // seconds
00182         *     long    tv_usec;        // and microseconds
00183         *     };
00184         * @param _Time timeval struct used to set the Epoch time.
00185         */
00186     void SetEpoch(const timeval &_Time)                         
00187         {SetEpoch(_Time.tv_sec + _Time.tv_usec/1000000.);};
00188     
00189     /*! \brief Set the epoch of the ssfTime object based on a calendar date.
00190         * @param year 4-digit year (must be between 1900-2100)
00191         * @param month numeric month (1-12)
00192         * @param day day of the month (1-31)
00193         * @param hour hour in 24-hour format (0-23)
00194         * @param minute minutes of the hour (0-59)
00195         * @param seconds seconds of the minute (0-59.9999999999)
00196         */
00197     void SetEpoch(int year, int month, int day, int hour, int minute, double seconds);
00198     
00199     /*! \brief Return the current time in seconds 
00200         * @return currently stored time (seconds)
00201         */
00202     ssfSeconds GetSeconds()  const      
00203         {return m_StoredTime;};
00204 
00205     /*! \brief Return a tm struct of the date, time of the stored time. 
00206         * @return tm struct of the date-time
00207         * @em tm Struct Definition:
00208         \code
00209         * int tm_sec;     // seconds (0 - 60) 
00210         * int tm_min;     // minutes (0 - 59) 
00211         * int tm_hour;    // hours (0 - 23) 
00212         * int tm_mday;    // day of month (1 - 31) 
00213         * int tm_mon;     // month of year (0 - 11) 
00214         * int tm_year;    // year - 1900 
00215         * int tm_wday;    // day of week (Sunday = 0) 
00216         * int tm_yday;    // day of year (0 - 365) 
00217         * int tm_isdst;   // is summer time in effect? 
00218         * char *tm_zone;  // abbreviation of timezone name 
00219         * long tm_gmtoff; // offset from UTC in seconds 
00220         \endcode
00221         * \par Example:
00222         * \code 
00223         * cout << myTime.GetDateTime().tm_mon << "/" << myTime.GetEpochDateTime().tm_mday << "/" << myTime.GetEpochDateTime().tm_year;
00224         * \endcode 
00225         * \warning does not return sub-seconds (rounded to lowest second)
00226         */
00227     tm GetDateTime()  const     
00228         {time_t t = static_cast<time_t>(floor(m_StoredTime));return *gmtime(&t);};
00229     
00230     /*! \brief Return the epoch in a tm struct of the date-time . 
00231         * @return tm struct of the date-time.
00232         *
00233         * @em tm Struct Definition:
00234         \code
00235         * int tm_sec;     // seconds (0 - 60) 
00236         * int tm_min;     // minutes (0 - 59) 
00237         * int tm_hour;    // hours (0 - 23) 
00238         * int tm_mday;    // day of month (1 - 31) 
00239         * int tm_mon;     // month of year (0 - 11) 
00240         * int tm_year;    // year - 1900 
00241         * int tm_wday;    // day of week (Sunday = 0) 
00242         * int tm_yday;    // day of year (0 - 365) 
00243         * int tm_isdst;   // is summer time in effect? 
00244         * char *tm_zone;  // abbreviation of timezone name 
00245         * long tm_gmtoff; // offset from UTC in seconds 
00246         \endcode
00247         * \par Example:
00248         * \code 
00249         * cout << myTime.GetEpochDateTime().tm_mon << "/" << myTime.GetEpochDateTime().tm_mday << "/" << myTime.GetEpochDateTime().tm_year;
00250         * \endcode 
00251         * \warning does not return sub-seconds (rounded to lowest second)
00252         */
00253     tm GetEpochDateTime()  const        
00254         {time_t t = static_cast<time_t>(floor(m_EpochTime));return *gmtime(&t);};
00255         
00256     /*! \brief Return the current Epoch 
00257         * @return currently stored epoch time (tm struct)
00258         */
00259     ssfSeconds GetEpoch() const 
00260         {return m_EpochTime;};
00261         
00262         
00263     /*! \brief Get the Julian Date of the time object.
00264         * @return This function returns the Julian Date (DETAIL JD OUTPUT)
00265         */ 
00266     ssfJulianDate GetJulianDate() const;
00267     
00268     /*! \brief Get the Julian Date of the time object's epoch.
00269         * @return This function returns the Epoch in Julian Date format (DETAIL JD OUTPUT)
00270         */ 
00271     ssfJulianDate GetEpochJulianDate() const;
00272     
00273         
00274     /*! \brief Calculate the Greenwich sidereal time of the stored time.
00275         * @return Greenwich sidereal time, measured from epoch in 1970, [rad]
00276         */ 
00277     Angle GetGreenwichMeanSiderealTime() const;
00278     
00279     /*! \brief Get the Julian Date of the time object's epoch.
00280         *
00281         * ref Vallado p.61-63
00282         * \warning need to change to accept different epochs & account for rotation of central body
00283         * @return Greenwich sidereal time of the epoch, measured from epoch in 1970, [rad]
00284         */ 
00285     Angle GetEpochGreenwichMeanSiderealTime() const;
00286 
00287     /*! \brief Return the current Epoch 
00288         *
00289         * ref Vallado p.61-63
00290         * \warning need to change to accept different epochs & account for rotation of central body
00291         * @return currently stored epoch time (tm struct)
00292         */
00293 //    tm GetEpoch() const 
00294   //      {return *gmtime(&m_EpochTime);};
00295     
00296     /*! \brief Return the time since epoch 
00297         * @return the number of seconds that have passed since epoch
00298         */
00299     ssfSeconds SecondsSinceEpoch() const
00300         {return static_cast<ssfSeconds>(m_StoredTime - m_EpochTime);};
00301     
00302     /*! \brief Add specified number of seconds to the current time and return a new object.
00303         * @param rhsSeconds Number of seconds to be added.
00304         * @return new Time object whose current time is equal to the original time plus rhsSeconds.
00305         */
00306     ssfTime operator+ (const int& rhsSeconds) const
00307         {return operator+(static_cast<ssfSeconds>(rhsSeconds));};
00308     
00309     /*! \brief Add specified number of seconds to the current time.
00310         * @param rhsSeconds Number of seconds to be added.
00311         * @return the same time object with the current time plus rhsSeconds.
00312         */    
00313     ssfTime operator+= (const int& rhsSeconds)
00314         {return operator+=(static_cast<ssfSeconds>(rhsSeconds));};       
00315 
00316     /*! \brief Add specified number of seconds to the current time and return a new object.
00317         * @param rhsSeconds Number of seconds to be added.
00318         * @return new Time object whose current time is equal to the original time plus rhsSeconds.
00319         */
00320     ssfTime operator+ (const long& rhsSeconds) const
00321         {return operator+(static_cast<ssfSeconds>(rhsSeconds));};
00322 
00323     /*! \brief Add specified number of seconds to the current time.
00324         * @param rhsSeconds Number of seconds to be added.
00325         * @return the same time object with the current time plus rhsSeconds.
00326         */ 
00327     ssfTime operator+= (const long& rhsSeconds)
00328         {return operator+=(static_cast<ssfSeconds>(rhsSeconds));}; 
00329     
00330     /*! \brief Add specified number of seconds to the current time and return a new object.
00331         * @param rhsSeconds Number of seconds to be added.
00332         * @return new Time object whose current time is equal to the original time plus rhsSeconds.
00333         */
00334     ssfTime operator+ (const ssfSeconds& rhsSeconds) const
00335         {return ssfTime(m_StoredTime + rhsSeconds);};
00336     
00337     /*! \brief Add specified number of seconds to the current time.
00338         * @param rhsSeconds Number of seconds to be added.
00339         * @return the same time object with the current time plus rhsSeconds.
00340         */ 
00341     ssfTime operator+= (const ssfSeconds& rhsSeconds)
00342         {m_StoredTime += rhsSeconds; return *this;}; 
00343         
00344     /*! \brief Subtract two time objects (the stored times).
00345         * @param rhs time object to be subtracted.
00346         * @return new time object that is the difference between the lhs and the rhs.
00347         */ 
00348     ssfSeconds operator- (const ssfTime &rhs) const
00349         {return (m_StoredTime - rhs.GetSeconds());};
00350         
00351     /*! \brief Greater than comparison two time objects (the stored times).
00352         * @param rhs time object to be compared with.
00353         * @return TRUE if the left operand's stored time is greater than the right operand's stored time, FALSE if it is not.
00354         */ 
00355     bool operator> (const ssfTime &rhs) const
00356         {return (m_StoredTime > rhs.GetSeconds());};
00357         
00358     /*! \brief Greater than or equal comparison two time objects (the stored times).
00359         * @param rhs time object to be compared with.
00360         * @return TRUE if the left operand's stored time is greater than or equal to the right operand's stored time, FALSE if it is not.
00361         */ 
00362     bool operator>= (const ssfTime &rhs) const
00363         {return (m_StoredTime >= rhs.GetSeconds());};
00364 
00365     /*! \brief Less than comparison two time objects (the stored times).
00366         * @param rhs time object to be compared with.
00367         * @return TRUE if the left operand's stored time is less than the right operand's stored time, FALSE if it is not.
00368         */ 
00369     bool operator< (const ssfTime &rhs) const
00370         {return (m_StoredTime < rhs.GetSeconds());};
00371         
00372     /*! \brief Less than or equal comparison two time objects (the stored times).
00373         * @param rhs time object to be compared with.
00374         * @return TRUE if the left operand's stored time is Less than or equal to the right operand's stored time, FALSE if it is not.
00375         */ 
00376     bool operator<= (const ssfTime &rhs) const
00377         {return (m_StoredTime <= rhs.GetSeconds());};
00378                 
00379     /*! \brief Compare the equality of two time objects (the stored times).
00380         * @param rhs time object to be compared with.
00381         * @return TRUE if the stored times are equal, FALSE if they are not.
00382         * \todo Determine if it needs to compare the Epoch times as well.
00383         */ 
00384     bool operator== (const ssfTime &rhs) const
00385         {return (m_StoredTime == rhs.GetSeconds());};
00386    
00387      /*! \brief Compare the inequality of two time objects (the stored times).
00388         * @param rhs time object to be compared with.
00389         * @return TRUE if the stored times are not equal, FALSE if they are equal.
00390         * \todo Determine if it needs to compare the Epoch times as well.
00391         */ 
00392     bool operator!= (const ssfTime &rhs) const
00393         {return (m_StoredTime != rhs.GetSeconds());};
00394                 
00395     /*! \brief output the time in seconds format
00396     */
00397     friend std::ostream & operator << (std::ostream& s, ssfTime& t);
00398 private:
00399     ssfSeconds m_StoredTime; /*!< Internally stored time (seconds) */
00400     ssfSeconds m_EpochTime;  /*!< Internatlly stored Epoch time (seconds) */
00401     
00402 };
00403 
00404     /*! \brief time used as epoch for measuring Greenwich sidereal time. 
00405     * 
00406     * 
00407     */
00408     static const ssfTime c_GreenwichSiderealEpochTime = ssfTime(1970,1,1,0,0,0);
00409     /*! actual Greenwich sidereal time at the specified epoch, m_GreenwichSiderealEpochTime. */
00410     static const Angle c_GreenwichSiderealTimeAtEpoch = 1.74933340; 
00411     
00412 /*! \brief Returns the current time in seconds since Midnight GMT, January 1st, 1970.
00413     * \ingroup TimeUtils
00414     * \relates Time
00415     * @return number of seconds since Midnight UTC, January 1st, 1970
00416     */
00417 inline ssfSeconds Now()                 
00418         {timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec + tv.tv_usec/1000000.);}
00419        // {return time((time_t *)0);}; 
00420         
00421 
00422 /*! \brief Initializes the tick/tock counter 
00423 * \ingroup TimeUtils
00424 * \relates Time
00425 *
00426 *  Used for calculating the time during operations. First tick() is called, then
00427 * when the operation has been completed tock() is called which returns the time (in seconds) 
00428 * since tick() was called.
00429 * \sa tock()
00430 \code
00431 tick();
00432 for (int ii = 0; ii < 10; ++ii) {
00433     ii += ii*ii;
00434 }
00435 cout << tock();
00436 \endcode
00437 * the sample code would output the time it took to calculate \f$\sum{ii^2}\f$ to the console.
00438 */
00439 static ssfTime tickTime(-1); /*< global variable used to store the initial tick() time */
00440 static ssfTime tockTime(-1); /*< global variable used to store the ending tock() time */
00441 
00442 inline void tick()
00443 {
00444     tickTime.Set(Now());
00445     return;
00446 }
00447 /*! \brief Stops the tick/tock counter and returns the time (in seconds) since tick() was called.
00448 * \ingroup TimeUtils
00449 * \relates Time
00450 * \sa tick()
00451 */
00452 inline ssfSeconds tock()
00453 {
00454     if(tickTime.GetSeconds() > -1)
00455     {
00456         tockTime.Set(Now());
00457         return tockTime-tickTime;
00458     }
00459     else
00460         return -1;
00461 }
00462 
00463 /*! \brief Converts the day of the year (1-365) (given a year) to the Month and Day of they year
00464 * \ingroup TimeUtils
00465 * \relates Time
00466 */
00467 void DayofYear2YMD(int _dayOfYear, int _year, int &_month, int &_day);
00468 
00469 } // close namespace O_SESSAME
00470 
00471 #endif 
00472 
00473 // Do not change the comments below - they will be added automatically by CVS
00474 /*****************************************************************************
00475 *       $Log: Time.h,v $
00476 *       Revision 1.1.1.1  2005/04/26 17:41:01  cakinli
00477 *       Adding OpenSESSAME to DSACSS distrib to capture fixed version.
00478 *       
00479 *       Revision 1.15  2003/10/18 21:54:44  rsharo
00480 *       Fixed CF-LF problem and added missing comment.
00481 *       
00482 *       Revision 1.14  2003/10/18 21:37:29  rsharo
00483 *       Removed "../utils" from all qmake project paths. Prepended "utils
00484 *       /" to all #include directives for utils. Removed ".h" extensions from STL header
00485 *       s and referenced STL components from "std::" namespace.  Overall, changed to be
00486 *       more portable.
00487 *       
00488 *       Revision 1.13  2003/06/11 14:22:34  nilspace
00489 *       Added comments to GetDateTime() and GetEpochDateTime()
00490 *       
00491 *       Revision 1.12  2003/06/10 01:11:46  nilspace
00492 *       Fixed Time to build correctly (changed Greenwich epoch time to object instead of pointer)
00493 *       
00494 *       Revision 1.11  2003/06/09 19:41:30  nilspace
00495 *       Added SetEpoch(year,month,day,hour,minute,second)
00496 *       
00497 *       Revision 1.10  2003/06/06 00:34:47  nilspace
00498 *       ?
00499 *       
00500 *       Revision 1.9  2003/05/21 03:57:52  nilspace
00501 *       Added GetEpochJulianDate and comments to JulianDate conversion function.
00502 *       
00503 *       Revision 1.8  2003/05/19 21:19:49  nilspace
00504 *       Made calls to overloaded Set() and SetEpoch() functions recursive calls to Set(ssfSeconds) and SetEpoch(ssfSeconds)
00505 *       
00506 *       Revision 1.7  2003/05/19 19:21:37  nilspace
00507 *       Added #include<sys/time.h>
00508 *       
00509 *       Revision 1.6  2003/05/16 14:01:24  nilspace
00510 *       Called gettimeofday(timeval*) to have Now(), and tick/tock return seconds with subsecond decimal parts.
00511 *       
00512 *       Revision 1.5  2003/05/09 23:44:29  nilspace
00513 *       Added operator!=()
00514 *       
00515 *       Revision 1.4  2003/04/30 16:32:48  nilspace
00516 *       Added operator== to ssfTime
00517 *       
00518 *       Revision 1.3  2003/04/27 22:04:34  nilspace
00519 *       Created the namespace O_SESSAME.
00520 *       
00521 *       Revision 1.2  2003/04/25 13:45:56  nilspace
00522 *       const'd Get() functions.
00523 *       
00524 *       Revision 1.1  2003/04/23 14:14:45  nilspace
00525 *       New simulation time.
00526 *       
00527 *
00528 ******************************************************************************/

Generated on Wed Sep 5 12:54:26 2007 for DSACSS Operational Code by  doxygen 1.3.9.1