Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

SimpleTime.cpp

Go to the documentation of this file.
00001 #include "SimpleTime.h"
00002 #include "SimpleTimeDuration.h"
00003 #include "IntegerConversion.h"
00004 
00005 #include <time.h>
00006 
00007 #define DEBUG
00008 
00009 //-ap these give warnings as enums, so we simply move them here ...
00010 
00011 // DinoFM: Win32 does not support properly unsigned 64 bit integers
00012 #ifdef _WIN32
00013 
00014 const TimeT SIMPLETIME_BILLION     = 1000000000;
00016 const TimeT SIMPLETIME_UNIX_ORIGIN = 2208988800000000000;
00017 // January 19, 2038
00018 const TimeT SIMPLETIME_UNIX_MAX    = 4356476047000000000;
00019 // 2^63-1 ("infinity"), sometime in 2262
00020 const TimeT SIMPLETIME_MAX         = 9223372036854775807;
00021 #else
00022 
00023 const TimeT SIMPLETIME_BILLION     = 1000000000LL;
00025 const TimeT SIMPLETIME_UNIX_ORIGIN = 2208988800000000000LL;
00027 const TimeT SIMPLETIME_UNIX_MAX    = 4356476047000000000LL;
00028 //-ULL const TimeT SIMPLETIME_MAX         = 18446744073709551615LL;    // 2^64-1 ("infinity"), 02.07.2484
00030 const TimeT SIMPLETIME_MAX         = 9223372036854775807LL;
00031 #endif
00032 
00033 
00035 // Constructors
00037 
00038 SimpleTime::SimpleTime() {
00039   // default: now.
00040   fromUnixTime(::time(0));
00041 }
00042 
00043 
00044 
00045 SimpleTime::SimpleTime(const time_t &unix_time) {
00046   fromUnixTime(unix_time);
00047 }
00048 
00049 SimpleTime::SimpleTime(const TimeT &TimeT_time) {
00050   timeval = TimeT_time;
00051 }
00052 
00053 SimpleTime::SimpleTime(const unsigned short year,
00054                        const unsigned short month,
00055                        const unsigned short day,
00056                        const unsigned short hour,
00057                        const unsigned short min,
00058                        const unsigned short sec,
00059                        const unsigned long ns,
00060                        const bool plusInf,
00061                        const bool minusInf) {
00062   fromCalendarTime(year, month, day,
00063                    hour, min, sec, ns, plusInf, minusInf);
00064 }
00065 
00066 SimpleTime::SimpleTime(const timeAndDate_t & in) {
00067   fromCalendarTime(in);
00068 }
00069 
00070 SimpleTime::SimpleTime(const AIDA_STD::string & netloggerstring) {
00071   fromNetLogger(netloggerstring);
00072 }
00073 
00075 // Operators
00077 void SimpleTime::operator = (const SimpleTime & t) {
00078   timeval=t.toTimeT();
00079 }
00080 
00081 void SimpleTime::operator = (const TimeT & t) {
00082   timeval=t;
00083 }
00084 
00085 void SimpleTime::operator += (const SimpleTimeDuration & d) {
00086   if (isMinusInf() || isPlusInf()) { // Leave unchanged if at infinity
00087     return;
00088   } else if (d.isPlusInf()) { // Set to inf if inf added
00089     setPlusInf();
00090   } else {
00091     timeval+=d.duration();
00092   }
00093 }
00094 
00095 void SimpleTime::operator -= (const SimpleTimeDuration & d) {
00096   if (isMinusInf() || isPlusInf()) { // Leave unchanged if at infinity
00097     return;
00098   } else if (d.isPlusInf()) { // Set to -inf if inf subtracted
00099     setMinusInf();
00100   } else {
00101     timeval-=d.duration();
00102   }
00103 }
00104 
00105 #ifndef _WIN32
00106 AIDA_STD::ostream & operator << (AIDA_STD::ostream & out, const SimpleTime & t) {
00107   //  out << t.toTimeT();
00108   if (t.isPlusInf()) {
00109     out << "+Inf";
00110     return out;
00111   }
00112   if (t.isMinusInf()) {
00113     out << "-Inf";
00114     return out;
00115   }
00116   const char * mon[] = { "NONE", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" } ;
00117   out << t.year()       << "-"
00118       << mon[t.month()] << "-"
00119       << t.day()        << " "
00120       << t.hour()       << ":"
00121       << t.minute()     << ":"
00122       << t.second()     << "."
00123       << t.nanosec()    << " (GMT) ";
00124   return out;
00125 }
00126 #endif
00127 
00129 // Aux. fcns
00131 TimeT SimpleTime::time() const {
00132   std::cerr << "SimpleTime::time()> use of this method is deprecated, use toTimeT() instead" << std::endl;
00133   return timeval;
00134 }
00135 
00136 void SimpleTime::setPlusInf() {
00137   timeval = SIMPLETIME_MAX;
00138 }
00139 
00140 void SimpleTime::setMinusInf() {
00141   timeval = 0;
00142 }
00143 
00144 bool SimpleTime::isPlusInf() const {
00145   return (timeval == SIMPLETIME_MAX);
00146 }
00147 
00148 bool SimpleTime::isMinusInf() const {
00149   return (timeval == 0);
00150 }
00151 
00153 // Comparison fcns
00155 bool SimpleTime::isBefore(const SimpleTime& comparison) const {
00156   return (timeval < comparison.toTimeT());
00157 }
00158 
00160 // Conversion fcns
00162 
00163 void SimpleTime::fromNetLogger(const AIDA_STD::string & timestring) {
00164   timeAndDate_t timestruct;
00165   timestruct.plusInf=0;
00166   timestruct.minusInf=0;
00167 
00168   if (timestring=="+inf") {
00169     timestruct.plusInf=1;
00170   } else if (timestring=="-inf") {
00171     timestruct.minusInf=1;
00172   } else {
00173     UnsignedIntegerConversion<unsigned short> ushortConv;
00174     UnsignedIntegerConversion<unsigned long> ulongConv;
00175     timestruct.year = ushortConv.strtoi(timestring.substr(0,4));
00176     timestruct.month= ushortConv.strtoi(timestring.substr(4,2));
00177     timestruct.day  = ushortConv.strtoi(timestring.substr(6,2));
00178     timestruct.hour = ushortConv.strtoi(timestring.substr(8,2));
00179     timestruct.min  = ushortConv.strtoi(timestring.substr(10,2));
00180     timestruct.sec  = ushortConv.strtoi(timestring.substr(12,2));
00181     timestruct.ns   = ulongConv.strtoi(timestring.substr(15));
00182   }
00183   fromCalendarTime(timestruct);
00184 }
00185 
00186 AIDA_STD::string SimpleTime::toNetLogger() const {
00187   // Convert the internal representation to a human readable
00188   // (and sortable) string.
00189 
00190   // Infinity handling
00191   if (isPlusInf()) {
00192     return "+inf";
00193   }
00194   if (isMinusInf()) {
00195     return "-inf";
00196   }
00197 
00198   AIDA_STD::string timestring;
00199   timeAndDate_t calendarTime=toCalendarTime();
00200   UnsignedIntegerConversion<unsigned short> ushortConv;
00201   UnsignedIntegerConversion<unsigned long>  ulongConv;
00202 
00203   // When converting to strings, insert possibly leading zeros
00204   AIDA_STD::string tmp_string=ushortConv.itostr(calendarTime.year);
00205   while(tmp_string.length() < 4) // This should never be needed
00206     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00207   timestring=tmp_string;
00208   tmp_string=ushortConv.itostr(calendarTime.month);
00209   while(tmp_string.length() < 2)
00210     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00211   timestring+=tmp_string;
00212   tmp_string=ushortConv.itostr(calendarTime.day);
00213   while(tmp_string.length() < 2)
00214     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00215   timestring+=tmp_string;
00216   tmp_string=ushortConv.itostr(calendarTime.hour);
00217   while(tmp_string.length() < 2)
00218     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00219   timestring+=tmp_string;
00220   tmp_string=ushortConv.itostr(calendarTime.min);
00221   while(tmp_string.length() < 2)
00222     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00223   timestring+=tmp_string;
00224   tmp_string=ushortConv.itostr(calendarTime.sec);
00225   while(tmp_string.length() < 2)
00226     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00227   timestring+=tmp_string;
00228   tmp_string=ulongConv.itostr(calendarTime.ns);
00229   while (tmp_string.length() < 9)
00230     tmp_string.insert((AIDA_STD::string::size_type)0,1,(char)('0'));
00231   timestring+= "." + tmp_string;
00232   return timestring;
00233 }
00234 
00235 TimeT SimpleTime::toTimeT() const {
00236   return timeval;
00237 }
00238 
00239 time_t SimpleTime::toUnixTime() const {
00240   if (isPlusInf() || isMinusInf())
00241     return -1;
00242   if (timeval < SIMPLETIME_UNIX_ORIGIN || // Outside unix_time's bounds...
00243       timeval > SIMPLETIME_UNIX_MAX)
00244     return -1;
00245   else
00246     return (timeval-SIMPLETIME_UNIX_ORIGIN)/SIMPLETIME_BILLION;
00247 }
00248 
00249 void SimpleTime::fromUnixTime(const time_t &unix_time) {
00250   timeval=SIMPLETIME_UNIX_ORIGIN + unix_time*SIMPLETIME_BILLION;
00251 }
00252 
00253 void 
00254 SimpleTime::fromCalendarTime(const unsigned short in_year,
00255                  const unsigned short in_month,
00256                  const unsigned short in_day,
00257                  const unsigned short in_hour,
00258                  const unsigned short in_min,
00259                  const unsigned short in_sec,
00260                  const unsigned long in_ns,
00261                  const bool plusInf,
00262                  const bool minusInf) {
00263   timeAndDate_t timestruct;
00264   timestruct.year =in_year;
00265   timestruct.month=in_month;
00266   timestruct.day  =in_day;
00267   timestruct.hour =in_hour;
00268   timestruct.min  =in_min;
00269   timestruct.sec  =in_sec;
00270   timestruct.ns   =in_ns;
00271   timestruct.plusInf=plusInf;
00272   timestruct.minusInf=minusInf;
00273   fromCalendarTime(timestruct);
00274 }
00275 
00276 void SimpleTime:: fromCalendarTime(const timeAndDate_t & in) {
00277   // fromCalendarTime converts an instance of timeAndDate_t into the 
00278   // internal representation.
00279 
00280   // Infinity is simple... We don't care about
00281   // the rest of the struct's contents.
00282   if (in.plusInf) {
00283     setPlusInf();
00284     return;
00285   }
00286   if (in.minusInf) {
00287     setMinusInf();
00288     return;
00289   }
00290 
00291   // Simple error check on the years. TODO: Throw an exception.
00292   if ((in.year < 1900) || (in.year > 2484)) {
00293     return;
00294   }
00295   unsigned short year=in.year-1900;
00296   TimeT days=0;
00297 
00298   // Calculate number of days elapsed since the origin (1900)
00299   days = year*365 + year/4
00300     - year/100 + (year+300)/400;
00301 
00302   // Add the proper number of days according to which month it is
00303   // The first month (January) is 1.
00304   switch(in.month) {
00305   case 1: days+=0;
00306     break;
00307   case 2: days+=31; // Jan
00308     break;
00309   case 3: days+=31+28; // Feb (Leap day treatment below!)
00310     break;
00311   case 4: days+=31+28+31; // Mar
00312     break;
00313   case 5: days+=31+28+31+30; // Apr
00314     break;
00315   case 6: days+=31+28+31+30+31; // May
00316     break;
00317   case 7: days+=31+28+31+30+31+30; // Jun
00318     break;
00319   case 8: days+=31+28+31+30+31+30+31; // Jul
00320     break;
00321   case 9: days+=31+28+31+30+31+30+31+31; // Aug
00322     break;
00323   case 10: days+=31+28+31+30+31+30+31+31+30; // Sep
00324     break;
00325   case 11: days+=31+28+31+30+31+30+31+31+30+31; // Oct
00326     break;
00327   case 12: days+=31+28+31+30+31+30+31+31+30+31+30; // Nov
00328     break;
00329   default:
00330     return; // Invalid number of months. Exit and leave the time untouched.
00331     // TODO: Throw an exception.
00332     break;
00333   }
00334 
00335   // The leap day (added above, in the years section) should be subtracted
00336   // for Jan..Feb (before Feb 29), if the year is
00337   // - every 4th year (leap year),
00338   // - although not each 100th year (1900, 2100, 2200, ...)
00339   // - but still every 400th year (2000, 2400, ...)
00340   if ((  year %  4 == 0) &&
00341       (!(year %100 == 0) || ((year+300)% 400 == 0)) &&
00342       (  in.month  < 3)) {
00343     days--;
00344   }
00345 
00346   // Add day of month. The first day in the month is 1 (subtract 1).
00347   days += in.day-1;
00348 
00349   timeval=(TimeT)
00350     ((((days*24) +
00351        in.hour)*60 +
00352       in.min)*60 +
00353      in.sec)*SIMPLETIME_BILLION +
00354     in.ns;
00355 }
00356 
00357 timeAndDate_t SimpleTime::toCalendarTime() const {
00358   // toCalendarTime converts the internal representation
00359   // to an instance of timeAndDate_t.
00360 
00361   timeAndDate_t retval;
00362   retval.plusInf=retval.minusInf=0;
00363 
00364   if (isPlusInf()) {
00365     retval.plusInf=1;
00366     return retval;
00367   }
00368   if (isMinusInf()) {
00369     retval.minusInf=1;
00370     return retval;
00371   }
00372 
00373   TimeT t1, t2;
00374   SimpleTime subtractor;
00375   int leap=0;
00376 
00377   // Year section
00378   // t1 = Approx. number of years
00379   t1=(TimeT)(timeval/(365.25637*24*60*60*SIMPLETIME_BILLION));
00380   // Count number of leap days
00381   t2=t1/4 - t1/100 + (t1+300)/400;
00382   t1=(timeval-t2*24*60*60*SIMPLETIME_BILLION)/
00383     (365*24*60*60*SIMPLETIME_BILLION); // Num. of years (more acc.)
00384   retval.year=t1+1900;
00385 
00386   // Month section
00387   subtractor.fromCalendarTime(retval.year, 1, 1, 0, 0, 0, 0);
00388   t1=timeval-subtractor.toTimeT(); // Number of ns in the month part
00389   // Is it leap year?
00390   if ((  (retval.year-1900) %  4 == 0) &&
00391       (!((retval.year-1900) %100 == 0) || (((retval.year-1900)+300)% 400 == 0)))
00392     leap=1;
00393   else
00394     leap=0;
00395 
00396   // Determine the month
00397   if (t1 < (31+28+leap+31+30+31+30+31+31+30+31+30+31)*
00398       24*60*60*SIMPLETIME_BILLION)
00399     t2=12;
00400   if (t1 < (31+28+leap+31+30+31+30+31+31+30+31+30)*
00401       24*60*60*SIMPLETIME_BILLION)
00402     t2=11;
00403   if (t1 < (31+28+leap+31+30+31+30+31+31+30+31)*
00404       24*60*60*SIMPLETIME_BILLION)
00405     t2=10;
00406   if (t1 < (31+28+leap+31+30+31+30+31+31+30)*
00407       24*60*60*SIMPLETIME_BILLION)
00408     t2=9;
00409   if (t1 < (31+28+leap+31+30+31+30+31+31)*
00410       24*60*60*SIMPLETIME_BILLION)
00411     t2=8;
00412   if (t1 < (31+28+leap+31+30+31+30+31)*
00413       24*60*60*SIMPLETIME_BILLION)
00414     t2=7;
00415   if (t1 < (31+28+leap+31+30+31+30)*
00416       24*60*60*SIMPLETIME_BILLION)
00417     t2=6;
00418   if (t1 < (31+28+leap+31+30+31)*
00419       24*60*60*SIMPLETIME_BILLION)
00420     t2=5;
00421   if (t1 < (31+28+leap+31+30)*
00422       24*60*60*SIMPLETIME_BILLION)
00423     t2=4;
00424   if (t1 < (31+28+leap+31)*
00425       24*60*60*SIMPLETIME_BILLION)
00426     t2=3;
00427   if (t1 < (31+28+leap)*
00428       24*60*60*SIMPLETIME_BILLION)
00429     t2=2;
00430   if (t1 < (31)*
00431       24*60*60*SIMPLETIME_BILLION)
00432     t2=1;
00433   retval.month=t2;
00434 
00435   // Days, hours, minutes, seconds and subseconds are left
00436   subtractor.fromCalendarTime(retval.year, retval.month, 1, 0, 0, 0, 0);
00437   t1=timeval-subtractor.toTimeT();
00438   retval.day=t1/(24*60*60*SIMPLETIME_BILLION) +1;
00439   t1%=24*60*60*SIMPLETIME_BILLION;
00440   retval.hour=t1/(60*60*SIMPLETIME_BILLION);
00441   t1%=60*60*SIMPLETIME_BILLION;
00442   retval.min=t1/(60*SIMPLETIME_BILLION);
00443   t1%=60*SIMPLETIME_BILLION;
00444   retval.sec=t1/SIMPLETIME_BILLION;
00445   t1%=SIMPLETIME_BILLION;
00446   retval.ns=t1;
00447 
00448   return retval;
00449 }
00450 
00451 unsigned short SimpleTime::year() const {
00452   return toCalendarTime().year;
00453 }
00454 
00455 unsigned short SimpleTime::month() const {
00456   return toCalendarTime().month;
00457 }
00458 
00459 unsigned short SimpleTime::day() const {
00460   return toCalendarTime().day;
00461 }
00462 
00463 unsigned short SimpleTime::hour() const {
00464   return toCalendarTime().hour;
00465 }
00466 
00467 unsigned short SimpleTime::minute() const {
00468   return toCalendarTime().min;
00469 }
00470 
00471 unsigned short SimpleTime::second() const {
00472   return toCalendarTime().sec;
00473 }
00474 
00475 unsigned long SimpleTime::nanosec() const {
00476   return (unsigned long) (toTimeT()%SIMPLETIME_BILLION);
00477 }
00478 
00479 SimpleTime operator + (const SimpleTime & arg1,
00480                        const SimpleTimeDuration & arg2) {
00481   SimpleTime retval(arg1);
00482   retval += arg2;
00483   return retval;
00484 }
00485 
00486 SimpleTime operator - (const SimpleTime & arg1,
00487                        const SimpleTimeDuration & arg2) {
00488   SimpleTime retval(arg1);
00489   retval -= arg2;
00490   return retval;
00491 }

Generated on Tue May 20 14:50:25 2003 for HepUtilities by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002