SNAP Library , Developer Reference  2013-01-07 14:03:36
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("aug"); 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   IAssertR(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    //int(TMath::Round(Tm.GetSec()*1000+Tm.GetMSec()))).GetAbsSecs()){}
00436 
00437 TSecTm::TSecTm(const PXmlTok& XmlTok) {
00438   const int Year = XmlTok->GetIntArgVal("Year");
00439   const int Month = XmlTok->GetIntArgVal("Month");
00440   const int Day = XmlTok->GetIntArgVal("Day");
00441   const int Hour = XmlTok->GetIntArgVal("Hour");
00442   const int Min = XmlTok->GetIntArgVal("Min");
00443   const int Sec = XmlTok->GetIntArgVal("Sec");
00444   AbsSecs = TSecTm(Year, Month, Day, Hour, Min, Sec).GetAbsSecs();
00445 }
00446 
00447 PXmlTok TSecTm::GetXmlTok() const {
00448   PXmlTok NodeTok = TXmlTok::New("NodeTime");
00449   NodeTok->AddArg("Year", GetYearN());
00450   NodeTok->AddArg("Month", GetMonthN());
00451   NodeTok->AddArg("Day", GetDayN());
00452   NodeTok->AddArg("Hour", GetHourN());
00453   NodeTok->AddArg("Min", GetMinN());
00454   NodeTok->AddArg("Sec", GetSecN());
00455   return NodeTok;
00456 }
00457 
00458 TStr TSecTm::GetStr(const TLoc& Loc) const {
00459   if (IsDef()) {
00460     struct tm Tm;
00461     IAssert(GetTmStruct(AbsSecs(), Tm));
00462     // Wed May 14 15:30:17 2003
00463     return TStr::Fmt("%s %s %d %02d:%02d:%02d %d",
00464       TTmInfo::GetDayOfWeekNm(Tm.tm_wday + 1, Loc).CStr(),
00465       TTmInfo::GetMonthNm(Tm.tm_mon + 1, Loc).CStr(),
00466       Tm.tm_mday, Tm.tm_hour, Tm.tm_min, Tm.tm_sec, Tm.tm_year+1900);
00467   } else {
00468     return "Undef";
00469   }
00470 }
00471 
00472 TStr TSecTm::GetStr(const TTmUnit& TmUnit) const {
00473   if (TmUnit == tmuYear) {
00474     return TInt::GetStr(GetYearN()); }
00475   else if (TmUnit == tmuMonth) {
00476     return TStr::Fmt("%04d-%02d", GetYearN(), GetMonthN()); }
00477   else if (TmUnit == tmuDay) {
00478     return TStr::Fmt("%04d-%02d-%02d", GetYearN(), GetMonthN(), GetDayN()); }
00479   else {
00480     return TStr::Fmt("%04d-%02d-%02d %02d:%02d:%02d",
00481       GetYearN(), GetMonthN(), GetDayN(), GetHourN(), GetMinN(), GetSecN());
00482   }
00483 }
00484 
00485 TStr TSecTm::GetDtStr(const TLoc& Loc) const {
00486   if (IsDef()){
00487     struct tm Tm;
00488     IAssert(GetTmStruct(AbsSecs(), Tm));
00489     return TStr::Fmt("%s %s %d %d",
00490       TTmInfo::GetDayOfWeekNm(Tm.tm_wday + 1, Loc).CStr(),
00491       TTmInfo::GetMonthNm(Tm.tm_mon + 1, Loc).CStr(), Tm.tm_year+1900);
00492   } else {
00493     return "Undef";
00494   }
00495 }
00496 
00497 TStr TSecTm::GetDtMdyStr() const {
00498   struct tm Tm;
00499   IAssert(GetTmStruct(AbsSecs(), Tm));
00500   return TStr::Fmt("%02d/%02d%/%04d", Tm.tm_mon+1, Tm.tm_mday, Tm.tm_year+1900);
00501 }
00502 
00503 TStr TSecTm::GetDtYmdStr() const {
00504   struct tm Tm;
00505   IAssert(GetTmStruct(AbsSecs(), Tm));
00506   return TStr::Fmt("%04d-%02d-%02d", Tm.tm_year+1900, Tm.tm_mon+1, Tm.tm_mday);
00507 }
00508 
00509 TStr TSecTm::GetYmdTmStr() const {
00510   struct tm Tm;
00511   IAssert(GetTmStruct(AbsSecs(), Tm));
00512   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);
00513 }
00514 
00515 
00516 TStr TSecTm::GetTmStr() const {
00517   if (IsDef()){
00518     struct tm Tm;
00519     IAssert(GetTmStruct(AbsSecs(), Tm));
00520     return TStr::Fmt("%02d:%02d:%02d", Tm.tm_hour, Tm.tm_min, Tm.tm_sec);
00521   } else {
00522     return "Undef";
00523   }
00524 }
00525 
00526 TStr TSecTm::GetTmMinStr() const {
00527   if (IsDef()){
00528     struct tm Tm;
00529     IAssert(GetTmStruct(AbsSecs(), Tm));
00530     return TStr::Fmt("%02d:%02d", Tm.tm_min, Tm.tm_sec);
00531   } else {
00532     return "Undef";
00533   }
00534 }
00535 
00536 TStr TSecTm::GetDtTmSortStr() const {
00537   return
00538     TInt::GetStr(GetYearN(), "%04d")+"/"+
00539     TInt::GetStr(GetMonthN(), "%02d")+"/"+
00540     TInt::GetStr(GetDayN(), "%02d")+" "+
00541     TInt::GetStr(GetHourN(), "%02d")+":"+
00542     TInt::GetStr(GetMinN(), "%02d")+":"+
00543     TInt::GetStr(GetSecN(), "%02d");
00544 }
00545 
00546 TStr TSecTm::GetDtTmSortFNmStr() const {
00547   return
00548     TInt::GetStr(GetYearN(), "%04d")+"-"+
00549     TInt::GetStr(GetMonthN(), "%02d")+"-"+
00550     TInt::GetStr(GetDayN(), "%02d")+"_"+
00551     TInt::GetStr(GetHourN(), "%02d")+"-"+
00552     TInt::GetStr(GetMinN(), "%02d")+"-"+
00553     TInt::GetStr(GetSecN(), "%02d");
00554 }
00555 
00556 int TSecTm::GetYearN() const {
00557   struct tm Tm;
00558   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00559   return Tm.tm_year+1900;
00560 }
00561 
00562 int TSecTm::GetMonthN() const {
00563   struct tm Tm;
00564   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00565   return Tm.tm_mon+1;
00566 }
00567 
00568 TStr TSecTm::GetMonthNm(const TLoc& Loc) const {
00569   struct tm Tm;
00570   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00571   return TTmInfo::GetMonthNm(Tm.tm_mon+1, Loc);
00572 }
00573 
00574 int TSecTm::GetDayN() const {
00575   struct tm Tm;
00576   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00577   return Tm.tm_mday;
00578 }
00579 
00580 int TSecTm::GetDayOfWeekN() const {
00581   struct tm Tm;
00582   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00583   return Tm.tm_wday + 1;
00584 }
00585 
00586 TStr TSecTm::GetDayOfWeekNm(const TLoc& Loc) const {
00587   struct tm Tm;
00588   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00589   return TTmInfo::GetDayOfWeekNm(Tm.tm_wday+1, Loc);
00590 }
00591 
00592 int TSecTm::GetHourN() const {
00593   struct tm Tm;
00594   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00595   return Tm.tm_hour;
00596 }
00597 
00598 int TSecTm::GetMinN() const {
00599   struct tm Tm;
00600   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00601   return Tm.tm_min;
00602 }
00603 
00604 int TSecTm::GetSecN() const {
00605   struct tm Tm;
00606   IAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00607   return Tm.tm_sec;
00608 }
00609 
00610 void TSecTm::GetComps(int& Year, int& Month, int& Day, int& Hour, int& Min, int& Sec) const {
00611   struct tm Tm;
00612   EAssert(IsDef() && GetTmStruct(AbsSecs(), Tm));
00613   Year = Tm.tm_year+1900;
00614   Month = Tm.tm_mon+1;
00615   Day = Tm.tm_mday;
00616   Hour = Tm.tm_hour;
00617   Min = Tm.tm_min;
00618   Sec = Tm.tm_sec;
00619 }
00620 
00621 TSecTm TSecTm::Round(const TTmUnit& TmUnit) const {
00622   if (TmUnit == tmu1Sec) { return *this; }
00623   struct tm Time;
00624   IAssert(IsDef() && GetTmStruct(AbsSecs(), Time));
00625   switch (TmUnit) {
00626     case tmu1Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, Time.tm_min, 0);
00627     case tmu10Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 10*(Time.tm_min/10), 0);
00628     case tmu15Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 15*(Time.tm_min/15), 0);
00629     case tmu30Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 30*(Time.tm_min/30), 0);
00630     case tmu1Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 0, 0);
00631     case tmu2Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 2*(Time.tm_hour/2), 0, 0);
00632     case tmu4Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 4*(Time.tm_hour/4), 0, 0);
00633     case tmu6Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 6*(Time.tm_hour/6), 0, 0);
00634     case tmu12Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 12*(Time.tm_hour/12), 0, 0);
00635     case tmuDay : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, 0, 0, 0);
00636     case tmuMonth : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, 1, 0, 0, 0);
00637     case tmuYear : return TSecTm(Time.tm_year+1900, 1, 1, 0, 0, 0);
00638     case tmuWeek : { int dd=1, mm=1, yy=1;
00639       // week starts on Thursday, since 1.1.1970 is Thursday
00640       const int Day = TJulianDate::GetJulianDateN(Time.tm_mday, Time.tm_mon+1, 1900+Time.tm_year);
00641       TJulianDate::GetCalendarDate(3+7*(Day/7), dd, mm, yy);  return TSecTm(yy, mm, dd, 0, 0, 0); }
00642     default : Fail;
00643   }
00644   return TSecTm();
00645 }
00646 uint TSecTm::GetInUnits(const TTmUnit& TmUnit) const {
00647   static const int DayZero = TJulianDate::GetJulianDateN(1, 1, 1970);
00648   if (TmUnit == tmu1Sec) { return AbsSecs; }
00649   struct tm Time;
00650   IAssert(IsDef() && GetTmStruct(AbsSecs(), Time));
00651   switch (TmUnit) {
00652     case tmu1Min : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, Time.tm_min, 0).GetAbsSecs()/60;
00653     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);
00654     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);
00655     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);
00656     case tmu1Hour : return TSecTm(Time.tm_year+1900, Time.tm_mon+1, Time.tm_mday, Time.tm_hour, 0, 0).GetAbsSecs()/3600;
00657     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);
00658     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);
00659     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);
00660     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);
00661     case tmuDay : return TJulianDate::GetJulianDateN(Time.tm_mday, Time.tm_mon+1, 1900+Time.tm_year) - DayZero;
00662     case tmuWeek : return (TJulianDate::GetJulianDateN(Time.tm_mday, Time.tm_mon+1, 1900+Time.tm_year)-DayZero)/7;
00663     case tmuMonth : return 12*(Time.tm_year-70)+Time.tm_mon+1;
00664     case tmuYear : return Time.tm_year+1900;
00665     default : Fail;
00666   }
00667   return TUInt::Mx;
00668 }
00669 
00670 TStr TSecTm::GetDayPart() const {
00671         const int Hour = GetHourN();
00672         if (0 <= Hour && Hour < 6) { return "Night"; }
00673         else if (6 <= Hour && Hour < 12) { return "Morning"; }
00674         else if (12 <= Hour && Hour < 18) { return "Afternoon"; }
00675         else if (18 <= Hour && Hour < 24) { return "Evening"; }
00676         return "";
00677 }
00678 
00679 uint TSecTm::GetDSecs(const TSecTm& SecTm1, const TSecTm& SecTm2){
00680   IAssert(SecTm1.IsDef()&&SecTm2.IsDef());
00681   const time_t Time1= time_t(SecTm1.AbsSecs());
00682   const time_t Time2= time_t(SecTm2.AbsSecs());
00683   return uint(difftime(Time2, Time1));
00684 }
00685 
00686 TSecTm TSecTm::GetZeroWeekTm(){
00687   TSecTm ZeroWeekTm=GetZeroTm();
00688   while (ZeroWeekTm.GetDayOfWeekN()!=TTmInfo::MonN){
00689     ZeroWeekTm.AddDays(1);}
00690   return ZeroWeekTm;
00691 }
00692 
00693 TSecTm TSecTm::GetCurTm(){
00694   const time_t TmSec = time(NULL);
00695   struct tm LocTm;
00696   uint AbsSec = TUInt::Mx;
00697   #if defined(GLib_MSN)
00698   localtime_s(&LocTm, &TmSec);
00699   #elif defined(GLib_BCB)
00700   LocTm = *localtime(&TmSec);
00701   #else
00702   LocTm = *localtime(&TmSec);
00703   #endif
00704   IAssert(TSecTm::GetTmSec(LocTm, AbsSec));
00705   return TSecTm(AbsSec);
00706 }
00707 
00708 TSecTm TSecTm::GetDtTmFromHmsStr(const TStr& HmsStr){
00709   int HmsStrLen=HmsStr.Len();
00710   // hour
00711   TChA ChA; int ChN=0;
00712   while ((ChN<HmsStrLen)&&(HmsStr[ChN]!=':')){ChA+=HmsStr[ChN]; ChN++;}
00713   TStr HourStr=ChA;
00714   // minute
00715   ChA.Clr(); ChN++;
00716   while ((ChN<HmsStrLen)&&(HmsStr[ChN]!=':')){ChA+=HmsStr[ChN]; ChN++;}
00717   TStr MinStr=ChA;
00718   // second
00719   ChA.Clr(); ChN++;
00720   while (ChN<HmsStrLen){ChA+=HmsStr[ChN]; ChN++;}
00721   TStr SecStr=ChA;
00722   // transform to numbers
00723   int HourN=HourStr.GetInt();
00724   int MinN=MinStr.GetInt();
00725   int SecN=SecStr.GetInt();
00726   // construct the time
00727   TSecTm Tm=TSecTm::GetZeroTm();
00728   Tm.AddHours(HourN);
00729   Tm.AddMins(MinN);
00730   Tm.AddSecs(SecN);
00731   return Tm;
00732 }
00733 
00734 TSecTm TSecTm::GetDtTmFromMdyStr(const TStr& MdyStr){
00735   int MdyStrLen=MdyStr.Len();
00736   // month
00737   TChA ChA; int ChN=0;
00738   while ((ChN<MdyStrLen)&&(MdyStr[ChN]!='/')){
00739     ChA+=MdyStr[ChN]; ChN++;}
00740   TStr MonthStr=ChA;
00741   // day
00742   ChA.Clr(); ChN++;
00743   while ((ChN<MdyStrLen)&&(MdyStr[ChN]!='/')){
00744     ChA+=MdyStr[ChN]; ChN++;}
00745   TStr DayStr=ChA;
00746   // year
00747   ChA.Clr(); ChN++;
00748   while (ChN<MdyStrLen){
00749     ChA+=MdyStr[ChN]; ChN++;}
00750   TStr YearStr=ChA;
00751   // transform to numbers
00752   int MonthN=MonthStr.GetInt();
00753   int DayN=DayStr.GetInt();
00754   int YearN=YearStr.GetInt();
00755   if (YearN<1000){
00756     if (YearN<70){YearN+=2000;} else {YearN+=1900;}}
00757   // construct the date
00758   return GetDtTm(YearN, MonthN, DayN);
00759 }
00760 
00761 // parse 28/03/03 and 28-MAY-03 formats
00762 TSecTm TSecTm::GetDtTmFromDmyStr(const TStr& DmyStr){
00763   int DmyStrLen=DmyStr.Len();
00764   // day
00765   TChA ChA; int ChN=0;
00766   while ((ChN<DmyStrLen)&&(DmyStr[ChN]!='/')&&(DmyStr[ChN]!='-')){
00767     ChA+=DmyStr[ChN]; ChN++;}
00768   TStr DayStr=ChA;
00769   // month
00770   ChA.Clr(); ChN++;
00771   while ((ChN<DmyStrLen)&&(DmyStr[ChN]!='/')&&(DmyStr[ChN]!='-')){
00772     ChA+=DmyStr[ChN]; ChN++;}
00773   TStr MonthStr=ChA;
00774   // year
00775   ChA.Clr(); ChN++;
00776   while (ChN<DmyStrLen){
00777     ChA+=DmyStr[ChN]; ChN++;}
00778   TStr YearStr=ChA;
00779   // transform to numbers
00780   int DayN=DayStr.GetInt(-1);
00781   int MonthN=MonthStr.GetInt(-1);
00782   int YearN=YearStr.GetInt(-1);
00783   if (MonthN == -1){
00784     MonthN = TTmInfo::GetMonthN(MonthStr.ToCap()); }
00785   if ((DayN==-1)||(MonthN==-1)||(YearN==-1)){
00786     return TSecTm();
00787   } else {
00788     if (YearN<1000){
00789       if (YearN<70){YearN+=2000;} else {YearN+=1900;}}
00790     // construct the date
00791     return GetDtTm(YearN, MonthN, DayN);
00792   }
00793   return TSecTm();
00794 }
00795 
00796 TSecTm TSecTm::GetDtTmFromMdyHmsPmStr(const TStr& MdyHmsPmStr,
00797  const char& DateSepCh, const char& TimeSepCh){
00798   int MdyHmsPmStrLen=MdyHmsPmStr.Len();
00799   // month
00800   TChA ChA; int ChN=0;
00801   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=DateSepCh)){
00802     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00803   TStr MonthStr=ChA;
00804   // day
00805   ChA.Clr(); ChN++;
00806   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=DateSepCh)){
00807     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00808   TStr DayStr=ChA;
00809   // year
00810   ChA.Clr(); ChN++;
00811   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=' ')){
00812     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00813   TStr YearStr=ChA;
00814   // hour
00815   ChA.Clr(); ChN++;
00816   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=TimeSepCh)){
00817     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00818   TStr HourStr=ChA;
00819   // minute
00820   ChA.Clr(); ChN++;
00821   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=TimeSepCh)){
00822     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00823   TStr MinStr=ChA;
00824   // second
00825   ChA.Clr(); ChN++;
00826   while ((ChN<MdyHmsPmStrLen)&&(MdyHmsPmStr[ChN]!=' ')){
00827     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00828   TStr SecStr=ChA;
00829   // AM/PM
00830   ChA.Clr(); ChN++;
00831   while (ChN<MdyHmsPmStrLen){
00832     ChA+=MdyHmsPmStr[ChN]; ChN++;}
00833   TStr AmPmStr=ChA;
00834   // transform to numbers
00835   int MonthN=MonthStr.GetInt();
00836   int DayN=DayStr.GetInt();
00837   int YearN=YearStr.GetInt();
00838   int HourN; int MinN; int SecN;
00839   if (HourStr.IsInt()){
00840     HourN=HourStr.GetInt();
00841     MinN=MinStr.GetInt();
00842     SecN=SecStr.GetInt();
00843     if (AmPmStr=="AM"){} else if (AmPmStr=="PM"){HourN+=12;} else {Fail;}
00844   } else {
00845     HourN=0; MinN=0; SecN=0;
00846   }
00847   // construct the time
00848   TSecTm Tm=TSecTm::GetDtTm(YearN, MonthN, DayN);
00849   Tm.AddHours(HourN);
00850   Tm.AddMins(MinN);
00851   Tm.AddSecs(SecN);
00852   return Tm;
00853 }
00854 
00855 TSecTm TSecTm::GetDtTmFromYmdHmsStr(const TStr& YmdHmsPmStr,
00856  const char& DateSepCh, const char& TimeSepCh){
00857   int YmdHmsPmStrLen=YmdHmsPmStr.Len();
00858   // year
00859   TChA ChA; int ChN=0;
00860   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=DateSepCh)){
00861     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00862   TStr YearStr=ChA;
00863   // month
00864   ChA.Clr(); ChN++;
00865   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=DateSepCh)){
00866     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00867   TStr MonthStr=ChA;
00868   // day
00869   ChA.Clr(); ChN++;
00870   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=' ')){
00871     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00872   TStr DayStr=ChA;
00873   // hour
00874   ChA.Clr(); ChN++;
00875   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=TimeSepCh)){
00876     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00877   TStr HourStr=ChA;
00878   // minute
00879   ChA.Clr(); ChN++;
00880   while ((ChN<YmdHmsPmStrLen)&&(YmdHmsPmStr[ChN]!=TimeSepCh)){
00881     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00882   TStr MinStr=ChA;
00883   // second
00884   ChA.Clr(); ChN++;
00885   while (ChN<YmdHmsPmStrLen){
00886     ChA+=YmdHmsPmStr[ChN]; ChN++;}
00887   TStr SecStr=ChA;
00888   // transform to numbers
00889   int MonthN=MonthStr.GetInt();
00890   int DayN=DayStr.GetInt();
00891   int YearN=YearStr.GetInt();
00892   int HourN; int MinN; int SecN;
00893   if (HourStr.IsInt()){
00894     HourN=HourStr.GetInt();
00895     MinN=MinStr.GetInt();
00896     SecN=SecStr.GetInt();
00897   } else {
00898     HourN=0; MinN=0; SecN=0;
00899   }
00900   // construct the time
00901   TSecTm Tm=TSecTm::GetDtTm(YearN, MonthN, DayN);
00902   Tm.AddHours(HourN);
00903   Tm.AddMins(MinN);
00904   Tm.AddSecs(SecN);
00905   return Tm;
00906 }
00907 
00908 // Parse strings of the form 2006-08-28 14:11:16 or 14:11:16  08/28/2008
00909 // Non-numeric characters act as separators (there can be many consecutive separating characters)
00910 // Variables give indexes of the date fields
00911 TSecTm TSecTm::GetDtTmFromStr(const TChA& YmdHmsPmStr, const int& YearId, const int& MonId,
00912  const int& DayId, const int& HourId, const int& MinId, const int& SecId) {
00913   TChA Tmp = YmdHmsPmStr;
00914   TVec<char *> FldV;
00915   // get the sequences of numbers
00916   for (char *c = (char *) Tmp.CStr(); *c; c++) {
00917     if (TCh::IsNum(*c)) {
00918       FldV.Add(c);
00919       while (TCh::IsNum(*c)) { c++; }
00920       c--;
00921     } else { *c = 0; }
00922   }
00923   const int Y = atoi(FldV[YearId]);
00924   const int M = atoi(FldV[MonId]);
00925   const int D = atoi(FldV[DayId]);
00926   const int H = atoi(FldV[HourId]);
00927   const int m = atoi(FldV[MinId]);
00928   const int S = atoi(FldV[SecId]);
00929   IAssert(Y>0 && M>0 && D>0 && M<13 && D<32);
00930   IAssert(H>=0 && H<24 && m>=0 && m<60 && S>=0 && S<60);
00931   return TSecTm(Y,M,D,H,m,S);
00932 }
00933 
00934 TSecTm TSecTm::GetDtTm(const int& YearN, const int& MonthN, const int& DayN){
00935   uint AbsSecs;
00936   TSecTm::GetTmSec(YearN, MonthN, DayN, 0, 0, 0, AbsSecs);
00937   return TSecTm(AbsSecs);
00938 }
00939 
00940 TSecTm TSecTm::GetDtTm(const TSecTm& Tm){
00941   int DaySecs=Tm.GetHourN()*3600+Tm.GetMinN()*60+Tm.GetSecN();
00942   TSecTm DtTm(Tm.AbsSecs-DaySecs);
00943   return DtTm;
00944 }
00945 
00946 TSecTm TSecTm::LoadTxt(TILx& Lx){
00947   return TSecTm(Lx.GetInt());
00948 }
00949 
00950 void TSecTm::SaveTxt(TOLx& Lx) const {
00951   IAssert(int(AbsSecs) < TInt::Mx);
00952   Lx.PutInt((int)AbsSecs);
00953 }
00954 
00956 // Date-Time
00957 TStr TTm::GetStr(const bool& MSecP) const {
00958   TChA ChA;
00959   ChA+=TInt::GetStr(Year, "%04d"); ChA+='-';
00960 //  ChA+=GetMonthNm(); ChA+='-';
00961   ChA+=TInt::GetStr(Month, "%02d"); ChA+='-';
00962   ChA+=TInt::GetStr(Day, "%02d"); ChA+=' ';
00963 //  ChA+=GetDayOfWeekNm(); ChA+=' ';
00964   ChA+=TInt::GetStr(Hour, "%02d"); ChA+=':';
00965   ChA+=TInt::GetStr(Min, "%02d"); ChA+=':';
00966   ChA+=TInt::GetStr(Sec, "%02d");
00967   if (MSecP){ChA+='.'; ChA+=TInt::GetStr(MSec, "%04d");}
00968   return ChA;
00969 }
00970 
00971 TStr TTm::GetYMDDashStr() const {
00972   TChA ChA;
00973   ChA+=TInt::GetStr(Year, "%04d");
00974   ChA+='-'; ChA+=TInt::GetStr(Month, "%02d");
00975   ChA+='-'; ChA+=TInt::GetStr(Day, "%02d");
00976   return ChA;
00977 }
00978 
00979 TStr TTm::GetHMSTColonDotStr(const bool& FullP, const bool& MSecP) const {
00980   TChA ChA;
00981   ChA+=TInt::GetStr(Hour, "%02d");
00982   ChA+=':'; ChA+=TInt::GetStr(Min, "%02d");
00983   if (FullP||((Sec!=0)||(MSec!=0))){
00984     ChA+=':'; ChA+=TInt::GetStr(Sec, "%02d");
00985     if ((MSecP)&&(FullP||(MSec!=0))){
00986       ChA+='.'; ChA+=TInt::GetStr(MSec, "%d");
00987     }
00988   }
00989   return ChA;
00990 }
00991 
00992 TStr TTm::GetIdStr() const {
00993   TChA ChA;
00994   ChA+=TInt::GetStr(Year%100, "%02d");
00995   ChA+=TInt::GetStr(Month, "%02d");
00996   ChA+=TInt::GetStr(Day, "%02d");
00997   ChA+=TInt::GetStr(Hour, "%02d");
00998   ChA+=TInt::GetStr(Min, "%02d");
00999   ChA+=TInt::GetStr(Sec, "%02d");
01000   ChA+=TInt::GetStr(MSec, "%03d");
01001   return ChA;
01002 }
01003 
01004 
01005 void TTm::AddTime(const int& Hours,
01006  const int& Mins, const int& Secs, const int& MSecs){
01007   uint64 TmMSecs=TTm::GetMSecsFromTm(*this);
01008   TmMSecs+=(uint64(Hours)*uint64(3600)*uint64(1000));
01009   TmMSecs+=(uint64(Mins)*uint64(60)*uint64(1000));
01010   TmMSecs+=(uint64(Secs)*uint64(1000));
01011   TmMSecs+=uint64(MSecs);
01012   *this=GetTmFromMSecs(TmMSecs);
01013 }
01014 
01015 void TTm::SubTime(const int& Hours,
01016  const int& Mins, const int& Secs, const int& MSecs){
01017   uint64 TmMSecs=TTm::GetMSecsFromTm(*this);
01018   TmMSecs-=(uint64(Hours)*uint64(3600)*uint64(1000));
01019   TmMSecs-=(uint64(Mins)*uint64(60)*uint64(1000));
01020   TmMSecs-=(uint64(Secs)*uint64(1000));
01021   TmMSecs-=(uint64(MSecs));
01022   *this=GetTmFromMSecs(TmMSecs);
01023 }
01024 
01025 TTm TTm::GetCurUniTm(){
01026   return TSysTm::GetCurUniTm();
01027 }
01028 
01029 TTm TTm::GetUniqueCurUniTm(){
01030   static TTm LastUniqueTm=TSysTm::GetCurUniTm();
01031   TTm CurUniqueTm=TSysTm::GetCurUniTm();
01032   if (CurUniqueTm<LastUniqueTm){CurUniqueTm=LastUniqueTm;}
01033   if (CurUniqueTm==LastUniqueTm){CurUniqueTm.AddTime(0, 0, 0, 1);}
01034   LastUniqueTm=CurUniqueTm;
01035   return CurUniqueTm;
01036 }
01037 
01038 TTm TTm::GetUniqueCurUniTm(const int& UniqueSpaces, const int& UniqueSpaceN){
01039   static uint64 LastMUniqueTmMSecs=TSysTm::GetCurUniMSecs();
01040   // uniqueness-space-parameters range-check
01041   Assert(UniqueSpaces>=1&&UniqueSpaceN>=0&&UniqueSpaceN<UniqueSpaces);
01042   // get current time
01043   uint64 CurUniqueTmMSecs=TSysTm::GetCurUniMSecs();
01044   if (CurUniqueTmMSecs<LastMUniqueTmMSecs){CurUniqueTmMSecs=LastMUniqueTmMSecs;}
01045   // normalize to uniqueness-space-grid
01046   CurUniqueTmMSecs-=CurUniqueTmMSecs%UniqueSpaces; CurUniqueTmMSecs+=UniqueSpaceN;
01047   // get next free unique-time
01048   if (CurUniqueTmMSecs<=LastMUniqueTmMSecs){
01049     CurUniqueTmMSecs+=UniqueSpaces;
01050   }
01051   // update last-time
01052   LastMUniqueTmMSecs=CurUniqueTmMSecs;
01053   return GetTmFromMSecs(CurUniqueTmMSecs);
01054 }
01055 
01056 TTm TTm::GetCurLocTm(){
01057   return TSysTm::GetCurLocTm();
01058 }
01059 
01060 uint64 TTm::GetCurUniMSecs(){
01061   return TSysTm::GetCurUniMSecs();
01062 }
01063 
01064 uint64 TTm::GetCurLocMSecs(){
01065   return TSysTm::GetCurLocMSecs();
01066 }
01067 
01068 uint64 TTm::GetMSecsFromTm(const TTm& Tm){
01069   return TSysTm::GetMSecsFromTm(Tm);
01070 }
01071 
01072 TTm TTm::GetTmFromMSecs(const uint64& MSecs){
01073   return TSysTm::GetTmFromMSecs(MSecs);
01074 }
01075 
01076 uint TTm::GetMSecsFromOsStart(){
01077   return TSysTm::GetMSecsFromOsStart();
01078 }
01079 
01080 uint64 TTm::GetPerfTimerFq(){
01081   return TSysTm::GetPerfTimerFq();
01082 }
01083 
01084 uint64 TTm::GetPerfTimerTicks(){
01085   return TSysTm::GetPerfTimerTicks();
01086 }
01087 
01088 void TTm::GetDiff(const TTm& Tm1, const TTm& Tm2, int& Days, 
01089           int& Hours, int& Mins, int& Secs, int& MSecs) {
01090 
01091         const uint64 DiffMSecs = TTm::GetDiffMSecs(Tm1, Tm2);
01092         const uint64 DiffSecs = DiffMSecs / 1000;
01093         const uint64 DiffMins = DiffSecs / 60;
01094         const uint64 DiffHours = DiffMins / 60; 
01095 
01096         MSecs = DiffMSecs % 1000;
01097         Secs = DiffSecs % 60;
01098         Mins = DiffMins % 60;
01099         Hours = DiffHours % 24;
01100         Days = (int)DiffHours / 24;
01101 }
01102 
01103 uint64 TTm::GetDiffMSecs(const TTm& Tm1, const TTm& Tm2){
01104   uint64 Tm1MSecs=GetMSecsFromTm(Tm1);
01105   uint64 Tm2MSecs=GetMSecsFromTm(Tm2);
01106   if (Tm1MSecs>Tm2MSecs){
01107     return Tm1MSecs-Tm2MSecs;
01108   } else {
01109     return Tm2MSecs-Tm1MSecs;
01110   }
01111 }
01112 
01113 TTm TTm::GetLocTmFromUniTm(const TTm& Tm){
01114   return TSysTm::GetLocTmFromUniTm(Tm);
01115 }
01116 
01117 TTm TTm::GetUniTmFromLocTm(const TTm& Tm){
01118   return TSysTm::GetUniTmFromLocTm(Tm);
01119 }
01120 
01121 TTm TTm::GetTmFromWebLogTimeStr(const TStr& TimeStr,
01122  const char TimeSepCh, const char MSecSepCh){
01123   int TimeStrLen=TimeStr.Len();
01124   // year
01125   TChA ChA; int ChN=0;
01126   while ((ChN<TimeStrLen)&&(TimeStr[ChN]!=TimeSepCh)){
01127     ChA+=TimeStr[ChN]; ChN++;}
01128   TStr HourStr=ChA;
01129   // minute
01130   ChA.Clr(); ChN++;
01131   while ((ChN<TimeStrLen)&&(TimeStr[ChN]!=TimeSepCh)){
01132     ChA+=TimeStr[ChN]; ChN++;}
01133   TStr MinStr=ChA;
01134   // second
01135   ChA.Clr(); ChN++;
01136   while ((ChN<TimeStrLen)&&(TimeStr[ChN]!=MSecSepCh)){
01137     ChA+=TimeStr[ChN]; ChN++;}
01138   TStr SecStr=ChA;
01139   // mili-second
01140   ChA.Clr(); ChN++;
01141   while (ChN<TimeStrLen){
01142     ChA+=TimeStr[ChN]; ChN++;}
01143   TStr MSecStr=ChA;
01144   // transform to numbers
01145   int HourN=HourStr.GetInt(0);
01146   int MinN=MinStr.GetInt(0);
01147   int SecN=SecStr.GetInt(0);
01148   int MSecN=MSecStr.GetInt(0);
01149   // construct time
01150   TTm Tm(-1, -1, -1, -1, HourN, MinN, SecN, MSecN);
01151   // return time
01152   return Tm;
01153 }
01154 
01155 TTm TTm::GetTmFromWebLogDateTimeStr(const TStr& DateTimeStr,
01156  const char DateSepCh, const char TimeSepCh, const char MSecSepCh,
01157  const char DateTimeSepCh){
01158   int DateTimeStrLen=DateTimeStr.Len();
01159   // year
01160   TChA ChA; int ChN=0;
01161   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=DateSepCh)){
01162     ChA+=DateTimeStr[ChN]; ChN++;}
01163   TStr YearStr=ChA;
01164   // month
01165   ChA.Clr(); ChN++;
01166   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=DateSepCh)){
01167     ChA+=DateTimeStr[ChN]; ChN++;}
01168   TStr MonthStr=ChA;
01169   // day
01170   ChA.Clr(); ChN++;
01171   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=DateTimeSepCh)){
01172     ChA+=DateTimeStr[ChN]; ChN++;}
01173   TStr DayStr=ChA;
01174   // hour
01175   ChA.Clr(); ChN++;
01176   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=TimeSepCh)){
01177     ChA+=DateTimeStr[ChN]; ChN++;}
01178   TStr HourStr=ChA;
01179   // minute
01180   ChA.Clr(); ChN++;
01181   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=TimeSepCh)){
01182     ChA+=DateTimeStr[ChN]; ChN++;}
01183   TStr MinStr=ChA;
01184   // second
01185   ChA.Clr(); ChN++;
01186   while ((ChN<DateTimeStrLen)&&(DateTimeStr[ChN]!=MSecSepCh)){
01187     ChA+=DateTimeStr[ChN]; ChN++;}
01188   TStr SecStr=ChA;
01189   // mili-second
01190   ChA.Clr(); ChN++;
01191   while (ChN<DateTimeStrLen){
01192     ChA+=DateTimeStr[ChN]; ChN++;}
01193   TStr MSecStr=ChA;
01194   // transform to numbers
01195   int YearN=YearStr.GetInt(-1);
01196   int MonthN=MonthStr.GetInt(-1);
01197   int DayN=DayStr.GetInt(-1);
01198   int HourN=HourStr.GetInt(0);
01199   int MinN=MinStr.GetInt(0);
01200   int SecN=SecStr.GetInt(0);
01201   int MSecN=MSecStr.GetInt(0);
01202   // construct time
01203   TTm Tm;
01204   if ((YearN!=-1)&&(MonthN!=-1)&&(DayN!=-1)){
01205     Tm=TTm(YearN, MonthN, DayN, -1, HourN, MinN, SecN, MSecN);
01206   }
01207   // return time
01208   return Tm;
01209 }
01210 
01211 TTm TTm::GetTmFromIdStr(const TStr& IdStr){
01212   // normalize
01213   TChA IdChA=IdStr;
01214   if (IdChA.Len()==14){
01215     IdChA.Ins(0, "0");}
01216   // check
01217   IAssert(IdChA.Len()==15);
01218   for (int ChN=0; ChN<IdChA.Len(); ChN++){
01219     IAssert(TCh::IsNum(IdChA[ChN]));}
01220   // extract parts
01221   int YearN=2000+(TStr(IdChA[0])+TStr(IdChA[1])).GetInt();
01222   int MonthN=(TStr(IdChA[2])+TStr(IdChA[3])).GetInt();
01223   int DayN=(TStr(IdChA[4])+TStr(IdChA[5])).GetInt();
01224   int HourN=(TStr(IdChA[6])+TStr(IdChA[7])).GetInt();
01225   int MinN=(TStr(IdChA[8])+TStr(IdChA[9])).GetInt();
01226   int SecN=(TStr(IdChA[10])+TStr(IdChA[11])).GetInt();
01227   int MSecN=(TStr(IdChA[12])+TStr(IdChA[13])+TStr(IdChA[14])).GetInt();
01228   TTm Tm=TTm(YearN, MonthN, DayN, -1, HourN, MinN, SecN, MSecN);
01229   return Tm;
01230 }
01231 
01232 uint TTm::GetDateTimeInt(const int& Year, const int& Month,
01233       const int& Day, const int& Hour, const int& Min, const int& Sec) {
01234 
01235         return TSecTm(Year, Month, Day, Hour, Min, Sec).GetAbsSecs();
01236 }
01237 
01238 uint TTm::GetDateIntFromTm(const TTm& Tm) {
01239     return Tm.IsDef() ? GetDateTimeInt(Tm.GetYear(), Tm.GetMonth(), Tm.GetDay()) : 0;
01240 }
01241 
01242 uint TTm::GetMonthIntFromTm(const TTm& Tm) {
01243     return Tm.IsDef() ? GetDateTimeInt(Tm.GetYear(), Tm.GetMonth()) : 0;
01244 }
01245 
01246 uint TTm::GetYearIntFromTm(const TTm& Tm) {
01247     return Tm.IsDef() ? GetDateTimeInt(Tm.GetYear()) : 0;
01248 }
01249 
01250 uint TTm::GetDateTimeIntFromTm(const TTm& Tm) {
01251     return Tm.IsDef() ? 
01252                 GetDateTimeInt(Tm.GetYear(), Tm.GetMonth(),
01253         Tm.GetDay(), Tm.GetHour(), Tm.GetMin(), Tm.GetSec()) : 0;
01254 }
01255 
01256 TTm TTm::GetTmFromDateTimeInt(const uint& DateTimeInt) {
01257         if (DateTimeInt == 0) { return TTm(); }
01258         return TTm(TSecTm(DateTimeInt));
01259 }
01260 
01261 TSecTm TTm::GetSecTmFromDateTimeInt(const uint& DateTimeInt) {
01262         if (DateTimeInt == 0) { return TSecTm(); }
01263         return TSecTm(DateTimeInt);
01264 }
01265 
01266 uint TTm::KeepMonthInDateTimeInt(const uint& DateTimeInt) {
01267         EAssert(DateTimeInt != 0);
01268         TSecTm SecTm(DateTimeInt);
01269         return GetDateTimeInt(2000, SecTm.GetMonthN(), 1);
01270 }
01271 
01272 uint TTm::KeepDayInDateTimeInt(const uint& DateTimeInt) {
01273         EAssert(DateTimeInt != 0);
01274         TSecTm SecTm(DateTimeInt);
01275         return GetDateTimeInt(2000, 1, SecTm.GetDayN());
01276 }
01277 
01278 uint TTm::KeepHourInDateTimeInt(const uint& DateTimeInt) {
01279         EAssert(DateTimeInt != 0);
01280         TSecTm SecTm(DateTimeInt);
01281         return GetDateTimeInt(2000, 1, 1, SecTm.GetHourN());
01282 }
01283 
01285 // Time-Profiler - poor-man's profiler
01286 int TTmProfiler::AddTimer(const TStr& TimerNm) { 
01287         MxNmLen = TInt::GetMx(MxNmLen, TimerNm.Len());
01288         return TimerH.AddKey(TimerNm); 
01289 }
01290 
01291 void TTmProfiler::ResetAll() {
01292     int TimerId = GetTimerIdFFirst();
01293         while (GetTimerIdFNext(TimerId)) {
01294                 ResetTimer(TimerId);
01295         }
01296 }
01297 
01298 double TTmProfiler::GetTimerSumSec() const {
01299         double Sum = 0.0;
01300     int TimerId = GetTimerIdFFirst();
01301         while (GetTimerIdFNext(TimerId)) {
01302                 Sum += GetTimerSec(TimerId);
01303         }
01304     return Sum;
01305 }
01306 
01307 double TTmProfiler::GetTimerSec(const int& TimerId) const {
01308     return TimerH[TimerId].GetSec();
01309 }
01310 
01311 void TTmProfiler::PrintReport(const TStr& ProfileNm) const {
01312     const double TimerSumSec = GetTimerSumSec();
01313         printf("-- %s --\n", ProfileNm.CStr());
01314     printf("Sum: (%.2f sec):\n", TimerSumSec);
01315     int TimerId = GetTimerIdFFirst();
01316         while (GetTimerIdFNext(TimerId)) {
01317         // get timer name
01318         TStr TimerNm = GetTimerNm(TimerId);
01319         TimerNm = TStr::GetSpaceStr(TimerNm.Len() - MxNmLen) + TimerNm;
01320         // get timer time and precentage
01321         if (TimerSumSec > 0.0) {
01322             const double TimerSec = GetTimerSec(TimerId);
01323             const double TimerPerc =  TimerSec / TimerSumSec * 100.0;
01324             printf(" %s: %.2fs [%.2f%%]\n", TimerNm.CStr(), TimerSec, TimerPerc);
01325         } else {
01326             printf(" %s: -\n", TimerNm.CStr());
01327         }
01328     }
01329         printf("--\n");
01330 }