Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

CTBtime.cxx

Go to the documentation of this file.
00001 
00006 /*----------------------------------------------------------------------------*/
00007 /* C Tool Box: Designed and implemented by:                                   */
00008 /*    Walter F.J. Mueller   Gesellschaft fuer Schwerionenforschung (GSI)      */
00009 /*                          Planckstrasse 1, D-64291 Darmstadt, Germany       */
00010 /*                  Email:  W.F.J.Mueller@gsi.de                              */
00011 /*                  WWW:    http://www-kp3.gsi.de/www/kp3/people/mueller.html */
00012 /*------------------------------------------+---------------------------------*/
00013 
00014 #include "CTB.hxx"
00015 #include "CTBioState.hxx"
00016 #include "CTBosFill.hxx"
00017 #include "CTBprintf.hxx"
00018 #include "CTBnum.hxx"
00019 #include "CTBtime.hxx"
00020 
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <ctype.h>
00024 #include <time.h>
00025 #include <sys/time.h>
00026 #include <unistd.h>
00027 #include <math.h>
00028 
00041 //------------------------------------------+-----------------------------------
00043 
00044 void CTBtime::GetSystemTime()
00045 {
00046   timeval  tv;
00047 
00048   if(gettimeofday(&tv,0) ==  0) {
00049     md_time = (double)tv.tv_sec + 1.e-6 * (double)tv.tv_usec;
00050   } else {
00051     md_time = -1.;
00052   }
00053   
00054   return;
00055 }
00056 
00057 //------------------------------------------+-----------------------------------
00059 
00060 void CTBtime::Split(CTBint32& i_sec, CTBint32& i_usec) const
00061 {
00062   if (Valid()) {
00063     double d_sec  = floor(md_time);
00064     double d_usec = floor(1.e6*(md_time-d_sec));
00065 
00066     if (d_usec >= 1.e6) {
00067       d_sec  += 1.;
00068       d_usec -= 1.e6;
00069     }
00070     i_sec  = (CTBint32) d_sec;
00071     i_usec = (CTBint32) d_usec;
00072     
00073   } else {
00074     i_sec  = -1;
00075     i_usec = 0;
00076   }
00077   
00078   return;
00079 }
00080 
00081 //------------------------------------------+-----------------------------------
00083 
00084 void CTBtime::ToStream(ostream& os) const
00085 {
00086   CTBtimeParsed tp = *this;
00087   tp.ToStream(os);
00088   return;
00089 }
00090 
00091 //------------------------------------------+-----------------------------------
00093 
00094 void CTBtime::FromStream(istream& is)
00095 {
00096   CTBtimeParsed tp;
00097 
00098   tp.FromStream(is);
00099   *this = tp.MakeTime();
00100 
00101   return;
00102 }
00103 
00104 //------------------------------------------+-----------------------------------
00106 
00117 CTBint32 CTBtime::ymdhms2ui(int i_year, int i_month, int i_day,
00118                             int i_hour, int i_min, int i_sec)
00119 {
00120   struct tm  s_time;
00121   time_t     i_time;
00122 
00123   i_year  -= 1900;                          // counting years from 1900 here
00124   i_month -= 1;                             // counting month from 0 here 
00125   
00126   s_time.tm_sec    = i_sec;
00127   s_time.tm_min    = i_min;
00128   s_time.tm_hour   = i_hour;
00129   s_time.tm_mday   = i_day;
00130   s_time.tm_mon    = i_month;
00131   s_time.tm_year   = i_year;
00132   s_time.tm_wday   =  0;
00133   s_time.tm_yday   =  0;
00134   s_time.tm_isdst  = -1;                    // let mktime find out about DST
00135 
00136   i_time = mktime(&s_time);
00137   
00138   if (s_time.tm_sec  != i_sec ||            // quit on any time wrap
00139       s_time.tm_min  != i_min ||
00140       s_time.tm_hour != i_hour ||
00141       s_time.tm_mday != i_day ||
00142       s_time.tm_mon  != i_month ||
00143       s_time.tm_year != i_year) return -1;
00144   
00145   return i_time;
00146 }
00147 
00148 //------------------------------------------+-----------------------------------
00150 
00151 CTBint32 CTBtime::vms2ui(const char* c_time)
00152 {
00153   int           i_year   = -1;
00154   int           i_month  = -1;
00155   int           i_day    = -1;
00156   int           i_hour   =  0;
00157   int           i_min    =  0;
00158   int           i_sec    =  0;
00159   int           ni_year  = -1;
00160   int           ni_month = -1;
00161   int           ni_day   = -1;
00162   int           ni_hour  = -1;
00163   int           ni_min   = -1;
00164   int           ni_sec   = -1;
00165   char          c_dtsep  = 0;
00166   
00167   char          c_month[4];
00168   char          *c_mtable[12] =
00169                       {"JAN","FEB","MAR","APR","MAY","JUN",
00170                        "JUL","AUG","SEP","OCT","NOV","DEC"};
00171 
00172   c_month[0] = 0;                           // init month string to null string
00173 
00174   (void) sscanf(c_time,"%d%n-%3s%n-%d%n%c%d%n:%d%n:%d%n",
00175                 &i_day,&ni_day,c_month,&ni_month,&i_year,&ni_year,
00176                 &c_dtsep,&i_hour,&ni_hour,&i_min,&ni_min,&i_sec,&ni_sec);
00177 
00178 //  printf("%d %d - %s %d - %d %d | %c | %d %d : %d %d : %d %d \n",
00179 //       i_day,ni_day,c_month,ni_month,i_year,ni_year,
00180 //       c_dtsep,i_hour,ni_hour,i_min,ni_min,i_sec,ni_sec);
00181 
00182   if (ni_day == -1) return -1;              // day not converted
00183   if (c_time[ni_day] != '-') return -1;     // dd-mmm delimiter not '-'
00184   if (ni_month == -1) return -1;            // month not converted
00185   if (c_time[ni_month] != '-') return -1;   // mmm-yyyy delimiter not '-'
00186   if (ni_year == -1) return -1;             // year not converted
00187   if (c_time[ni_year] != ' ' &&             // yyyy:hh delimiter not ' ' or ':'
00188       c_time[ni_year] != ':' &&
00189       c_time[ni_year] != 0) return -1;
00190   if (ni_hour > 0 &&                        // if hh converted
00191       c_time[ni_hour] != ':' &&             // hh:mm delimeter better be ':'
00192       c_time[ni_hour] != 0) return -1;
00193   if (ni_min > 0 &&                         // if mm converted
00194       c_time[ni_sec] != ':' &&              // mm:ss delimeter better be ':'
00195       c_time[ni_sec] != 0) return -1;
00196   if (ni_sec > 0 &&                         // if ss converted
00197       c_time[ni_sec] != 0) return -1;       // ss better delimter by string end
00198 
00199   for (int i = 0; i < 3; i++) c_month[i] = toupper(c_month[i]);
00200 
00201   i_month    = -1;                          // init in case of no match
00202 
00203   for (int i = 0; i < 12; i++) {            // check against month string table
00204     if (strcmp(c_mtable[i],c_month) == 0) {
00205       i_month = i+1;
00206       break;
00207     }
00208   }  
00209 
00210   if (i_month == -1) return -1;             // month not identified
00211 
00212   if (i_year < 100) {                       // handle 2 digit years
00213     if (i_year >= 70) i_year += 1900;       // after  70 -> 19xx
00214     else i_year += 2000;                    // before 70 -> 20xx
00215   }
00216   
00217   return ymdhms2ui(i_year,i_month,i_day,i_hour,i_min,i_sec);
00218 }
00219 
00220 //------------------------------------------+-----------------------------------
00222 
00228 void CTBtime::ui2local(char* c_time, int i_size,
00229                        const char* c_format, CTBint32 i_time)
00230 {
00231   time_t      i_time_val = i_time;
00232   struct tm*  ps_time = localtime(&i_time_val);
00233 
00234   strftime(c_time,i_size,c_format,ps_time);
00235   
00236   return;
00237 }
00238 
00239 //------------------------------------------+-----------------------------------
00241 
00247 void CTBtime::ui2utc(char* c_time, int i_size,
00248                        const char* c_format, CTBint32 i_time)
00249 {
00250   time_t      i_time_val = i_time;
00251   struct tm*  ps_time = gmtime(&i_time_val);
00252 
00253   strftime(c_time,i_size,c_format,ps_time);
00254   
00255   return;
00256 }
00257 
00258 //------------------------------------------+-----------------------------------
00260 
00265 void CTBtime::ui2vms(char c_time[21], CTBint32 i_time)
00266 {
00267   ui2local(c_time,21,"%d-%b-%Y %H:%M:%S",i_time);  
00268   return;
00269 }
00270 
00271 //##############################################################################
00277 //------------------------------------------+-----------------------------------
00279 
00280 void CTBtimeParsed::ParseTime(const CTBtime& time)
00281 {
00282 
00283   if (time.Valid()) {
00284     CTBint32 i_sec;
00285     CTBint32 i_usec;
00286 
00287     time.Split(i_sec,i_usec);
00288 
00289     time_t i_time = i_sec;
00290     tm*    p_time = localtime(&i_time);
00291     
00292     mi_year     = p_time->tm_year + 1900;   // tm returns # of years since 1900
00293     mi_month    = p_time->tm_mon  + 1;      // tm returns 0=jan
00294     mi_day      = p_time->tm_mday;
00295     mi_wday     = p_time->tm_wday;
00296     mi_yday     = p_time->tm_yday;
00297     mi_hour     = p_time->tm_hour;
00298     mi_min      = p_time->tm_min;
00299     mi_sec      = p_time->tm_sec;
00300     mi_usec     = i_usec;
00301     mi_tzoffset = __timezone;
00302     mi_dst      = p_time->tm_isdst;
00303     if (mi_dst > 0) {
00304       strncpy(mc_tzname,__tzname[1],8);
00305       mc_tzname[7] = 0;
00306       mi_tzoffset -= 3600;
00307     } else {
00308       strncpy(mc_tzname,__tzname[0],8);
00309       mc_tzname[7] = 0;
00310     }
00311 
00312   } else {
00313     Init();
00314   }
00315 
00316   return;
00317 }
00318 
00319 //------------------------------------------+-----------------------------------
00321 
00322 CTBtime CTBtimeParsed::MakeTime()
00323 {
00324   double d_time = -1.;
00325   tm     s_time;
00326   
00327   s_time.tm_year  = mi_year  - 1900;        // tm wants # of years since 1900
00328   s_time.tm_mon   = mi_month - 1;           // tm wants 0 based month (0=jan)
00329   s_time.tm_mday  = mi_day;
00330   s_time.tm_wday  = -1;
00331   s_time.tm_yday  = -1;
00332   s_time.tm_hour  = mi_hour;
00333   s_time.tm_min   = mi_min;
00334   s_time.tm_sec   = mi_sec;
00335   s_time.tm_isdst = mi_dst;
00336   
00337   time_t i_time = mktime(&s_time);
00338   if (i_time >= 0) {
00339     d_time      = (double)i_time + 1.e-6*mi_usec;
00340     mi_year     = s_time.tm_year + 1900;
00341     mi_month    = s_time.tm_mon  + 1;
00342     mi_day      = s_time.tm_mday;
00343     mi_wday     = s_time.tm_wday;
00344     mi_yday     = s_time.tm_yday;
00345     mi_hour     = s_time.tm_hour;
00346     mi_min      = s_time.tm_min;
00347     mi_sec      = s_time.tm_sec;
00348     mi_dst      = s_time.tm_isdst;
00349     mi_tzoffset = __timezone;               // ??? is timezone really defined ?
00350     if (mi_dst > 0) {
00351       strncpy(mc_tzname,__tzname[1],8);
00352       mc_tzname[7] = 0;
00353       mi_tzoffset -= 3600;
00354     } else {
00355       strncpy(mc_tzname,__tzname[0],8);
00356       mc_tzname[7] = 0;
00357     }
00358   }
00359   return CTBtime(d_time);
00360 }
00361 
00362 //------------------------------------------+-----------------------------------
00364 
00374 void CTBtimeParsed::ToStream(ostream& os) const
00375 {
00376   if (Valid()) {
00377     os << CTBprintf(mi_year,"d0",4) 
00378        << "-" << CTBprintf(mi_month,"d0",2)
00379        << "-" << CTBprintf(mi_day,"d0",2)
00380        << " " << CTBprintf(mi_hour,"d0",2)
00381        << ":" << CTBprintf(mi_min,"d0",2)
00382        << ":" << CTBprintf(mi_sec,"d0",2);
00383 
00384     if (mi_usec != 0) os << "." << CTBprintf(mi_usec,"d0",6);
00385 
00386     int i_tzs = CTBabs(mi_tzoffset);
00387     int i_tzh = i_tzs/3600;
00388     int i_tzm = (i_tzs-3600*i_tzh)/60;
00389     os << " " << ((mi_tzoffset>0) ? '-' : '+')   // sign is reversed here !
00390        << CTBprintf(i_tzh,"d0",2) << CTBprintf(i_tzm,"d0",2);
00391   } else {
00392     os << "0000-00-00 00:00:00 +0000";
00393   }
00394   
00395   return;
00396 }
00397 
00398 //------------------------------------------+-----------------------------------
00400 
00409 void CTBtimeParsed::FromStream(istream& is)
00410 {
00411   CTBioState iostate(is,"d");
00412   double     d_secfrac;
00413   int        i_tzoff;
00414   
00415   Init();
00416   is >> mi_year;
00417 
00418   if (is.get() != '-') is.setstate(ios::failbit);
00419   is >> mi_month;
00420 
00421   if (is.get() != '-') is.setstate(ios::failbit);
00422   is >> mi_day;
00423 
00424   is >> mi_hour;
00425 
00426   if (is.get() != ':') is.setstate(ios::failbit);
00427   is >> mi_min;
00428 
00429   if (is.get() != ':') is.setstate(ios::failbit);
00430   is >> d_secfrac;
00431   double d_sec = floor(d_secfrac);
00432   mi_sec  = (int) floor(d_sec);
00433   mi_usec = (int) floor(1.e6*(d_secfrac-d_sec));
00434 
00435   is >> i_tzoff;                            // ??? currently IGNORED !!!
00436 
00437   return;
00438 }
00439 
00440 //------------------------------------------+-----------------------------------
00442 
00443 void CTBtimeParsed::Dump(int i_indent, ostream& os, const char* p_text) const
00444 {
00445   CTBosFill bl(i_indent);
00446   os << bl << "--CTBtimeParsed ";
00447   if (p_text) os << p_text;
00448   os << " @ " << this << endl;
00449   os << bl << "    mi_year:     " << CTBprintf(mi_year,"d",6) << "\n";
00450   os << bl << "    mi_month:    " << CTBprintf(mi_month,"d",6) << "\n";
00451   os << bl << "    mi_day:      " << CTBprintf(mi_day,"d",6) << "\n";
00452   os << bl << "    mi_wday:     " << CTBprintf(mi_wday,"d",6) << "\n";
00453   os << bl << "    mi_yday:     " << CTBprintf(mi_yday,"d",6) << "\n";
00454   os << bl << "    mi_hour:     " << CTBprintf(mi_hour,"d",6) << "\n";
00455   os << bl << "    mi_min:      " << CTBprintf(mi_min,"d",6) << "\n";
00456   os << bl << "    mi_sec:      " << CTBprintf(mi_sec,"d",6) << "\n";
00457   os << bl << "    mi_usec:     " << CTBprintf(mi_usec,"d",6) << "\n";
00458   os << bl << "    mi_tzoffset: " << CTBprintf(mi_tzoffset,"d",6) << "\n";
00459   os << bl << "    mc_tzname:   " << mc_tzname << "\n";
00460   os << bl << "    mi_dst:      " << mi_dst << "\n";
00461 
00462   return;
00463 }
00464 
00465 //------------------------------------------+-----------------------------------
00467 
00468 CTBtimeParsed::operator CTBtime() const
00469 {
00470   CTBtimeParsed temp(*this);
00471   return temp.MakeTime();
00472 }
00473 
00474 //------------------------------------------+-----------------------------------
00476 
00477 void CTBtimeParsed::Init()
00478 {
00479   mi_year      =  0;
00480   mi_month     =  0;
00481   mi_day       =  0;
00482   mi_wday      = -1;
00483   mi_yday      = -1;
00484   mi_hour      =  0;
00485   mi_min       =  0;
00486   mi_sec       =  0;
00487   mi_usec      =  0;
00488   mi_tzoffset  =  0;
00489   mc_tzname[0] =  0;
00490   mi_dst       = -1;
00491   return;
00492 }

Generated at Fri Oct 24 18:11:30 2003 for CTBbase by doxygen1.2.9-20010812 written by Dimitri van Heesch, © 1997-2001