00001 ////////////////////////////////////////////////////////////////////////////////////////////////// 00002 /*! \file Time.h 00003 * \brief Implementation of the Time class. 00004 * \author $Author: cakinli $ 00005 * \version $Revision: 1.1.1.1 $ 00006 * \date $Date: 2005/04/26 17:41:01 $ 00007 *////////////////////////////////////////////////////////////////////////////////////////////////// 00008 /* 00009 * \todo Finish implementing the rest of the time representatins. 00010 */ 00011 ////////////////////////////////////////////////////////////////////////////////////////////////// 00012 00013 #include "utils/Time.h" 00014 00015 namespace O_SESSAME { 00016 00017 static int DaysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 00018 00019 /*! \brief Calculates the Julian Date given a time in seconds since the system epoch. 00020 * \ingroup TimeUtils 00021 * \relates ssfTime 00022 * This function takes in seconds since epoch and returns the datetime in Julian Date 00023 * format. Since the input time is seconds since system epoch (Jan 1, 1970 at midnight for 00024 * linux), the JulianDate function uses the system gmtime() function to convert to a DateTime 00025 * struct. 00026 * \warning be careful of differences in system epoch times (Unix vs. Windows). 00027 * @param _time The time to be converted in seconds since the system epoch time. 00028 * @return this function returns the conversion from seconds since system epoch time to 00029 * Julian Date. 00030 */ 00031 ssfJulianDate JulianDate(const ssfSeconds &_time) 00032 { 00033 time_t t = static_cast<time_t>(floor(_time)); 00034 tm DateTime = *gmtime(&t); 00035 ssfJulianDate JD = 0; 00036 double uSec = _time - floor(_time); 00037 JD += 367 * (DateTime.tm_year + 1900); 00038 JD -= floor((7 * ((DateTime.tm_year + 1900) + floor(((DateTime.tm_mon + 1) + 9)/12))) / 4); 00039 JD += floor((275 * (DateTime.tm_mon + 1)) / 9); 00040 JD += DateTime.tm_mday; 00041 JD += 1721013.5; 00042 JD += (((DateTime.tm_sec + uSec)/60.0 + DateTime.tm_min) / 60.0 + DateTime.tm_hour) / 24; 00043 return JD; 00044 } 00045 00046 void DayofYear2YMD(int _dayOfYear, int _year, int &_month, int &_day) 00047 { 00048 int total = 0; 00049 // Is it a leap-year? 00050 if (_year % 4 == 0) 00051 DaysInMonth[1] = 29; 00052 for (_month = 0; total + DaysInMonth[_month+1] < _dayOfYear; ++_month) 00053 { 00054 total += DaysInMonth[_month]; 00055 } 00056 ++_month; 00057 _day = _dayOfYear - total; 00058 return; 00059 } 00060 00061 /*! \fn ssfJulianDate ssfTime::GetJulianDate() const 00062 * 00063 /f[ 00064 \mbox{Julian Date} & = & 367(year) - floor\left(\frac{7\left[year+floor\left(\frac{month+9}{12}\right)\right]}{4}\right) \\ 00065 & & + floor\left(\frac{275month}{9}\right) + day + 1,721,013.5\\ 00066 & & + \frac{\frac{\left(\frac{seconds}{60} + minute\right)}{60}+hour}{24} 00067 /f] 00068 */ 00069 ssfJulianDate ssfTime::GetJulianDate() const 00070 { 00071 /* 00072 time_t t = static_cast<time_t>(floor(m_StoredTime)); 00073 tm DateTime = *gmtime(&t); 00074 ssfJulianDate JD = 0; 00075 double uSec = m_StoredTime - floor(m_StoredTime); 00076 JD += 367 * (DateTime.tm_year + 1900); 00077 JD -= floor((7 * ((DateTime.tm_year + 1900) + floor(((DateTime.tm_mon + 1) + 9)/12))) / 4); 00078 JD += floor((275 * (DateTime.tm_mon + 1)) / 9); 00079 JD += DateTime.tm_mday; 00080 JD += 1721013.5; 00081 JD += (((DateTime.tm_sec + uSec)/60.0 + DateTime.tm_min) / 60.0 + DateTime.tm_hour) / 24; 00082 return JD; 00083 */ 00084 return JulianDate(m_StoredTime); 00085 } 00086 00087 ssfJulianDate ssfTime::GetEpochJulianDate() const 00088 { 00089 return JulianDate(m_EpochTime); 00090 } 00091 void ssfTime::Set(int year, int month, int day, int hour, int minute, double seconds) 00092 { 00093 tm DateTime; 00094 DateTime.tm_year = year - 1900; 00095 DateTime.tm_mon = month - 1; 00096 DateTime.tm_mday = day; 00097 DateTime.tm_hour = hour; 00098 DateTime.tm_min = minute; 00099 DateTime.tm_sec = static_cast<int>(floor(seconds)); 00100 m_StoredTime = static_cast<ssfSeconds>(timegm(&DateTime)); 00101 m_StoredTime += seconds - floor(seconds); 00102 } 00103 00104 void ssfTime::SetEpoch(int year, int month, int day, int hour, int minute, double seconds) 00105 { 00106 tm DateTime; 00107 DateTime.tm_year = year - 1900; 00108 DateTime.tm_mon = month - 1; 00109 DateTime.tm_mday = day; 00110 DateTime.tm_hour = hour; 00111 DateTime.tm_min = minute; 00112 DateTime.tm_sec = static_cast<int>(floor(seconds)); 00113 m_EpochTime = static_cast<ssfSeconds>(timegm(&DateTime)); 00114 m_EpochTime += seconds - floor(seconds); 00115 } 00116 00117 00118 void ssfTime::SetJulianDate(ssfJulianDate _newJD) 00119 { 00120 // Since the Julian Date is measured in days, while the 00121 // internal time is stored in seconds since the system epoch, 00122 // subtract the system Julian Date from the specified 00123 // Julian Date and convert to seconds. 00124 m_StoredTime = (_newJD - JulianDate(0)) * 24 * 60 * 60; 00125 return; 00126 } 00127 00128 void ssfTime::SetEpochJulianDate(ssfJulianDate _newJD) 00129 { 00130 // Since the Julian Date is measured in days, while the 00131 // internal time is stored in seconds since the system epoch, 00132 // subtract the system Julian Date from the specified 00133 // Julian Date and convert to seconds. 00134 m_EpochTime = (_newJD - JulianDate(0)) * 24 * 60 * 60; 00135 return; 00136 } 00137 00138 Angle ssfTime::GetGreenwichMeanSiderealTime() const 00139 { 00140 double Tut1 = (this->GetJulianDate() - c_GreenwichSiderealEpochTime.GetJulianDate() - 2451545) / 36525; 00141 return 1.753368560 + 628.3319706889*Tut1 + 6.7707*pow(10,-6)*pow(Tut1,2) - 4.5*pow(10,-10)*pow(Tut1,3); 00142 } 00143 00144 Angle ssfTime::GetEpochGreenwichMeanSiderealTime() const 00145 { 00146 double Tut1 = (this->GetEpochJulianDate() - c_GreenwichSiderealEpochTime.GetJulianDate() - 2451545) / 36525; 00147 return 1.753368560 + 628.3319706889*Tut1 + 6.7707*pow(10,-6)*pow(Tut1,2) - 4.5*pow(10,-10)*pow(Tut1,3); 00148 } 00149 00150 std::ostream & operator << (std::ostream& s, ssfTime& t) 00151 { 00152 s << std::setprecision(TIME_PRECISION) << t.GetSeconds(); 00153 return s; 00154 } 00155 } // close namespace O_SESSAME 00156 00157 // Do not change the comments below - they will be added automatically by CVS 00158 /***************************************************************************** 00159 * $Log: Time.cpp,v $ 00160 * Revision 1.1.1.1 2005/04/26 17:41:01 cakinli 00161 * Adding OpenSESSAME to DSACSS distrib to capture fixed version. 00162 * 00163 * Revision 1.10 2003/10/18 22:02:11 rsharo 00164 * Fixed CR-LF problem. 00165 * 00166 * Revision 1.9 2003/10/18 21:37:29 rsharo 00167 * Removed "../utils" from all qmake project paths. Prepended "utils 00168 * /" to all #include directives for utils. Removed ".h" extensions from STL header 00169 * s and referenced STL components from "std::" namespace. Overall, changed to be 00170 * more portable. 00171 * 00172 * Revision 1.8 2003/06/10 14:49:16 nilspace 00173 * removed commas from numbers. 00174 * 00175 * Revision 1.7 2003/06/10 01:11:46 nilspace 00176 * Fixed Time to build correctly (changed Greenwich epoch time to object instead of pointer) 00177 * 00178 * Revision 1.6 2003/06/09 19:41:30 nilspace 00179 * Added SetEpoch(year,month,day,hour,minute,second) 00180 * 00181 * Revision 1.5 2003/05/21 13:35:59 nilspace 00182 * Fixed the second GetJulianDate to be GetEpochJulianDate 00183 * 00184 * Revision 1.4 2003/05/21 03:57:52 nilspace 00185 * Added GetEpochJulianDate and comments to JulianDate conversion function. 00186 * 00187 * Revision 1.3 2003/05/20 17:44:21 nilspace 00188 * Updated comments. 00189 * 00190 * Revision 1.2 2003/04/27 22:04:34 nilspace 00191 * Created the namespace O_SESSAME. 00192 * 00193 * Revision 1.1 2003/04/23 14:46:49 nilspace 00194 * New Time class for simulation time. 00195 * 00196 * 00197 ******************************************************************************/ 00198