| [2654] | 1 | #include "machdefs.h"
 | 
|---|
 | 2 | #include <stdio.h>
 | 
|---|
 | 3 | #include <time.h>
 | 
|---|
 | 4 | #include <ctype.h>
 | 
|---|
 | 5 | #include <math.h>
 | 
|---|
 | 6 | #include "timestamp.h"
 | 
|---|
 | 7 | #include "pexceptions.h"
 | 
|---|
 | 8 | #include <iostream>
 | 
|---|
 | 9 | 
 | 
|---|
| [3232] | 10 | namespace SOPHYA {
 | 
|---|
 | 11 | 
 | 
|---|
| [2805] | 12 | /*!
 | 
|---|
| [3233] | 13 |    \class TimeStamp
 | 
|---|
| [2805] | 14 |    \ingroup BaseTools
 | 
|---|
 | 15 |    A simple class for representing date and time. Simple operations 
 | 
|---|
 | 16 |    on date/time are also provided. 
 | 
|---|
 | 17 |    
 | 
|---|
 | 18 |    \code
 | 
|---|
 | 19 |    // Create a object with the current date and time and prints it to cout
 | 
|---|
 | 20 |    TimeStamp ts; 
 | 
|---|
 | 21 |    cout << ts << endl;
 | 
|---|
 | 22 |    // Create an object with a specified date and time 
 | 
|---|
 | 23 |    TimeStamp ts2("01/01/1905","00:00:00");
 | 
|---|
 | 24 |    // Get the number of days since 0 Jan 1901
 | 
|---|
 | 25 |    cout << ts2.ToDays() << endl;
 | 
|---|
 | 26 |    \endcode
 | 
|---|
 | 27 | */
 | 
|---|
 | 28 | 
 | 
|---|
| [2656] | 29 | #ifdef Linux 
 | 
|---|
 | 30 | // La fonction trunc non declaree ds math.h sous Linux
 | 
|---|
| [2666] | 31 | extern "C" { double trunc   (double x); }
 | 
|---|
| [2656] | 32 | #endif
 | 
|---|
| [2654] | 33 | //-------------------------------------------------------------------------
 | 
|---|
 | 34 | //--------------------------  Classe TimeStamp   --------------------------
 | 
|---|
 | 35 | //-------------------------------------------------------------------------
 | 
|---|
| [2805] | 36 | 
 | 
|---|
| [2654] | 37 | enum Jour {jour_Lundi=0, jour_Mardi, jour_Mercredi, jour_Jeudi, jour_Vendredi, jour_Samedi, jour_Dimanche};
 | 
|---|
 | 38 | enum Mois {mois_Janvier=1, mois_Fevrier, mois_Mars, mois_Avril, mois_Mai, mois_Juin, mois_Juillet,
 | 
|---|
 | 39 |                    mois_Aout, mois_Septembre, mois_Octobre, mois_Novembre, mois_Decembre};
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 |   /*
 | 
|---|
 | 42 |   //! Day of the week enum
 | 
|---|
 | 43 |   enum WeekDay {day_Monday=0, day_Tuesday, day_Wednesday, day_Thursday, day_Friday, day_Saturday, day_Sunday};
 | 
|---|
 | 44 |   */
 | 
|---|
 | 45 |  
 | 
|---|
 | 46 | TimeStamp::TimeStamp()
 | 
|---|
 | 47 | {
 | 
|---|
 | 48 |   mSeconds = 0.;
 | 
|---|
 | 49 |   mDays = 0;
 | 
|---|
 | 50 |   SetNow();
 | 
|---|
 | 51 | }
 | 
|---|
 | 52 | 
 | 
|---|
 | 53 | TimeStamp::TimeStamp(TimeStamp const & ts)
 | 
|---|
 | 54 | {
 | 
|---|
 | 55 |   Set(ts);
 | 
|---|
 | 56 |   mSeconds = ts.mSeconds;
 | 
|---|
 | 57 |   mDays = ts.mDays;
 | 
|---|
 | 58 | }
 | 
|---|
 | 59 | 
 | 
|---|
 | 60 | TimeStamp::TimeStamp(int year, int month, int day, int hour, int min, double sec)
 | 
|---|
 | 61 | {
 | 
|---|
 | 62 |   SetDate(year, month, day);
 | 
|---|
 | 63 |   SetHour(hour, min, sec);
 | 
|---|
 | 64 | }
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 | TimeStamp::TimeStamp(double days)
 | 
|---|
 | 68 | {
 | 
|---|
 | 69 |   Set(days);
 | 
|---|
 | 70 | }
 | 
|---|
 | 71 | 
 | 
|---|
| [2826] | 72 | TimeStamp::TimeStamp(int_8 days, r_8 seconds)
 | 
|---|
 | 73 | {
 | 
|---|
 | 74 |   Set(days, seconds);
 | 
|---|
 | 75 | }
 | 
|---|
 | 76 | 
 | 
|---|
| [2830] | 77 | TimeStamp::TimeStamp(string const & date, string const & hour)
 | 
|---|
| [2654] | 78 | {
 | 
|---|
 | 79 |   SetDate(date);
 | 
|---|
 | 80 |   SetHour(hour);
 | 
|---|
 | 81 | }
 | 
|---|
 | 82 | 
 | 
|---|
 | 83 | TimeStamp::TimeStamp(const char* date, const char* hour)
 | 
|---|
 | 84 | {
 | 
|---|
 | 85 |   SetDate(date);
 | 
|---|
 | 86 |   SetHour(hour);
 | 
|---|
 | 87 | }
 | 
|---|
 | 88 | 
 | 
|---|
| [2830] | 89 | TimeStamp::TimeStamp(string& datim)
 | 
|---|
 | 90 | {
 | 
|---|
 | 91 |   Set(datim);
 | 
|---|
 | 92 | }
 | 
|---|
| [2654] | 93 | 
 | 
|---|
| [2830] | 94 | TimeStamp::TimeStamp(const char* datim)
 | 
|---|
 | 95 | {
 | 
|---|
 | 96 |   Set(datim);
 | 
|---|
 | 97 | }
 | 
|---|
 | 98 | 
 | 
|---|
| [2654] | 99 | void TimeStamp::Set(TimeStamp const & ts)
 | 
|---|
 | 100 | {
 | 
|---|
 | 101 |   mSeconds = ts.mSeconds;
 | 
|---|
 | 102 |   mDays = ts.mDays;
 | 
|---|
 | 103 | }
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 | void TimeStamp::Set(double days)
 | 
|---|
 | 106 | {
 | 
|---|
| [2826] | 107 |   if (days >= 0.) {
 | 
|---|
| [2830] | 108 |     mDays = (int_8)trunc(days);
 | 
|---|
| [2826] | 109 |     mSeconds = (days-trunc(days))*86400.;
 | 
|---|
| [2654] | 110 |   }
 | 
|---|
 | 111 |   else {
 | 
|---|
| [2826] | 112 |     if ( (trunc(days)-days) > 0.) {
 | 
|---|
| [2830] | 113 |       mDays = (int_8)trunc(days)-1;
 | 
|---|
| [2826] | 114 |       mSeconds = (days-mDays)*86400.;
 | 
|---|
 | 115 |     }
 | 
|---|
 | 116 |     else {
 | 
|---|
| [2830] | 117 |       mDays = (int_8)trunc(days);
 | 
|---|
| [2826] | 118 |       mSeconds = 0.;
 | 
|---|
 | 119 |     }
 | 
|---|
| [2654] | 120 |   }
 | 
|---|
 | 121 | }
 | 
|---|
 | 122 | 
 | 
|---|
| [2826] | 123 | void TimeStamp::Set(int_8 days, r_8 seconds)
 | 
|---|
 | 124 | {
 | 
|---|
 | 125 |   if ( (seconds < 0.) || (seconds > 86400.) ) 
 | 
|---|
 | 126 |     throw ParmError("TimeStamp::Set(int_8, r_8) seconds<0 or seconds>86400.");
 | 
|---|
 | 127 |   mDays = days;
 | 
|---|
| [2830] | 128 |   mSeconds = seconds;
 | 
|---|
| [2826] | 129 | }
 | 
|---|
 | 130 | 
 | 
|---|
| [2830] | 131 | void TimeStamp::Set(const char * datim)
 | 
|---|
 | 132 | {
 | 
|---|
 | 133 |   int year, month, day;
 | 
|---|
 | 134 |   int hour, min;
 | 
|---|
 | 135 |   double sec;
 | 
|---|
 | 136 |   sscanf(datim,"%d-%d-%dT%d:%d:%lf", &year, &month, &day,
 | 
|---|
 | 137 |          &hour, &min, &sec);
 | 
|---|
 | 138 |   SetDate(year, month, day);
 | 
|---|
 | 139 |   SetHour(hour, min, sec);
 | 
|---|
 | 140 | }
 | 
|---|
 | 141 | 
 | 
|---|
 | 142 | 
 | 
|---|
| [2654] | 143 | void TimeStamp::SetNow()
 | 
|---|
 | 144 | {
 | 
|---|
 | 145 |   time_t t = time(NULL);
 | 
|---|
 | 146 |   struct tm* TM = gmtime(&t);
 | 
|---|
 | 147 | 
 | 
|---|
 | 148 |   int JJ,MM,AA;
 | 
|---|
 | 149 |   int hh,mm;
 | 
|---|
 | 150 |   double ss; 
 | 
|---|
 | 151 |   
 | 
|---|
 | 152 |   AA = TM->tm_year + 1900;
 | 
|---|
 | 153 |   MM = TM->tm_mon+1;
 | 
|---|
 | 154 |   JJ = TM->tm_mday;
 | 
|---|
 | 155 |   hh = TM->tm_hour;
 | 
|---|
 | 156 |   mm = TM->tm_min;
 | 
|---|
 | 157 |   ss = TM->tm_sec;
 | 
|---|
 | 158 |   SetDate(AA,MM,JJ);
 | 
|---|
 | 159 |   SetHour(hh,mm,ss);
 | 
|---|
 | 160 | }
 | 
|---|
 | 161 | 
 | 
|---|
 | 162 | void TimeStamp::SetDate(int year, int month, int day)
 | 
|---|
 | 163 | {
 | 
|---|
 | 164 |   mDays = ConvertToDays(year, month, day);
 | 
|---|
 | 165 | }
 | 
|---|
 | 166 | 
 | 
|---|
 | 167 | void TimeStamp::SetDate(const char* date)
 | 
|---|
 | 168 | {
 | 
|---|
 | 169 |   int day,month,year;
 | 
|---|
 | 170 |   sscanf(date,"%d/%d/%d", &day, &month, &year);
 | 
|---|
 | 171 |   mDays = ConvertToDays(year, month, day);
 | 
|---|
 | 172 | }
 | 
|---|
 | 173 | 
 | 
|---|
 | 174 | void TimeStamp::SetHour(int hour, int min, double sec)
 | 
|---|
 | 175 | {
 | 
|---|
 | 176 |   mSeconds = hour*3600.+min*60+sec;
 | 
|---|
 | 177 | }
 | 
|---|
 | 178 | 
 | 
|---|
 | 179 | void TimeStamp::SetHour(const char* shour)
 | 
|---|
 | 180 | {
 | 
|---|
 | 181 |   int hour, min;
 | 
|---|
 | 182 |   double sec;
 | 
|---|
 | 183 |   sscanf(shour,"%d:%d:%lf",&hour, &min, &sec);
 | 
|---|
 | 184 |   mSeconds = hour*3600.+min*60+sec;
 | 
|---|
 | 185 | 
 | 
|---|
 | 186 | }
 | 
|---|
 | 187 | 
 | 
|---|
 | 188 | void TimeStamp::GetDate(int& year, int& month, int& day) const
 | 
|---|
 | 189 | {
 | 
|---|
 | 190 |   int_8 jours = mDays;
 | 
|---|
 | 191 |   // Recherche de l'annee
 | 
|---|
 | 192 |   if (jours < 0) {
 | 
|---|
 | 193 |     year = 1901;
 | 
|---|
 | 194 |     while(jours < 0)  { 
 | 
|---|
 | 195 |       year--;
 | 
|---|
 | 196 |       jours += YearDays(year); 
 | 
|---|
 | 197 |     }
 | 
|---|
 | 198 |   }
 | 
|---|
 | 199 |   else {
 | 
|---|
 | 200 |     year = 1901;
 | 
|---|
 | 201 |     while(jours > YearDays(year))  { 
 | 
|---|
 | 202 |       jours -= YearDays(year); 
 | 
|---|
 | 203 |       year++;
 | 
|---|
 | 204 |     }
 | 
|---|
 | 205 |   }
 | 
|---|
 | 206 |   // Recherche du mois
 | 
|---|
 | 207 |   month = 1;
 | 
|---|
 | 208 |   while(jours > MonthDays(year, month) )  { 
 | 
|---|
 | 209 |     jours -= MonthDays(year, month);
 | 
|---|
 | 210 |     month++;
 | 
|---|
 | 211 |   }
 | 
|---|
 | 212 |   day = jours;
 | 
|---|
 | 213 | }
 | 
|---|
 | 214 | 
 | 
|---|
 | 215 | void TimeStamp::GetHour(int& hour, int& min, double& sec) const
 | 
|---|
 | 216 | {
 | 
|---|
 | 217 |   double seconds = mSeconds;
 | 
|---|
| [2830] | 218 |   hour = (int)trunc(seconds/3600.);
 | 
|---|
| [2654] | 219 |   seconds -= hour*3600;
 | 
|---|
| [2830] | 220 |   min = (int)trunc(seconds/60.);
 | 
|---|
| [2826] | 221 |   while (min >= 60) { hour++; min -= 60; }
 | 
|---|
| [2654] | 222 |   sec = seconds-min*60;
 | 
|---|
| [2826] | 223 |   while (sec >= 60.) { min++; sec -= 60.; }
 | 
|---|
| [2654] | 224 | }
 | 
|---|
| [2826] | 225 | 
 | 
|---|
| [2654] | 226 | double TimeStamp::ToDays() const
 | 
|---|
 | 227 | {
 | 
|---|
 | 228 |   return((double)mDays + mSeconds/86400.);
 | 
|---|
 | 229 | }
 | 
|---|
 | 230 | 
 | 
|---|
| [2826] | 231 | /*!
 | 
|---|
| [2830] | 232 | \param fmt : String format for the date 
 | 
|---|
 | 233 |   - FmtPackedDateTime : YYYY-MM-DDThh:mm:ss.s
 | 
|---|
 | 234 |   - FmtDateOnly : dd/mm/yyyy
 | 
|---|
 | 235 |   - FmtTimeOnly : hh:mm:ss.s
 | 
|---|
 | 236 |   - FmtDateTime : dd/mm/yyyy hh:mm:ss.s UT
 | 
|---|
| [2826] | 237 | */
 | 
|---|
| [2830] | 238 | string TimeStamp::ToString(StrFmt fmt) const
 | 
|---|
| [2654] | 239 | {
 | 
|---|
 | 240 |   char buff[128];
 | 
|---|
 | 241 |   int aa, mm, jj;
 | 
|---|
 | 242 |   int hh, min;
 | 
|---|
 | 243 |   double sec;
 | 
|---|
 | 244 |   GetDate(aa, mm, jj);
 | 
|---|
 | 245 |   GetHour(hh, min, sec);
 | 
|---|
| [2830] | 246 |   if (fmt == FmtPackedDateTime) 
 | 
|---|
 | 247 |     sprintf(buff,"%04d-%02d-%02dT%02d:%02d:%02.1f", aa,mm,jj, hh,min,sec);
 | 
|---|
 | 248 |   else {
 | 
|---|
 | 249 |     if (fmt == FmtDateOnly) 
 | 
|---|
 | 250 |       sprintf(buff,"%02d/%02d/%04d ", jj,mm,aa);
 | 
|---|
 | 251 |     else if (fmt == FmtTimeOnly) 
 | 
|---|
 | 252 |       sprintf(buff,"%02d:%02d:%02.3f ", hh,min,sec);
 | 
|---|
 | 253 |     else 
 | 
|---|
 | 254 |       sprintf(buff,"%02d/%02d/%04d %02d:%02d:%02.1f UT", jj,mm,aa,hh,min,sec);
 | 
|---|
 | 255 |   }
 | 
|---|
| [2654] | 256 |   return buff;
 | 
|---|
 | 257 | }
 | 
|---|
 | 258 | 
 | 
|---|
| [2826] | 259 | /*!
 | 
|---|
| [2830] | 260 | \param fmt : String format for the date 
 | 
|---|
 | 261 |   - FmtPackedDateTime : YYYY-MM-DDThh:mm:ss.s
 | 
|---|
 | 262 |   - FmtDateOnly : dd/mm/yyyy
 | 
|---|
 | 263 |   - FmtTimeOnly : hh:mm:ss.s
 | 
|---|
 | 264 |   - FmtDateTime : dd/mm/yyyy hh:mm:ss.s UT
 | 
|---|
| [2826] | 265 | */
 | 
|---|
| [2830] | 266 | void TimeStamp::Print(ostream& os, StrFmt fmt)  const
 | 
|---|
| [2654] | 267 | {
 | 
|---|
| [2830] | 268 |   os << " " << ToString(fmt) << " "; 
 | 
|---|
| [2654] | 269 | }
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 | int TimeStamp::MonthDays(int annee, int mois) 
 | 
|---|
 | 272 | {
 | 
|---|
 | 273 |   if (mois<1 || mois>12) throw ParmError("TimeStamp::MonthDays month out of range");
 | 
|---|
 | 274 |   
 | 
|---|
 | 275 |   switch(mois) {
 | 
|---|
 | 276 |     case mois_Janvier: 
 | 
|---|
 | 277 |     case mois_Mars:
 | 
|---|
 | 278 |     case mois_Mai:
 | 
|---|
 | 279 |     case mois_Juillet:
 | 
|---|
 | 280 |     case mois_Aout:
 | 
|---|
 | 281 |     case mois_Octobre:
 | 
|---|
 | 282 |     case mois_Decembre:
 | 
|---|
 | 283 |       return 31;
 | 
|---|
 | 284 |     case mois_Avril:
 | 
|---|
 | 285 |     case mois_Juin:
 | 
|---|
 | 286 |     case mois_Septembre:
 | 
|---|
 | 287 |     case mois_Novembre:
 | 
|---|
 | 288 |       return 30;
 | 
|---|
 | 289 |     case mois_Fevrier:
 | 
|---|
 | 290 |      return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 29 : 28;
 | 
|---|
 | 291 |   }
 | 
|---|
 | 292 |   return -1;
 | 
|---|
 | 293 | }
 | 
|---|
 | 294 | 
 | 
|---|
 | 295 | int TimeStamp::YearDays(int annee)
 | 
|---|
 | 296 | //      Retourne le nombre de jours dans l'année
 | 
|---|
 | 297 | {
 | 
|---|
 | 298 |   return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 366 : 365;
 | 
|---|
 | 299 | }
 | 
|---|
 | 300 | 
 | 
|---|
 | 301 | int_8 TimeStamp::ConvertToDays(int AA, int MM, int JJ)
 | 
|---|
 | 302 | {
 | 
|---|
 | 303 |   int_8 t = 0;
 | 
|---|
 | 304 |   //   if (!UndetDate()) {
 | 
|---|
 | 305 |   int nban = AA-1901;
 | 
|---|
 | 306 |   if (nban >= 0)  
 | 
|---|
 | 307 |     t = nban*365 + (nban/4) - (nban/100) + ((nban+300)/400);
 | 
|---|
 | 308 |   else 
 | 
|---|
 | 309 |     t = nban*365 + (nban/4) - (nban/100) + ((nban-100)/400);
 | 
|---|
 | 310 |   for (int i=1; i<MM; i++)  t += TimeStamp::MonthDays(AA, i);
 | 
|---|
 | 311 |   t += JJ;
 | 
|---|
 | 312 |   // }
 | 
|---|
 | 313 |   return t;
 | 
|---|
 | 314 | }
 | 
|---|
| [2830] | 315 | 
 | 
|---|
 | 316 | //----------------------------------------------------------
 | 
|---|
 | 317 | // Classe pour la gestion de persistance
 | 
|---|
 | 318 | // ObjFileIO<TimeStamp>
 | 
|---|
 | 319 | //----------------------------------------------------------
 | 
|---|
 | 320 | 
 | 
|---|
 | 321 | /* --Methode-- */
 | 
|---|
 | 322 | DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
 | 
|---|
 | 323 | void        ObjFileIO<TimeStamp>::WriteSelf(POutPersist& s) const
 | 
|---|
 | 324 | {
 | 
|---|
 | 325 |   if (dobj == NULL)
 | 
|---|
 | 326 |     throw NullPtrError("ObjFileIO<TimeStamp>::WriteSelf() dobj=NULL");
 | 
|---|
 | 327 |   int_4 ver;
 | 
|---|
 | 328 |   ver = 1;
 | 
|---|
 | 329 |   s.Put(ver);   // Lecture numero de version PPF
 | 
|---|
 | 330 |   s.Put(dobj->DaysPart());
 | 
|---|
 | 331 |   s.Put(dobj->SecondsPart());
 | 
|---|
 | 332 | }
 | 
|---|
 | 333 | 
 | 
|---|
 | 334 | /* --Methode-- */
 | 
|---|
 | 335 | DECL_TEMP_SPEC  /* equivalent a template <> , pour SGI-CC en particulier */
 | 
|---|
 | 336 | void        ObjFileIO<TimeStamp>::ReadSelf(PInPersist& s)
 | 
|---|
 | 337 | {
 | 
|---|
 | 338 |   int_4 ver;
 | 
|---|
 | 339 |   s.Get(ver);   // Lecture numero de version PPF
 | 
|---|
 | 340 |   r_8 seconds;
 | 
|---|
 | 341 |   int_8 days;
 | 
|---|
 | 342 |   s.Get(days);
 | 
|---|
 | 343 |   s.Get(seconds);
 | 
|---|
 | 344 | 
 | 
|---|
 | 345 |   if (dobj == NULL) dobj = new TimeStamp(days, seconds);
 | 
|---|
 | 346 |   else dobj->Set(days, seconds);
 | 
|---|
 | 347 | }
 | 
|---|
 | 348 | 
 | 
|---|
 | 349 | 
 | 
|---|
 | 350 | #ifdef __CXX_PRAGMA_TEMPLATES__
 | 
|---|
 | 351 | #pragma define_template ObjFileIO<TimeStamp>
 | 
|---|
 | 352 | #endif
 | 
|---|
 | 353 | 
 | 
|---|
 | 354 | #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
 | 
|---|
| [3232] | 355 | template class ObjFileIO<TimeStamp>;
 | 
|---|
| [2830] | 356 | #endif
 | 
|---|
| [3232] | 357 | 
 | 
|---|
 | 358 | } // FIN namespace SOPHYA 
 | 
|---|