SNAP Library 2.2, Developer Reference  2014-03-11 19:15:55
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
tm.cpp
Go to the documentation of this file.
00001 
00002 // Time-Names
00003 bool TTmInfo::InitP=false;
00004 TStrV TTmInfo::UsMonthNmV;
00005 TStrV TTmInfo::SiMonthNmV;
00006 TStrV TTmInfo::UsDayOfWeekNmV;
00007 TStrV TTmInfo::SiDayOfWeekNmV;
00008 
00009 void TTmInfo::InitMonthNmV(){
00010   // english
00011   UsMonthNmV.Add("jan"); UsMonthNmV.Add("feb"); UsMonthNmV.Add("mar");
00012   UsMonthNmV.Add("apr"); UsMonthNmV.Add("may"); UsMonthNmV.Add("jun");
00013   UsMonthNmV.Add("jul"); UsMonthNmV.Add("aug"); UsMonthNmV.Add("sep");
00014   UsMonthNmV.Add("oct"); UsMonthNmV.Add("nov"); UsMonthNmV.Add("dec");
00015   IAssert(UsMonthNmV.Len()==12);
00016   // slovene
00017   SiMonthNmV.Add("jan"); SiMonthNmV.Add("feb"); SiMonthNmV.Add("mar");
00018   SiMonthNmV.Add("apr"); SiMonthNmV.Add("maj"); SiMonthNmV.Add("jun");
00019   SiMonthNmV.Add("jul"); SiMonthNmV.Add("avg"); SiMonthNmV.Add("sep");
00020   SiMonthNmV.Add("okt"); SiMonthNmV.Add("nov"); SiMonthNmV.Add("dec");
00021   IAssert(SiMonthNmV.Len()==12);
00022 }
00023 
00024 void TTmInfo::InitDayOfWeekNmV(){
00025   // english
00026   UsDayOfWeekNmV.Add("sun"); UsDayOfWeekNmV.Add("mon");
00027   UsDayOfWeekNmV.Add("tue"); UsDayOfWeekNmV.Add("wed");
00028   UsDayOfWeekNmV.Add("thu"); UsDayOfWeekNmV.Add("fri");
00029   UsDayOfWeekNmV.Add("sat");
00030   IAssert(UsDayOfWeekNmV.Len()==7);
00031   // slovene
00032   SiDayOfWeekNmV.Add("ned"); SiDayOfWeekNmV.Add("pon");
00033   SiDayOfWeekNmV.Add("tor"); SiDayOfWeekNmV.Add("sre");
00034   SiDayOfWeekNmV.Add("cet"); SiDayOfWeekNmV.Add("pet");
00035   SiDayOfWeekNmV.Add("sob");
00036   IAssert(SiDayOfWeekNmV.Len()==7);
00037 }
00038 
00039 int TTmInfo::GetMonthN(const TStr& MonthNm, const TLoc& Loc){
00040   EnsureInit();
00041   int MonthN=-1;
00042   switch (Loc){
00043     case lUs: MonthN=UsMonthNmV.SearchForw(MonthNm.GetLc()); break;
00044     case lSi: MonthN=SiMonthNmV.SearchForw(MonthNm.GetLc()); break;
00045     default: Fail;
00046   }
00047   if (MonthN==-1){return -1;} else {return MonthN+1;}
00048 }
00049 
00050 TStr TTmInfo::GetMonthNm(const int& MonthN, const TLoc& Loc){
00051   EnsureInit();
00052   IAssert((1<=MonthN)&&(MonthN<=12));
00053   switch (Loc){
00054     case lUs: return UsMonthNmV[MonthN-1];
00055     case lSi: return SiMonthNmV[MonthN-1];
00056     default: Fail; return TStr();
00057   }
00058 }
00059 
00060 int TTmInfo::GetDayOfWeekN(const TStr& DayOfWeekNm, const TLoc& Loc){
00061   EnsureInit();
00062   int DayOfWeekN=-1;
00063   switch (Loc){
00064     case lUs: DayOfWeekN=UsDayOfWeekNmV.SearchForw(DayOfWeekNm.GetLc()); break;
00065     case lSi: DayOfWeekN=SiDayOfWeekNmV.SearchForw(DayOfWeekNm.GetLc()); break;
00066     default: Fail;
00067   }
00068   if (DayOfWeekN==-1){return -1;} else {return DayOfWeekN+1;}
00069 }
00070 
00071 TStr TTmInfo::GetDayOfWeekNm(const int& DayOfWeekN, const TLoc& Loc){
00072   EnsureInit();
00073   IAssert((1<=DayOfWeekN)&&(DayOfWeekN<=7));
00074   switch (Loc){
00075     case lUs: return UsDayOfWeekNmV[DayOfWeekN-1];
00076     case lSi: return SiDayOfWeekNmV[DayOfWeekN-1];
00077     default: Fail; return TStr();
00078   }
00079 }
00080 
00081 TStr TTmInfo::GetHmFromMins(const int& Mins){
00082   return TInt::GetStr(Mins/60, "%02d")+":"+TInt::GetStr(Mins%60, "%02d");
00083 }
00084 
00085 int TTmInfo::GetTmUnitSecs(const TTmUnit& TmUnit) {
00086   switch(TmUnit) {
00087     case tmuYear : return 365*24*3600;
00088     case tmuMonth : return 31*24*3600;
00089     case tmuWeek : return 7*24*3600;
00090     case tmuDay : return 24*3600;
00091     case tmu12Hour : return 12*3600;
00092     case tmu6Hour : return 6*3600;
00093     case tmu4Hour : return 4*3600;
00094     case tmu2Hour : return 2*3600;
00095     case tmu1Hour : return 1*3600;
00096     case tmu30Min : return 30*60;
00097     case tmu15Min : return 15*60;
00098     case tmu10Min : return 10*60;
00099     case tmu1Min : return 60;
00100     case tmu1Sec : return 1;
00101     case tmuNodes : Fail;
00102     case tmuEdges : Fail;
00103     default: Fail;
00104   }
00105   return -1;
00106 }
00107 
00108 TStr TTmInfo::GetTmUnitStr(const TTmUnit& TmUnit) {
00109   switch(TmUnit) {
00110     case tmuYear : return "Year";
00111     case tmuMonth : return "Month";
00112     case tmuWeek : return "Week";
00113     case tmuDay : return "Day";
00114     case tmu12Hour : return "12 Hours";
00115     case tmu6Hour : return "6 Hours";
00116     case tmu4Hour : return "4 Hours";
00117     case tmu2Hour : return "2 Hours";
00118     case tmu1Hour : return "1 Hour";
00119     case tmu30Min : return "30 Minutes";
00120     case tmu15Min : return "15 Minutes";
00121     case tmu10Min : return "10 Minutes";
00122     case tmu1Min : return "Minute";
00123     case tmu1Sec : return "Second";
00124     case tmuNodes : return "Nodes";
00125     case tmuEdges : return "Edges";
00126     default: Fail;
00127   }
00128   return TStr::GetNullStr();
00129 }
00130 
00131 TStr TTmInfo::GetTmZoneDiffStr(const TStr& TmZoneStr){
00132   if (TmZoneStr=="A"){/* Alpha Time Zone Military*/ return "+1000";}
00133   if (TmZoneStr=="ACDT"){/* Australian Central Daylight Time    Australia */ return "+1030";}
00134   if (TmZoneStr=="ACST"){/* Australian Central Standard Time    Australia */ return "+0930";}
00135   if (TmZoneStr=="ADT"){/* Atlantic Daylight Time       North America */ return "-0300";}
00136   if (TmZoneStr=="AEDT"){/* Australian Eastern Daylight Time or Australian Eastern Summer Time  Australia */ return "+1100";}
00137   if (TmZoneStr=="AEST"){/* Australian Eastern Standard Time    Australia */ return "+1000";}
00138   if (TmZoneStr=="AKDT"){/* Alaska Daylight Time        North America */ return "-0800";}
00139   if (TmZoneStr=="AKST"){/* Alaska Standard Time        North America */ return "-0900";}
00140   if (TmZoneStr=="AST"){/* Atlantic Standard Time       North America */ return "-0400";}
00141   if (TmZoneStr=="AWDT"){/* Australian Western Daylight Time    Australia */ return "+0900";}
00142   if (TmZoneStr=="AWST"){/* Australian Western Standard Time    Australia */ return "+0800";}
00143   if (TmZoneStr=="B"){/* Bravo Time Zone        Military */ return "+0200";}
00144   if (TmZoneStr=="BST"){/* British Summer Time  Europe */ return "+0100";}
00145   if (TmZoneStr=="C"){/* Charlie Time Zone      Military */ return "+0300";}
00146   if (TmZoneStr=="CDT"){/* Central Daylight Time        North America */ return "-0500";}
00147   if (TmZoneStr=="CDT"){/* Central Daylight Time        Australia */ return "+1030";}
00148   if (TmZoneStr=="CEDT"){/* Central European Daylight Time      Europe */ return "+0200";}
00149   if (TmZoneStr=="CEST"){/* Central European Summer Time        Europe */ return "+0200";}
00150   if (TmZoneStr=="CET"){/* Central European Time        Europe */ return "+0100";}
00151   if (TmZoneStr=="CST"){/* Central Standard Time        North America */ return "-0600";}
00152   if (TmZoneStr=="CST"){/* Central Summer Time  Australia */ return "+1030";}
00153   if (TmZoneStr=="CST"){/* Central Standard Time        Australia */ return "+0930";}
00154   if (TmZoneStr=="CXT"){/* Christmas Island Time        Australia */ return "+0700";}
00155   if (TmZoneStr=="D"){/* Delta Time Zone        Military */ return "+0400";}
00156   if (TmZoneStr=="E"){/* Echo Time Zone Military */ return "+0500";}
00157   if (TmZoneStr=="EDT"){/* Eastern Daylight Time        North America */ return "-0400";}
00158   if (TmZoneStr=="EDT"){/* Eastern Daylight Time        Australia */ return "+1100";}
00159   if (TmZoneStr=="EEDT"){/* Eastern European Daylight Time      Europe */ return "+0300";}
00160   if (TmZoneStr=="EEST"){/* Eastern European Summer Time        Europe */ return "+0300";}
00161   if (TmZoneStr=="EET"){/* Eastern European Time        Europe */ return "+0200";}
00162   if (TmZoneStr=="EST"){/* Eastern Standard Time        North America */ return "-0500";}
00163   if (TmZoneStr=="EST"){/* Eastern Summer Time  Australia */ return "+1100";}
00164   if (TmZoneStr=="EST"){/* Eastern Standard Time        Australia */ return "+1000";}
00165   if (TmZoneStr=="F"){/* Foxtrot Time Zone      Military */ return "+0600";}
00166   if (TmZoneStr=="G"){/* Golf Time Zone Military */ return "+0700";}
00167   if (TmZoneStr=="GMT"){/* Greenwich Mean Time  Europe */ return "+0000";}
00168   if (TmZoneStr=="H"){/* Hotel Time Zone        Military */ return "+0800";}
00169   if (TmZoneStr=="HAA"){/* Heure Avancee de l'Atlantique        North America */ return "-0300";}
00170   if (TmZoneStr=="HAC"){/* Heure Avancee du Centre      North America */ return "-0500";}
00171   if (TmZoneStr=="HADT"){/* Hawaii-Aleutian Daylight Time       North America */ return "-0900";}
00172   if (TmZoneStr=="HAE"){/* Heure Avancee de l'Est       North America */ return "-0400";}
00173   if (TmZoneStr=="HAP"){/* Heure Avancee du Pacifique   North America */ return "-0700";}
00174   if (TmZoneStr=="HAR"){/* Heure Avancee des Rocheuses  North America */ return "-0600";}
00175   if (TmZoneStr=="HAST"){/* Hawaii-Aleutian Standard Time       North America */ return "-1000";}
00176   if (TmZoneStr=="HAT"){/* Heure Avancee de Terre-Neuve North America */ return "-0230";}
00177   if (TmZoneStr=="HAY"){/* Heure Avancee du Yukon       North America */ return "-0800";}
00178   if (TmZoneStr=="HNA"){/* Heure Normale de l'Atlantique        North America */ return "-0400";}
00179   if (TmZoneStr=="HNC"){/* Heure Normale du Centre      North America */ return "-0600";}
00180   if (TmZoneStr=="HNE"){/* Heure Normale de l'Est       North America */ return "-0500";}
00181   if (TmZoneStr=="HNP"){/* Heure Normale du Pacifique   North America */ return "-0800";}
00182   if (TmZoneStr=="HNR"){/* Heure Normale des Rocheuses  North America */ return "-0700";}
00183   if (TmZoneStr=="HNT"){/* Heure Normale de Terre-Neuve North America */ return "-0330";}
00184   if (TmZoneStr=="HNY"){/* Heure Normale du Yukon       North America */ return "-0900";}
00185   if (TmZoneStr=="I"){/* India Time Zone        Military */ return "+0900";}
00186   if (TmZoneStr=="IST"){/* Irish Summer Time    Europe */ return "+0100";}
00187   if (TmZoneStr=="K"){/* Kilo Time Zone Military */ return "+1000";}
00188   if (TmZoneStr=="L"){/* Lima Time Zone Military */ return "+1100";}
00189   if (TmZoneStr=="M"){/* Mike Time Zone Military */ return "+1200";}
00190   if (TmZoneStr=="MDT"){/* Mountain Daylight Time       North America */ return "-0600";}
00191   if (TmZoneStr=="MESZ"){/* Mitteleuropeische Sommerzeit        Europe */ return "+0200";}
00192   if (TmZoneStr=="MEZ"){/* Mitteleuropeische Zeit       Europe */ return "+0100";}
00193   if (TmZoneStr=="MSD"){/* Moscow Daylight Time Europe */ return "+0400";}
00194   if (TmZoneStr=="MSK"){/* Moscow Standard Time Europe */ return "+0300";}
00195   if (TmZoneStr=="MST"){/* Mountain Standard Time       North America */ return "-0700";}
00196   if (TmZoneStr=="N"){/* November Time Zone     Military */ return "-0100";}
00197   if (TmZoneStr=="NDT"){/* Newfoundland Daylight Time   North America */ return "-0230";}
00198   if (TmZoneStr=="NFT"){/* Norfolk (Island) Time        Australia */ return "+ 11:30";}
00199   if (TmZoneStr=="NST"){/* Newfoundland Standard Time   North America */ return "-0330";}
00200   if (TmZoneStr=="O"){/* Oscar Time Zone        Military */ return "-0200";}
00201   if (TmZoneStr=="P"){/* Papa Time Zone Military */ return "-0300";}
00202   if (TmZoneStr=="PDT"){/* Pacific Daylight Time        North America */ return "-0700";}
00203   if (TmZoneStr=="PST"){/* Pacific Standard Time        North America */ return "-0800";}
00204   if (TmZoneStr=="Q"){/* Quebec Time Zone       Military */ return "-0400";}
00205   if (TmZoneStr=="R"){/* Romeo Time Zone        Military */ return "-0500";}
00206   if (TmZoneStr=="S"){/* Sierra Time Zone       Military */ return "-0600";}
00207   if (TmZoneStr=="T"){/* Tango Time Zone        Military */ return "-0700";}
00208   if (TmZoneStr=="U"){/* Uniform Time Zone      Military */ return "-0800";}
00209   if (TmZoneStr=="UTC"){/* Coordinated Universal Time Europe */ return "+0000";}
00210   if (TmZoneStr=="V"){/* Victor Time Zone       Military */ return "-0900";}
00211   if (TmZoneStr=="W"){/* Whiskey Time Zone      Military */ return "-1000";}
00212   if (TmZoneStr=="WDT"){/* Western Daylight Time        Australia */ return "+0900";}
00213   if (TmZoneStr=="WEDT"){/* Western European Daylight Time      Europe */ return "+0100";}
00214   if (TmZoneStr=="WEST"){/* Western European Summer Time        Europe */ return "+0100";}
00215   if (TmZoneStr=="WET"){/* Western European Time        Europe */ return "+0000";}
00216   if (TmZoneStr=="WST"){/* Western Summer Time  Australia */ return "+0900";}
00217   if (TmZoneStr=="WST"){/* Western Standard Time        Australia */ return "+0800";}
00218   if (TmZoneStr=="X"){/* X-ray Time Zone        Military */ return "-1100";}
00219   if (TmZoneStr=="Y"){/* Yankee Time Zone       Military */ return "-1200";}
00220   if (TmZoneStr=="Z"){/* Zulu Time Zone Military */ return "+0000";}
00221   return "-0000";
00222 }
00223 
00224 // day-of-week numbers
00225 const int TTmInfo::SunN=1; const int TTmInfo::MonN=2;
00226 const int TTmInfo::TueN=3; const int TTmInfo::WedN=4;
00227 const int TTmInfo::ThuN=5; const int TTmInfo::FriN=6;
00228 const int TTmInfo::SatN=7;
00229 
00230 // month numbers
00231 const int TTmInfo::JanN=1; const int TTmInfo::FebN=2;
00232 const int TTmInfo::MarN=3; const int TTmInfo::AprN=4;
00233 const int TTmInfo::MayN=5; const int TTmInfo::JunN=6;
00234 const int TTmInfo::JulN=7; const int TTmInfo::AugN=8;
00235 const int TTmInfo::SepN=9; const int TTmInfo::OctN=10;
00236 const int TTmInfo::NovN=11; const int TTmInfo::DecN=12;
00237 
00239 // Julian-Dates
00240 
00241 /* public domain Julian Day Number functions
00242 **
00243 ** Based on formulae originally posted by
00244 **    Tom Van Flandern / Washington, DC / metares@well.sf.ca.us
00245 **       in the UseNet newsgroup sci.astro.
00246 **    Reposted 14 May 1991 in FidoNet C Echo conference by
00247 **       Paul Schlyter (Stockholm)
00248 ** Minor corrections, added JDN to julian, and recast into C by
00249 **    Raymond Gardner  Englewood, Colorado
00250 **
00251 ** Synopsis:
00252 **      long ymd_to_jdn(int year, int month, int day, int julian_flag)
00253 **      void jdn_to_ymd(long jdn, int *year, int *month, int *day,
00254 **                                                      int julian_flag)
00255 **      year is negative if BC
00256 **      if julian_flag is >  0, use Julian calendar
00257 **      if julian_flag is == 0, use Gregorian calendar
00258 **      if julian_flag is <  0, routines decide based on date
00259 **
00260 ** These routines convert Gregorian and Julian calendar dates to and
00261 ** from Julian Day Numbers.  Julian Day Numbers (JDN) are used by
00262 ** astronomers as a date/time measure independent of calendars and
00263 ** convenient for computing the elapsed time between dates.  The JDN
00264 ** for any date/time is the number of days (including fractional
00265 ** days) elapsed since noon, 1 Jan 4713 BC.  Julian Day Numbers were
00266 ** originated by Joseph Scaliger in 1582 and named after his father
00267 ** Julius, not after Julius Caesar.  They are not related to the
00268 ** Julian calendar.
00269 **
00270 ** For dates from 1 Jan 4713 BC thru 12 Dec Feb 32766 AD, ymd_to_jdn()
00271 ** will give the JDN for noon on that date.  jdn_to_ymd() will compute
00272 ** the year, month, and day from the JDN.  Years BC are given (and
00273 ** returned) as negative numbers.  Note that there is no year 0 BC;
00274 ** the day before 1 Jan 1 AD is 31 Dec 1 BC.  Note also that 1 BC,
00275 ** 5 BC, etc. are leap years.
00276 **
00277 ** Pope Gregory XIII decreed that the Julian calendar would end on
00278 ** 4 Oct 1582 AD and that the next day would be 15 Oct 1582 in the
00279 ** Gregorian Calendar.  The only other change is that centesimal
00280 ** years (years ending in 00) would no longer be leap years
00281 ** unless divisible by 400.  Britain and its possessions and
00282 ** colonies continued to use the Julian calendar up until 2 Sep
00283 ** 1752, when the next day became 14 Sep 1752 in the Gregorian
00284 ** Calendar.  These routines can be compiled to use either
00285 ** convention.  By default, the British convention will be used.
00286 ** Simply #define PAPAL to use Pope Gregory's convention.
00287 **
00288 ** Each routine takes, as its last argument, a flag to indicate
00289 ** whether to use the Julian or Gregorian calendar convention.  If
00290 ** this flag is negative, the routines decide based on the date
00291 ** itself, using the changeover date described in the preceding
00292 ** paragraph.  If the flag is zero, Gregorian conventions will be used,
00293 ** and if the flag is positive, Julian conventions will be used.
00294 */
00295 
00296 // Pope Gregory XIII's decree
00297 int TJulianDate::LastJulianDate=15821004; /* last day to use Julian calendar */
00298 int TJulianDate::LastJulianDateN=2299160; /* jdn of same */
00299 // British-American usage
00300 //int TJulianDate::LastJulianDate=17520902; /* last day to use Julian calendar */
00301 //int TJulianDate::LastJulianDateN=2361221; /* jdn of same */
00302 
00303 int TJulianDate::GetJulianDateN(int d, int m, int y){
00304   IAssert(y != 0);
00305   int julian = -1;
00306   long jdn;
00307 
00308   if (julian < 0){ /* set Julian flag if auto set */
00309     julian = (((y * 100L) + m) * 100 + d  <=  LastJulianDate);}
00310 
00311   if (y < 0){ /* adjust BC year */
00312     y++;}
00313 
00314   if (julian){
00315     jdn = 367L * y - 7 * (y + 5001L + (m - 9) / 7) / 4
00316      + 275 * m / 9 + d + 1729777L;
00317   } else {
00318     jdn = (long)(d - 32076)
00319      + 1461L * (y + 4800L + (m - 14) / 12) / 4
00320      + 367 * (m - 2 - (m - 14) / 12 * 12) / 12
00321      - 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4
00322      + 1;            /* correction by rdg */
00323   }
00324   return (int) jdn;
00325 }
00326 
00327 void TJulianDate::GetCalendarDate(int jdn, int& dd, int& mm, int& yy){
00328   int julian = -1;
00329 
00330   long x, z, m, d, y;
00331   long daysPer400Years = 146097L;
00332   long fudgedDaysPer4000Years = 1460970L + 31;
00333 
00334   if (julian < 0){ /* set Julian flag if auto set */
00335     julian = (jdn <= LastJulianDateN);}
00336 
00337   x = jdn + 68569L;
00338   if (julian){
00339     x+=38;
00340     daysPer400Years = 146100L;
00341     fudgedDaysPer4000Years = 1461000L + 1;
00342   }
00343   z = 4 * x / daysPer400Years;
00344   x = x - (daysPer400Years * z + 3) / 4;
00345   y = 4000 * (x + 1) / fudgedDaysPer4000Years;
00346   x = x - 1461 * y / 4 + 31;
00347   m = 80 * x / 2447;
00348   d = x - 2447 * m / 80;
00349   x = m / 11;
00350   m = m + 2 - 12 * x;
00351   y = 100 * (z - 49) + y + x;
00352 
00353   yy = (int)y;
00354   mm = (int)m;
00355   dd = (int)d;
00356 
00357   if (yy <= 0){ /* adjust BC years */
00358    (yy)--;}
00359 }
00360 
00362 // Seconds-Time
00363 bool TSecTm::GetTmSec(const int& YearN, const int& MonthN, const int& DayN, const int& HourN, const int& MinN, const int& SecN, uint& AbsSec) {
00364   AbsSec = 0;
00365   // tm_isdst:
00366   //  - Positive if daylight saving time is in effect;
00367   //  - 0 if daylight saving time is not in effect;
00368   //  - negative if status of daylight saving time is unknown.
00369   //  The C run-time library assumes the United States's rules for implementing
00370   //  the calculation of Daylight Saving Time (DST).
00371   struct tm Tm;
00372   Tm.tm_year=YearN-1900; Tm.tm_mon=MonthN-1; Tm.tm_mday=DayN;
00373   Tm.tm_hour=HourN; Tm.tm_min=MinN; Tm.tm_sec=SecN;
00374   Tm.tm_wday=1;  Tm.tm_yday=1;
00375   Tm.tm_isdst=-1;
00376   return TSecTm::GetTmSec(Tm, AbsSec);
00377 }
00378 
00379 // implementation of mkgmtime (taken from the web)
00380 time_t TSecTm::MkGmTime(struct tm *t) {
00381   static const int m_to_d[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
00382   short month, year;
00383   time_t result;
00384   month = t->tm_mon;
00385   year = t->tm_year + month / 12 + 1900;
00386   month %= 12;
00387   if (month < 0) {
00388     year -= 1;
00389     month += 12; }
00390   result = (year - 1970) * 365 + (year - 1969) / 4 + m_to_d[month];
00391   result = (year - 1970) * 365 + m_to_d[month];
00392   if (month <= 1) { year -= 1; }
00393   result += (year - 1968) / 4;
00394   result -= (year - 1900) / 100;
00395   result += (year - 1600) / 400;
00396   result += t->tm_mday;
00397   result -= 1;
00398   result *= 24;
00399   result += t->tm_hour;
00400   result *= 60;
00401   result += t->tm_min;
00402   result *= 60;
00403   result += t->tm_sec;
00404   return result;
00405 }
00406 
00407 bool TSecTm::GetTmSec(struct tm& Tm, uint& AbsSec) {
00408   const time_t GmtTime = MkGmTime(&Tm);
00409   EAssertR(uint(GmtTime) < TUInt::Mx,
00410     TStr::Fmt("Time out of range: %d/%d/%d %02d:%02d:%02d",
00411     Tm.tm_year, Tm.tm_mon, Tm.tm_mday, Tm.tm_hour, Tm.tm_min, Tm.tm_sec).CStr());
00412   AbsSec = uint(GmtTime);
00413   return GmtTime >= 0;
00414 }
00415 
00416 bool TSecTm::GetTmStruct(const uint& AbsSec, struct tm& Tm) {
00417   const time_t TimeT = time_t(AbsSec);
00418   #if defined(GLib_MSC)
00419   return _gmtime64_s(&Tm, &TimeT) == 0;
00420   #elif defined(GLib_BCB)
00421   Tm=*gmtime(&TimeT); return true;
00422   #else
00423   return gmtime_r(&TimeT, &Tm) != NULL;
00424   #endif
00425 }
00426 
00427 TSecTm::TSecTm(const int& YearN, const int& MonthN, const int& DayN,
00428  const int& HourN, const int& MinN, const int& SecN) : AbsSecs(TUInt::Mx){
00429   GetTmSec(YearN, MonthN, DayN, HourN, MinN, SecN, AbsSecs.Val);
00430 }
00431 
00432 TSecTm::TSecTm(const TTm& Tm): AbsSecs(
00433  TSecTm(Tm.GetYear(), Tm.GetMonth(), Tm.GetDay(), Tm.GetHour(),
00434    Tm.GetMin(), Tm.GetSec()).GetAbsSecs()) { }
00435 
00436 TSecTm::TSecTm(const PXmlTok& XmlTok) {
00437   const int Year = XmlTok->GetIntArgVal("Year");
00438   const int Month = XmlTok->GetIntArgVal("Month");
00439   const int Day = XmlTok->GetIntArgVal("Day");
00440   const int Hour = XmlTok->GetIntArgVal("Hour");
00441   const int Min = XmlTok->GetIntArgVal("Min");
00442   const int Sec = XmlTok->GetIntArgVal("Sec");
00443   AbsSecs = TSecTm(Year, Month, Day, Hour, Min, Sec).GetAbsSecs();
00444 }
00445 
00446 PXmlTok TSecTm::GetXmlTok() const {
00447   PXmlTok NodeTok = TXmlTok::New("NodeTime");
00448   NodeTok->AddArg("Year", GetYearN());
00449   NodeTok->AddArg("Month", GetMonthN());
00450   NodeTok->AddArg("Day", GetDayN());
00451   NodeTok->AddArg("Hour", GetHourN());
00452   NodeTok->AddArg("Min", GetMinN());
00453   NodeTok->AddArg("Sec", GetSecN());
00454   return NodeTok;
00455 }
00456 
00457 TStr TSecTm::GetStr(const TLoc& Loc) const {
00458   if (IsDef()) {
00459     struct tm Tm;
00460     IAssert(GetTmStruct(AbsSecs(), Tm));
00461     // Wed May 14 15:30:17 2003
00462     return TStr::Fmt("%s %s %d %02d:%02d:%02d %d",
00463       TTmInfo::GetDayOfWeekNm(Tm.tm_wday + 1, Loc).CStr(),
00464       TTmInfo::GetMonthNm(Tm.tm_mon + 1, Loc).CStr(),
00465       Tm.tm_mday, Tm.tm_hour, Tm.tm_min, Tm.tm_sec, Tm.tm_year+1900);
00466   } else {
00467     return "Undef";
00468   }
00469 }
00470 
00471 TStr TSecTm::GetStr(const TTmUnit& TmUnit) const {
00472   if (TmUnit == tmuYear) {
00473     return TInt::GetStr(GetYearN()); }
00474   else if (TmUnit == tmuMonth) {
00475     return TStr::Fmt("%04d-%02d", GetYearN(), GetMonthN()); }
00476   else if (TmUnit == tmuDay) {
00477     return TStr::Fmt("%04d-%02d-%02d", GetYearN(), GetMonthN(), GetDayN()); }
00478   else {
00479     return TStr::Fmt("%04d-%02d-%02d %02d:%02d:%02d",
00480       GetYearN(), GetMonthN(), GetDayN(), GetHourN(), GetMinN(), GetSecN());
00481   }
00482 }
00483 
00484 TStr TSecTm::GetDtStr(const TLoc& Loc) const {
00485   if (IsDef()){
00486     struct tm Tm;
00487     IAssert(GetTmStruct(AbsSecs(), Tm));
00488     return TStr::Fmt("%s %s %d %d",
00489       TTmInfo::GetDayOfWeekNm(Tm.tm_wday + 1, Loc).CStr(),
00490       TTmInfo::GetMonthNm(Tm.tm_mon + 1, Loc).CStr(), Tm.tm_year+1900);
00491   } else {
00492     return "Undef";
00493   }
00494 }
00495 
00496 TStr TSecTm::GetDtMdyStr() const {
00497   struct tm Tm;
00498   IAssert(GetTmStruct(AbsSecs(), Tm));
00499   return TStr::Fmt("%02d/%02d%/%04d", Tm.tm_mon+1, Tm.tm_mday, Tm.tm_year+1900);
00500 }
00501 
00502 TStr TSecTm::GetDtYmdStr() const {
00503   struct tm Tm;
00504   IAssert(GetTmStruct(AbsSecs(), Tm));
00505   return TStr::Fmt("%04d-%02d-%02d", Tm.tm_year+1900, Tm.tm_mon+1, Tm.tm_mday);
00506 }
00507 
00508 TStr TSecTm::GetYmdTmStr() const {
00509   struct tm Tm;
00510   IAssert(GetTmStruct(AbsSecs(), Tm));
00511   return TStr::Fmt("%04d-%02d-%02d %02d:%02d:%02d", Tm.tm_year+1900, Tm.tm_mon+1, Tm.tm_mday, Tm.tm_hour, Tm.tm_min, Tm.tm_sec);
00512 }
00513 
00514 
00515 TStr TSecTm::GetTmStr() const {
00516   if (IsDef()){
00517     struct tm Tm;
00518     IAssert(GetTmStruct(AbsSecs(), Tm));
00519     return TStr::Fmt("%02d:%02d:%02d", Tm.tm_hour, Tm.tm_min, Tm.tm_sec);
00520   } else {
00521     return "Undef";
00522   }
00523 }
00524 
00525 TStr TSecTm::GetTmMinStr() const {
00526   if (IsDef()){
00527     struct tm Tm;
00528     IAssert(GetTmStruct(AbsSecs(), Tm));
00529     return TStr::Fmt("%02d:%02d", Tm.tm_min, Tm.tm_sec);
00530   } else {
00531     return "Undef";
00532   }
00533 }
00534 
00535 TStr TSecTm::GetDtTmSortStr() const {
00536   return
00537     TInt::GetStr(GetYearN(), "%04d")+"/"+
00538     TInt::GetStr(GetMonthN(), "%02d")+"/"+
00539     TInt::GetStr(GetDayN(), "%02d")+" "+
00540     TInt::GetStr(GetHourN(), "%02d")+":"+
00541     TInt::GetStr(GetMinN(), "%02d")+":"+
00542     TInt::GetStr(GetSecN(), "%02d");
00543 }
00544 
00545 TStr TSecTm::GetDtTmSortFNmStr() const {
00546   return
00547     TInt::GetStr(GetYearN(), "%04d")+"-"+
00548     TInt::GetStr(GetMonthN(), "%02d")+"-"+
00549     TInt::GetStr(GetDayN(), "%02d")+"_"+
00550     TInt::GetStr(GetHourN(), "%02d")+"-"+
00551     TInt::GetStr(GetMinN(), "%02d")+"-"+
00552     TInt::GetStr(GetSecN(), "%02d");
00553 }
00554 
00555 int TSecTm::GetYearN() const {
00556   struct tm Tm;
00557   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00558   return Tm.tm_year+1900;
00559 }
00560 
00561 int TSecTm::GetMonthN() const {
00562   struct tm Tm;
00563   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00564   return Tm.tm_mon+1;
00565 }
00566 
00567 TStr TSecTm::GetMonthNm(const TLoc& Loc) const {
00568   struct tm Tm;
00569   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00570   return TTmInfo::GetMonthNm(Tm.tm_mon+1, Loc);
00571 }
00572 
00573 int TSecTm::GetDayN() const {
00574   struct tm Tm;
00575   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00576   return Tm.tm_mday;
00577 }
00578 
00579 int TSecTm::GetDayOfWeekN() const {
00580   struct tm Tm;
00581   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00582   return Tm.tm_wday + 1;
00583 }
00584 
00585 TStr TSecTm::GetDayOfWeekNm(const TLoc& Loc) const {
00586   struct tm Tm;
00587   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00588   return TTmInfo::GetDayOfWeekNm(Tm.tm_wday+1, Loc);
00589 }
00590 
00591 int TSecTm::GetHourN() const {
00592   struct tm Tm;
00593   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00594   return Tm.tm_hour;
00595 }
00596 
00597 int TSecTm::GetMinN() const {
00598   struct tm Tm;
00599   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00600   return Tm.tm_min;
00601 }
00602 
00603 int TSecTm::GetSecN() const {
00604   struct tm Tm;
00605   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00606   return Tm.tm_sec;
00607 }
00608 
00609 void TSecTm::GetComps(int& Year, int& Month, int& Day, int& Hour, int& Min, int& Sec) const {
00610   struct tm Tm;
00611   EAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00612   Year = Tm.tm_year+1900;
00613   Month = Tm.tm_mon+1;
00614   Day = Tm.tm_mday;
00615   Hour = Tm.tm_hour;
00616   Min = Tm.tm_min;
00617   Sec = Tm.tm_sec;
00618 }
00619 
00620 TSecTm TSecTm::Round(const TTmUnit& TmUnit) const {
00621   if (TmUnit == tmu1Sec) { return *this; }
00622   struct tm Time;
00623   IAssert(IsDef() && GetTmStruct(AbsSecs(), Time));
00624   switch (TmUnit) {
00625     case tmu1Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, Time.tm_min, 0);
00626     case tmu10Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 10*(Time.tm_min/10), 0);
00627     case tmu15Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 15*(Time.tm_min/15), 0);
00628     case tmu30Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 30*(Time.tm_min/30), 0);
00629     case tmu1Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 0, 0);
00630     case tmu2Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 2*(Time.tm_hour/2), 0, 0);
00631     case tmu4Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 4*(Time.tm_hour/4), 0, 0);
00632     case tmu6Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 6*(Time.tm_hour/6), 0, 0);
00633     case tmu12Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 12*(Time.tm_hour/12), 0, 0);
00634     case tmuDay : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 0, 0, 0);
00635     case tmuMonth : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, 1, 0, 0, 0);
00636     case tmuYear : return TSecTm(Time.tm_year+1900, 1, 1, 0, 0, 0);
00637     case tmuWeek : { int dd=1, mm=1, yy=1;
00638       // week starts on Thursday, since 1.1.1970 is Thursday
00639       const int Day = TJulianDate::GetJulianDateN(Time.tm_mday, Time.tm_mon+1, 1900+Time.tm_year);
00640       TJulianDate::GetCalendarDate(3+7*(Day/7), dd, mm, yy);  return TSecTm(yy, mm, dd, 0, 0, 0); }
00641     default : Fail;
00642   }
00643   return TSecTm();
00644 }
00645 uint TSecTm::GetInUnits(const TTmUnit& TmUnit) const {
00646   static const int DayZero = TJulianDate::GetJulianDateN(1, 1, 1970);
00647   if (TmUnit == tmu1Sec) { return AbsSecs; }
00648   struct tm Time;
00649   IAssert(IsDef() && GetTmStruct(AbsSecs(), Time));
00650   switch (TmUnit) {
00651     case tmu1Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, Time.tm_min, 0).GetAbsSecs()/60;
00652     case tmu10Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 10*(Time.tm_min/10), 0).GetAbsSecs()/(10*60);
00653     case tmu15Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 15*(Time.tm_min/15), 0).GetAbsSecs()/(15*60);
00654     case tmu30Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 30*(Time.tm_min/30), 0).GetAbsSecs()/(30*60);
00655     case tmu1Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 0, 0).GetAbsSecs()/3600;
00656     case tmu2Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 2*(Time.tm_hour/2), 0, 0).GetAbsSecs()/(2*3600);
00657     case tmu4Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 4*(Time.tm_hour/4), 0, 0).GetAbsSecs()/(4*3600);
00658     case tmu6Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 6*(Time.tm_hour/6), 0, 0).GetAbsSecs()/(6*3600);
00659     case tmu12Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 12*(Time.tm_hour/12), 0, 0).GetAbsSecs()/(12*3600);
00660     case tmuDay : return TJulianDate::GetJulianDateN(Time.tm_mday, Time.tm_mon+1, 1900+Time.tm_year) - DayZero;
00661     case tmuWeek : return (TJulianDate::GetJulianDateN(Time.tm_mday, Time.tm_mon+1, 1900+Time.tm_year)-DayZero)/7;
00662     case tmuMonth : return 12*(Time.tm_year-70)+Time.tm_mon+1;
00663     case tmuYear : return Time.tm_year+1900;
00664     default : Fail;
00665   }
00666   return TUInt::Mx;
00667 }
00668 
00669 TStr TSecTm::GetDayPart() const {
00670   const int Hour = GetHourN();
00671   if (0 <= Hour && Hour < 6) { return "Night"; }
00672   else if (6 <= Hour && Hour < 12) { return "Morning"; }
00673   else if (12 <= Hour && Hour < 18) { return "Afternoon"; }
00674   else if (18 <= Hour && Hour < 24) { return "Evening"; }
00675   return "";
00676 }
00677 
00678 uint TSecTm::GetDSecs(const TSecTm& SecTm1, const TSecTm& SecTm2){
00679   IAssert(SecTm1.IsDef()&&SecTm2.IsDef());
00680   const time_t Time1= time_t(SecTm1.AbsSecs());
00681   const time_t Time2= time_t(SecTm2.AbsSecs());
00682   return uint(difftime(Time2, Time1));
00683 }
00684 
00685 TSecTm TSecTm::GetZeroWeekTm(){
00686   TSecTm ZeroWeekTm=GetZeroTm();
00687   while (ZeroWeekTm.GetDayOfWeekN()!=TTmInfo::MonN){
00688     ZeroWeekTm.AddDays(1);}
00689   return ZeroWeekTm;
00690 }
00691 
00692 TSecTm TSecTm::GetCurTm(){
00693   const time_t TmSec = time(NULL);
00694   struct tm LocTm;
00695   uint AbsSec = TUInt::Mx;
00696   #if defined(GLib_MSN)
00697   localtime_s(&LocTm, &TmSec);
00698   #elif defined(GLib_BCB)
00699   LocTm = *localtime(&TmSec);
00700   #else
00701   LocTm = *localtime(&TmSec);
00702   #endif
00703   IAssert(TSecTm::GetTmSec(LocTm, AbsSec));
00704   return TSecTm(AbsSec);
00705 }
00706 
00707 TSecTm TSecTm::GetDtTmFromHmsStr(const TStr& HmsStr){
00708   int HmsStrLen=HmsStr.Len();
00709   // hour
00710   TChA ChA; int ChN=0;
00711   while ((ChN<HmsStrLen)&&(HmsStr[ChN]!=':')){ChA+=HmsStr[ChN]; ChN++;}
00712   TStr HourStr=ChA;
00713   // minute
00714   ChA.Clr(); ChN++;
00715   while ((ChN<HmsStrLen)&&(HmsStr[ChN]!=':')){ChA+=HmsStr[ChN]; ChN++;}
00716   TStr MinStr=ChA;
00717   // second
00718   ChA.Clr(); ChN++;
00719   while (ChN<HmsStrLen){ChA+=HmsStr[ChN]; ChN++;}
00720   TStr SecStr=ChA;
00721   // transform to numbers
00722   int HourN=HourStr.GetInt();
00723   int MinN=MinStr.GetInt();
00724   int SecN=SecStr.GetInt();
00725   // construct the time
00726   TSecTm Tm=TSecTm::GetZeroTm();
00727   Tm.AddHours(HourN);
00728   Tm.AddMins(MinN);
00729   Tm.AddSecs(SecN);
00730   return Tm;
00731 }
00732 
00733 TSecTm TSecTm::GetDtTmFromMdyStr(const TStr& MdyStr){
00734   int MdyStrLen=MdyStr.Len();
00735   // month
00736   TChA ChA; int ChN=0;
00737   while ((ChN<MdyStrLen)&&(MdyStr[ChN]!='/')){
00738     ChA+=MdyStr[ChN]; ChN++;}
00739   TStr MonthStr=ChA;
00740   // day
00741   ChA.Clr(); ChN++;
00742   while ((ChN<MdyStrLen)&&(MdyStr[ChN]!='/')){
00743     ChA+=MdyStr[ChN]; ChN++;}
00744   TStr DayStr=ChA;
00745   // year
00746   ChA.Clr(); ChN++;
00747   while (ChN<MdyStrLen){
00748     ChA+=MdyStr[ChN]; ChN++;}
00749   TStr YearStr=ChA;
00750   // transform to numbers
00751   int MonthN=MonthStr.GetInt();
00752   int DayN=DayStr.GetInt();
00753   int YearN=YearStr.GetInt();
00754   if (YearN<1000){
00755     if (YearN<70){YearN+=2000;} else {YearN+=1900;}}
00756   // construct the date
00757   return GetDtTm(YearN, MonthN, DayN);
00758 }
00759 
00760 // parse 28/03/03 and 28-MAY-03 formats
00761 TSecTm TSecTm::GetDtTmFromDmyStr(const TStr& DmyStr){
00762   int DmyStrLen=DmyStr.Len();
00763   // day
00764   TChA ChA; int ChN=0;
00765   while ((ChN<DmyStrLen)&&(DmyStr[ChN]!='/')&&(DmyStr[ChN]!='-')){
00766     ChA+=DmyStr[ChN]; ChN++;}
00767   TStr DayStr=ChA;
00768   // month
00769   ChA.Clr(); ChN++;
00770   while ((ChN<DmyStrLen)&&(DmyStr[ChN]!='/')&&(DmyStr[ChN]!='-')){
00771     ChA+=DmyStr[ChN]; ChN++;}
00772   TStr MonthStr=ChA;
00773   // year
00774   ChA.Clr(); ChN++;
00775   while (ChN<DmyStrLen){
00776     ChA+=DmyStr[ChN]; ChN++;}
00777   TStr YearStr=ChA;
00778   // transform to numbers
00779   int DayN=DayStr.GetInt(-1);
00780   int MonthN=MonthStr.GetInt(-1);
00781   int YearN=YearStr.GetInt(-1);
00782   if (MonthN == -1){
00783     MonthN = TTmInfo::GetMonthN(MonthStr.ToCap()); }
00784   if ((DayN==-1)||(MonthN==-1)||(YearN==-1)){
00785     return TSecTm();
00786   } else {
00787     if (YearN<1000){
00788       if (YearN<70){YearN+=2000;} else {YearN+=1900;}}
00789     // construct the date
00790     return GetDtTm(YearN, MonthN, DayN);
00791   }
00792   return TSecTm();
00793 }
00794 
00795 TSecTm TSecTm::GetDtTmFromMdyHmsPmStr(const TStr& MdyHmsPmStr,
00796  const char& DateSepCh, const char& TimeSepCh){
00797   int MdyHmsPmStrLen=MdyHmsPmStr.Len();
00798   // month
00799   TChA ChA; int ChN=0;
00800   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=DateSepCh)){
00801     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00802   TStr MonthStr=ChA;
00803   // day
00804   ChA.Clr(); ChN++;
00805   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=DateSepCh)){
00806     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00807   TStr DayStr=ChA;
00808   // year
00809   ChA.Clr(); ChN++;
00810   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=' ')){
00811     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00812   TStr YearStr=ChA;
00813   // hour
00814   ChA.Clr(); ChN++;
00815   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=TimeSepCh)){
00816     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00817   TStr HourStr=ChA;
00818   // minute
00819   ChA.Clr(); ChN++;
00820   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=TimeSepCh)){
00821     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00822   TStr MinStr=ChA;
00823   // second
00824   ChA.Clr(); ChN++;
00825   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=' ')){
00826     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00827   TStr SecStr=ChA;
00828   // AM/PM
00829   ChA.Clr(); ChN++;
00830   while (ChN<MdyHmsPmStrLen){
00831     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00832   TStr AmPmStr=ChA;
00833   // transform to numbers
00834   int MonthN=MonthStr.GetInt();
00835   int DayN=DayStr.GetInt();
00836   int YearN=YearStr.GetInt();
00837   int HourN; int MinN; int SecN;
00838   if (HourStr.IsInt()){
00839     HourN=HourStr.GetInt();
00840     MinN=MinStr.GetInt();
00841     SecN=SecStr.GetInt();
00842     if (AmPmStr=="AM"){} else if (AmPmStr=="PM"){HourN+=12;} else {Fail;}
00843   } else {
00844     HourN=0; MinN=0; SecN=0;
00845   }
00846   // construct the time
00847   TSecTm Tm=TSecTm::GetDtTm(YearN, MonthN, DayN);
00848   Tm.AddHours(HourN);
00849   Tm.AddMins(MinN);
00850   Tm.AddSecs(SecN);
00851   return Tm;
00852 }
00853 
00854 TSecTm TSecTm::GetDtTmFromYmdHmsStr(const TStr& YmdHmsPmStr,
00855  const char& DateSepCh, const char& TimeSepCh){
00856   int YmdHmsPmStrLen=YmdHmsPmStr.Len();
00857   // year
00858   TChA ChA; int ChN=0;
00859   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=DateSepCh)){
00860     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00861   TStr YearStr=ChA;
00862   // month
00863   ChA.Clr(); ChN++;
00864   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=DateSepCh)){
00865     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00866   TStr MonthStr=ChA;
00867   // day
00868   ChA.Clr(); ChN++;
00869   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=' ')){
00870     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00871   TStr DayStr=ChA;
00872   // hour
00873   ChA.Clr(); ChN++;
00874   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=TimeSepCh)){
00875     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00876   TStr HourStr=ChA;
00877   // minute
00878   ChA.Clr(); ChN++;
00879   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=TimeSepCh)){
00880     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00881   TStr MinStr=ChA;
00882   // second
00883   ChA.Clr(); ChN++;
00884   while (ChN<YmdHmsPmStrLen){
00885     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00886   TStr SecStr=ChA;
00887   // transform to numbers
00888   int MonthN=MonthStr.GetInt();
00889   int DayN=DayStr.GetInt();
00890   int YearN=YearStr.GetInt();
00891   int HourN; int MinN; int SecN;
00892   if (HourStr.IsInt()){
00893     HourN=HourStr.GetInt();
00894     MinN=MinStr.GetInt();
00895     SecN=SecStr.GetInt();
00896   } else {
00897     HourN=0; MinN=0; SecN=0;
00898   }
00899   // construct the time
00900   TSecTm Tm=TSecTm::GetDtTm(YearN, MonthN, DayN);
00901   Tm.AddHours(HourN);
00902   Tm.AddMins(MinN);
00903   Tm.AddSecs(SecN);
00904   return Tm;
00905 }
00906 
00907 // Parse strings of the form 2006-08-28 14:11:16 or 14:11:16  08/28/2008
00908 // Non-numeric characters act as separators (there can be many consecutive separating characters)
00909 // Variables give indexes of the date fields
00910 TSecTm TSecTm::GetDtTmFromStr(const TChA& YmdHmsPmStr, const int& YearId, const int& MonId,
00911  const int& DayId, const int& HourId, const int& MinId, const int& SecId) {
00912   TChA Tmp = YmdHmsPmStr;
00913   TVec<char *> FldV;
00914   // get the sequences of numbers
00915   for (char *c = (char *) Tmp.CStr(); *c; c++) {
00916     if (TCh::IsNum(*c)) {
00917       FldV.Add(c);
00918       while (TCh::IsNum(*c)) { c++; }
00919       c--;
00920     } else { *c = 0; }
00921   }
00922   const int Y = atoi(FldV[YearId]);
00923   const int M = atoi(FldV[MonId]);
00924   const int D = atoi(FldV[DayId]);
00925   const int H = atoi(FldV[HourId]);
00926   const int m = atoi(FldV[MinId]);
00927   const int S = atoi(FldV[SecId]);
00928   IAssert(Y>0 && M>0 && D>0 && M<13 && D<32);
00929   IAssert(H>=0 && H<24 && m>=0 && m<60 && S>=0 && S<60);
00930   return TSecTm(Y,M,D,H,m,S);
00931 }
00932 
00933 TSecTm TSecTm::GetDtTm(const int& YearN, const int& MonthN, const int& DayN){
00934   uint AbsSecs;
00935   TSecTm::GetTmSec(YearN, MonthN, DayN, 0, 0, 0, AbsSecs);
00936   return TSecTm(AbsSecs);
00937 }
00938 
00939 TSecTm TSecTm::GetDtTm(const TSecTm& Tm){
00940   int DaySecs=Tm.GetHourN()*3600+Tm.GetMinN()*60+Tm.GetSecN();
00941   TSecTm DtTm(Tm.AbsSecs-DaySecs);
00942   return DtTm;
00943 }
00944 
00945 TSecTm TSecTm::LoadTxt(TILx& Lx){
00946   return TSecTm(Lx.GetInt());
00947 }
00948 
00949 void TSecTm::SaveTxt(TOLx& Lx) const {
00950   IAssert(int(AbsSecs) < TInt::Mx);
00951   Lx.PutInt((int)AbsSecs);
00952 }
00953 
00955 // Date-Time
00956 TStr TTm::GetStr(const bool& MSecP) const {
00957   TChA ChA;
00958   ChA+=TInt::GetStr(Year, "%04d"); ChA+='-';
00959 //  ChA+=GetMonthNm(); ChA+='-';
00960   ChA+=TInt::GetStr(Month, "%02d"); ChA+='-';
00961   ChA+=TInt::GetStr(Day, "%02d"); ChA+=' ';
00962 //  ChA+=GetDayOfWeekNm(); ChA+=' ';
00963   ChA+=TInt::GetStr(Hour, "%02d"); ChA+=':';
00964   ChA+=TInt::GetStr(Min, "%02d"); ChA+=':';
00965   ChA+=TInt::GetStr(Sec, "%02d");
00966   if (MSecP){ChA+='.'; ChA+=TInt::GetStr(MSec, "%03d");}
00967   return ChA;
00968 }
00969 
00970 TStr TTm::GetYMDDashStr() const {
00971   TChA ChA;
00972   ChA+=TInt::GetStr(Year, "%04d");
00973   ChA+='-'; ChA+=TInt::GetStr(Month, "%02d");
00974   ChA+='-'; ChA+=TInt::GetStr(Day, "%02d");
00975   return ChA;
00976 }
00977 
00978 TStr TTm::GetHMSTColonDotStr(const bool& FullP, const bool& MSecP) const {
00979   TChA ChA;
00980   ChA+=TInt::GetStr(Hour, "%02d");
00981   ChA+=':'; ChA+=TInt::GetStr(Min, "%02d");
00982   if (FullP||((Sec!=0)||(MSec!=0))){
00983     ChA+=':'; ChA+=TInt::GetStr(Sec, "%02d");
00984     if ((MSecP)&&(FullP||(MSec!=0))){
00985       ChA+='.'; ChA+=TInt::GetStr(MSec, "%d");
00986     }
00987   }
00988   return ChA;
00989 }
00990 
00991 TStr TTm::GetIdStr() const {
00992   TChA ChA;
00993   ChA+=TInt::GetStr(Year%100, "%02d");
00994   ChA+=TInt::GetStr(Month, "%02d");
00995   ChA+=TInt::GetStr(Day, "%02d");
00996   ChA+=TInt::GetStr(Hour, "%02d");
00997   ChA+=TInt::GetStr(Min, "%02d");
00998   ChA+=TInt::GetStr(Sec, "%02d");
00999   ChA+=TInt::GetStr(MSec, "%03d");
01000   return ChA;
01001 }
01002 
01003 
01004 void TTm::AddTime(const int& Hours,
01005  const int& Mins, const int& Secs, const int& MSecs){
01006   uint64 TmMSecs=TTm::GetMSecsFromTm(*this);
01007   TmMSecs+=(uint64(Hours)*uint64(3600)*uint64(1000));
01008   TmMSecs+=(uint64(Mins)*uint64(60)*uint64(1000));
01009   TmMSecs+=(uint64(Secs)*uint64(1000));
01010   TmMSecs+=uint64(MSecs);
01011   *this=GetTmFromMSecs(TmMSecs);
01012 }
01013 
01014 void TTm::SubTime(const int& Hours,
01015  const int& Mins, const int& Secs, const int& MSecs){
01016   uint64 TmMSecs=TTm::GetMSecsFromTm(*this);
01017   TmMSecs-=(uint64(Hours)*uint64(3600)*uint64(1000));
01018   TmMSecs-=(uint64(Mins)*uint64(60)*uint64(1000));
01019   TmMSecs-=(uint64(Secs)*uint64(1000));
01020   TmMSecs-=(uint64(MSecs));
01021   *this=GetTmFromMSecs(TmMSecs);
01022 }
01023 
01024 TTm TTm::GetCurUniTm(){
01025   return TSysTm::GetCurUniTm();
01026 }
01027 
01028 TTm TTm::GetUniqueCurUniTm(){
01029   static TTm LastUniqueTm=TSysTm::GetCurUniTm();
01030   TTm CurUniqueTm=TSysTm::GetCurUniTm();
01031   if (CurUniqueTm<LastUniqueTm){CurUniqueTm=LastUniqueTm;}
01032   if (CurUniqueTm==LastUniqueTm){CurUniqueTm.AddTime(0, 0, 0, 1);}
01033   LastUniqueTm=CurUniqueTm;
01034   return CurUniqueTm;
01035 }
01036 
01037 TTm TTm::GetUniqueCurUniTm(const int& UniqueSpaces, const int& UniqueSpaceN){
01038   static uint64 LastMUniqueTmMSecs=TSysTm::GetCurUniMSecs();
01039   // uniqueness-space-parameters range-check
01040   Assert(UniqueSpaces>=1&&UniqueSpaceN>=0&&UniqueSpaceN<UniqueSpaces);
01041   // get current time
01042   uint64 CurUniqueTmMSecs=TSysTm::GetCurUniMSecs();
01043   if (CurUniqueTmMSecs<LastMUniqueTmMSecs){CurUniqueTmMSecs=LastMUniqueTmMSecs;}
01044   // normalize to uniqueness-space-grid
01045   CurUniqueTmMSecs-=CurUniqueTmMSecs%UniqueSpaces; CurUniqueTmMSecs+=UniqueSpaceN;
01046   // get next free unique-time
01047   if (CurUniqueTmMSecs<=LastMUniqueTmMSecs){
01048     CurUniqueTmMSecs+=UniqueSpaces;
01049   }
01050   // update last-time
01051   LastMUniqueTmMSecs=CurUniqueTmMSecs;
01052   return GetTmFromMSecs(CurUniqueTmMSecs);
01053 }
01054 
01055 TTm TTm::GetCurLocTm(){
01056   return TSysTm::GetCurLocTm();
01057 }
01058 
01059 uint64 TTm::GetCurUniMSecs(){
01060   return TSysTm::GetCurUniMSecs();
01061 }
01062 
01063 uint64 TTm::GetCurLocMSecs(){
01064   return TSysTm::GetCurLocMSecs();
01065 }
01066 
01067 uint64 TTm::GetMSecsFromTm(const TTm& Tm){
01068   return TSysTm::GetMSecsFromTm(Tm);
01069 }
01070 
01071 TTm TTm::GetTmFromMSecs(const uint64& MSecs){
01072   return TSysTm::GetTmFromMSecs(MSecs);
01073 }
01074 
01075 uint TTm::GetMSecsFromOsStart(){
01076   return TSysTm::GetMSecsFromOsStart();
01077 }
01078 
01079 uint64 TTm::GetPerfTimerFq(){
01080   return TSysTm::GetPerfTimerFq();
01081 }
01082 
01083 uint64 TTm::GetPerfTimerTicks(){
01084   return TSysTm::GetPerfTimerTicks();
01085 }
01086 
01087 void TTm::GetDiff(const TTm& Tm1, const TTm& Tm2, int& Days, 
01088           int& Hours, int& Mins, int& Secs, int& MSecs) {
01089 
01090         const uint64 DiffMSecs = TTm::GetDiffMSecs(Tm1, Tm2);
01091         const uint64 DiffSecs = DiffMSecs / 1000;
01092         const uint64 DiffMins = DiffSecs / 60;
01093         const uint64 DiffHours = DiffMins / 60; 
01094 
01095         MSecs = int(DiffMSecs % 1000);
01096         Secs = int(DiffSecs % 60);
01097         Mins = int(DiffMins % 60);
01098         Hours = int(DiffHours % 24);
01099         Days = int((int)DiffHours / 24);
01100 }
01101 
01102 uint64 TTm::GetDiffMSecs(const TTm& Tm1, const TTm& Tm2){
01103   uint64 Tm1MSecs=GetMSecsFromTm(Tm1);
01104   uint64 Tm2MSecs=GetMSecsFromTm(Tm2);
01105   if (Tm1MSecs>Tm2MSecs){
01106     return Tm1MSecs-Tm2MSecs;
01107   } else {
01108     return Tm2MSecs-Tm1MSecs;
01109   }
01110 }
01111 
01112 TTm TTm::GetLocTmFromUniTm(const TTm& Tm){
01113   return TSysTm::GetLocTmFromUniTm(Tm);
01114 }
01115 
01116 TTm TTm::GetUniTmFromLocTm(const TTm& Tm){
01117   return TSysTm::GetUniTmFromLocTm(Tm);
01118 }
01119 
01120 TTm TTm::GetTmFromWebLogTimeStr(const TStr& TimeStr,
01121  const char TimeSepCh, const char MSecSepCh){
01122   int TimeStrLen=TimeStr.Len();
01123   // year
01124   TChA ChA; int ChN=0;
01125   while ((ChN<TimeStrLen)&&(TimeStr[ChN]!=TimeSepCh)){
01126     ChA+=TimeStr[ChN]; ChN++;}
01127   TStr HourStr=ChA;
01128   // minute
01129   ChA.Clr(); ChN++;
01130   while ((ChN<TimeStrLen)&&(TimeStr[ChN]!=TimeSepCh)){
01131     ChA+=TimeStr[ChN]; ChN++;}
01132   TStr MinStr=ChA;
01133   // second
01134   ChA.Clr(); ChN++;
01135   while ((ChN<TimeStrLen)&&(TimeStr[ChN]!=MSecSepCh)){
01136     ChA+=TimeStr[ChN]; ChN++;}
01137   TStr SecStr=ChA;
01138   // mili-second
01139   ChA.Clr(); ChN++;
01140   while (ChN<TimeStrLen){
01141     ChA+=TimeStr[ChN]; ChN++;}
01142   TStr MSecStr=ChA;
01143   // transform to numbers
01144   int HourN=HourStr.GetInt(0);
01145   int MinN=MinStr.GetInt(0);
01146   int SecN=SecStr.GetInt(0);
01147   int MSecN=MSecStr.GetInt(0);
01148   // construct time
01149   TTm Tm(-1, -1, -1, -1, HourN, MinN, SecN, MSecN);
01150   // return time
01151   return Tm;
01152 }
01153 
01154 TTm TTm::GetTmFromWebLogDateTimeStr(const TStr& DateTimeStr,
01155  const char DateSepCh, const char TimeSepCh, const char MSecSepCh,
01156  const char DateTimeSepCh){
01157   int DateTimeStrLen=DateTimeStr.Len();
01158   // year
01159   TChA ChA; int ChN=0;
01160   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=DateSepCh)){
01161     ChA+=DateTimeStr[ChN]; ChN++;}
01162   TStr YearStr=ChA;
01163   // month
01164   ChA.Clr(); ChN++;
01165   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=DateSepCh)){
01166     ChA+=DateTimeStr[ChN]; ChN++;}
01167   TStr MonthStr=ChA;
01168   // day
01169   ChA.Clr(); ChN++;
01170   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=DateTimeSepCh)){
01171     ChA+=DateTimeStr[ChN]; ChN++;}
01172   TStr DayStr=ChA;
01173   // hour
01174   ChA.Clr(); ChN++;
01175   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=TimeSepCh)){
01176     ChA+=DateTimeStr[ChN]; ChN++;}
01177   TStr HourStr=ChA;
01178   // minute
01179   ChA.Clr(); ChN++;
01180   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=TimeSepCh)){
01181     ChA+=DateTimeStr[ChN]; ChN++;}
01182   TStr MinStr=ChA;
01183   // second
01184   ChA.Clr(); ChN++;
01185   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=MSecSepCh)){
01186     ChA+=DateTimeStr[ChN]; ChN++;}
01187   TStr SecStr=ChA;
01188   // mili-second
01189   ChA.Clr(); ChN++;
01190   while (ChN<DateTimeStrLen){
01191     ChA+=DateTimeStr[ChN]; ChN++;}
01192   TStr MSecStr=ChA;
01193   // transform to numbers
01194   int YearN=YearStr.GetInt(-1);
01195   int MonthN=MonthStr.GetInt(-1);
01196   int DayN=DayStr.GetInt(-1);
01197   int HourN=HourStr.GetInt(0);
01198   int MinN=MinStr.GetInt(0);
01199   int SecN=SecStr.GetInt(0);
01200   int MSecN=MSecStr.GetInt(0);
01201   // construct time
01202   TTm Tm;
01203   if ((YearN!=-1)&&(MonthN!=-1)&&(DayN!=-1)){
01204     Tm=TTm(YearN, MonthN, DayN, -1, HourN, MinN, SecN, MSecN);
01205   }
01206   // return time
01207   return Tm;
01208 }
01209 
01210 TTm TTm::GetTmFromIdStr(const TStr& IdStr){
01211   // normalize
01212   TChA IdChA=IdStr;
01213   if (IdChA.Len()==14){
01214     IdChA.Ins(0, "0");}
01215   // check
01216   IAssert(IdChA.Len()==15);
01217   for (int ChN=0; ChN<IdChA.Len(); ChN++){
01218     IAssert(TCh::IsNum(IdChA[ChN]));}
01219   // extract parts
01220   int YearN=2000+(TStr(IdChA[0])+TStr(IdChA[1])).GetInt();
01221   int MonthN=(TStr(IdChA[2])+TStr(IdChA[3])).GetInt();
01222   int DayN=(TStr(IdChA[4])+TStr(IdChA[5])).GetInt();
01223   int HourN=(TStr(IdChA[6])+TStr(IdChA[7])).GetInt();
01224   int MinN=(TStr(IdChA[8])+TStr(IdChA[9])).GetInt();
01225   int SecN=(TStr(IdChA[10])+TStr(IdChA[11])).GetInt();
01226   int MSecN=(TStr(IdChA[12])+TStr(IdChA[13])+TStr(IdChA[14])).GetInt();
01227   TTm Tm=TTm(YearN, MonthN, DayN, -1, HourN, MinN, SecN, MSecN);
01228   return Tm;
01229 }
01230 
01231 uint TTm::GetDateTimeInt(const int& Year, const int& Month,
01232       const int& Day, const int& Hour, const int& Min, const int& Sec) {
01233 
01234         return TSecTm(Year, Month, Day, Hour, Min, Sec).GetAbsSecs();
01235 }
01236 
01237 uint TTm::GetDateIntFromTm(const TTm& Tm) {
01238     return Tm.IsDef() ? GetDateTimeInt(Tm.GetYear(), Tm.GetMonth(), Tm.GetDay()) : 0;
01239 }
01240 
01241 uint TTm::GetMonthIntFromTm(const TTm& Tm) {
01242     return Tm.IsDef() ? GetDateTimeInt(Tm.GetYear(), Tm.GetMonth()) : 0;
01243 }
01244 
01245 uint TTm::GetYearIntFromTm(const TTm& Tm) {
01246     return Tm.IsDef() ? GetDateTimeInt(Tm.GetYear()) : 0;
01247 }
01248 
01249 uint TTm::GetDateTimeIntFromTm(const TTm& Tm) {
01250     return Tm.IsDef() ? 
01251                 GetDateTimeInt(Tm.GetYear(), Tm.GetMonth(),
01252         Tm.GetDay(), Tm.GetHour(), Tm.GetMin(), Tm.GetSec()) : 0;
01253 }
01254 
01255 TTm TTm::GetTmFromDateTimeInt(const uint& DateTimeInt) {
01256         if (DateTimeInt == 0) { return TTm(); }
01257         return TTm(TSecTm(DateTimeInt));
01258 }
01259 
01260 TSecTm TTm::GetSecTmFromDateTimeInt(const uint& DateTimeInt) {
01261         if (DateTimeInt == 0) { return TSecTm(); }
01262         return TSecTm(DateTimeInt);
01263 }
01264 
01266 // Time-Profiler - poor-man's profiler
01267 int TTmProfiler::AddTimer(const TStr& TimerNm) { 
01268         MxNmLen = TInt::GetMx(MxNmLen, TimerNm.Len());
01269         return TimerH.AddKey(TimerNm); 
01270 }
01271 
01272 void TTmProfiler::ResetAll() {
01273     int TimerId = GetTimerIdFFirst();
01274         while (GetTimerIdFNext(TimerId)) {
01275                 ResetTimer(TimerId);
01276         }
01277 }
01278 
01279 double TTmProfiler::GetTimerSumSec() const {
01280         double Sum = 0.0;
01281     int TimerId = GetTimerIdFFirst();
01282         while (GetTimerIdFNext(TimerId)) {
01283                 Sum += GetTimerSec(TimerId);
01284         }
01285     return Sum;
01286 }
01287 
01288 double TTmProfiler::GetTimerSec(const int& TimerId) const {
01289     return TimerH[TimerId].GetSec();
01290 }
01291 
01292 void TTmProfiler::PrintReport(const TStr& ProfileNm) const {
01293     const double TimerSumSec = GetTimerSumSec();
01294         printf("-- %s --\n", ProfileNm.CStr());
01295     printf("Sum: (%.2f sec):\n", TimerSumSec);
01296     int TimerId = GetTimerIdFFirst();
01297         while (GetTimerIdFNext(TimerId)) {
01298         // get timer name
01299         TStr TimerNm = GetTimerNm(TimerId);
01300         TimerNm = TStr::GetSpaceStr(TimerNm.Len() - MxNmLen) + TimerNm;
01301         // get timer time and precentage
01302         if (TimerSumSec > 0.0) {
01303             const double TimerSec = GetTimerSec(TimerId);
01304             const double TimerPerc =  TimerSec / TimerSumSec * 100.0;
01305             printf(" %s: %.2fs [%.2f%%]\n", TimerNm.CStr(), TimerSec, TimerPerc);
01306         } else {
01307             printf(" %s: -\n", TimerNm.CStr());
01308         }
01309     }
01310         printf("--\n");
01311 }