1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 To contact the author: codeworker@free.fr 20 */ 21 22 #ifdef WIN32 23 #pragma warning (disable : 4786) 24 #endif 25 26 #include <stdio.h> 27 #include <math.h> 28 #include <time.h> 29 30 #ifdef WIN32 31 # include <windows.h> 32 #endif 33 34 #include "UtlException.h" 35 #include "UtlDate.h" 36 #include "UtlString.h" 37 38 const double WINGZ_INFINITY = 1.0e300; 39 const int INFINITE_YEAR = 2000000000; 40 41 namespace CodeWorker { 42 class UtlInternalDate { 43 public: 44 static const char* _tsWeekDays[7]; 45 static const char* _tsMonths[12]; 46 static int _tNbDays[12]; 47 48 private: 49 int _iDay; 50 int _iMonth; 51 int _iYear; 52 int _iHour; 53 int _iMin; 54 int _iSec; 55 int _iMillis; 56 std::string _sComment; 57 58 private: formatInteger(int iNumber,unsigned int iDigits)59 static std::string formatInteger(int iNumber, unsigned int iDigits) { 60 char sNumber[32]; 61 sprintf(sNumber, "%d", iNumber); 62 std::string sResult = sNumber; 63 while (sResult.size() < iDigits) sResult = "0" + sResult; 64 return sResult; 65 } 66 67 public: UtlInternalDate()68 UtlInternalDate() { 69 #ifdef WIN32 70 SYSTEMTIME mySystemTime; 71 GetLocalTime(&mySystemTime); 72 _iDay = mySystemTime.wDay; 73 _iMonth = mySystemTime.wMonth; 74 _iYear = mySystemTime.wYear; 75 _iHour = mySystemTime.wHour; 76 _iMin = mySystemTime.wMinute; 77 _iSec = mySystemTime.wSecond; 78 _iMillis = mySystemTime.wMilliseconds; 79 #else 80 time_t timeInSecSince1970; 81 time(&timeInSecSince1970); 82 struct tm* today; 83 struct tm xTIME; 84 today = localtime_r(&timeInSecSince1970, &xTIME); 85 _iDay = today->tm_mday; 86 _iMonth = today->tm_mon + 1; 87 _iYear = today->tm_year + 1900; 88 _iHour = today->tm_hour; 89 _iMin = today->tm_min; 90 _iSec = today->tm_sec; 91 _iMillis = 0; 92 #endif 93 } UtlInternalDate(double dWINGZDate)94 UtlInternalDate(double dWINGZDate) { 95 setWINGZDate(dWINGZDate); 96 } UtlInternalDate(int iWinfrontDate)97 UtlInternalDate(int iWinfrontDate) { 98 setWinfrontDate(iWinfrontDate); 99 } UtlInternalDate(int iDay,int iMonth,int iYear,int iHour,int iMin,int iSec,int iMillis,const std::string & sComment)100 UtlInternalDate(int iDay, int iMonth, int iYear, int iHour, int iMin, int iSec, int iMillis, const std::string& sComment) : _iDay(iDay), _iMonth(iMonth), _iYear(iYear), _iHour(iHour), _iMin(iMin), _iSec(iSec), _iMillis(iMillis), _sComment(sComment) {} ~UtlInternalDate()101 virtual ~UtlInternalDate() {} 102 copyInstance() const103 virtual UtlInternalDate* copyInstance() const { return new UtlInternalDate(_iDay, _iMonth, _iYear, _iHour, _iMin, _iSec, _iMillis, _sComment); } 104 isInfinite() const105 bool isInfinite() const { 106 return (getYear() >= INFINITE_YEAR); 107 } 108 getComment() const109 const std::string& getComment() const { return _sComment; } setComment(const std::string & sComment)110 void setComment(const std::string& sComment) { _sComment = sComment; } 111 isAFixedDate() const112 virtual bool isAFixedDate() const { return true; } isAVariableDate() const113 virtual bool isAVariableDate() const { return false; } 114 getWeekDay() const115 virtual int getWeekDay() const { return (getDayWINGZDate() + 6) % 7; } getDay() const116 virtual int getDay() const { return _iDay; } getMonth() const117 virtual int getMonth() const { return _iMonth; } getYear() const118 virtual int getYear() const { return _iYear; } 119 setDay(int iDay)120 virtual void setDay(int iDay) { _iDay = iDay; } setMonth(int iMonth)121 virtual void setMonth(int iMonth) { _iMonth = iMonth; } setYear(int iYear)122 virtual void setYear(int iYear) { _iYear = iYear; } 123 addDay(int iDay)124 void addDay(int iDay) { 125 _iDay += iDay; 126 if (_iDay > 0) { 127 do { 128 int iNbDays = getNbDaysInMonth(_iMonth, _iYear); 129 if (_iDay > iNbDays) { 130 _iDay -= iNbDays; 131 _iMonth++; 132 if (_iMonth > 12) { 133 _iMonth = 1; 134 _iYear++; 135 } 136 } else break; 137 } while (true); 138 } else { 139 while (_iDay < 1) { 140 _iMonth--; 141 if (_iMonth <= 0) { 142 _iMonth = 12; 143 _iYear--; 144 } 145 int iNbDays = getNbDaysInMonth(_iMonth, _iYear); 146 _iDay += iNbDays; 147 } 148 } 149 } 150 addMonth(int iMonth)151 void addMonth(int iMonth) { 152 _iMonth += iMonth; 153 if (_iMonth <= 0) { 154 _iYear += ((_iMonth - 1) / 12) - 1; 155 _iMonth = (12 - ((1-_iMonth)%12))%12; 156 } else { 157 _iYear += ((_iMonth - 1) / 12); 158 _iMonth = (_iMonth - 1) % 12; 159 } 160 _iMonth++; 161 int iDaysOfMonth = getNbDaysInMonth(_iMonth, _iYear); 162 if (iDaysOfMonth < _iDay) _iDay = iDaysOfMonth; 163 } 164 addYear(int iYear)165 void addYear(int iYear) { 166 _iYear += iYear; 167 int iDaysOfMonth = getNbDaysInMonth(_iMonth, _iYear); 168 if (iDaysOfMonth < _iDay) _iDay = iDaysOfMonth; 169 } 170 setTime(int iHour,int iMin,int iSec,int iMillis)171 void setTime(int iHour, int iMin, int iSec, int iMillis) { 172 _iHour = iHour; 173 _iMin = iMin; 174 _iSec = iSec; 175 _iMillis = iMillis; 176 } 177 getHour() const178 inline int getHour() const { return _iHour; } setHour(int iHour)179 inline void setHour(int iHour) { _iHour = iHour; } getMin() const180 inline int getMin() const { return _iMin; } setMin(int iMin)181 inline void setMin(int iMin) { _iMin = iMin; } getSec() const182 inline int getSec() const { return _iSec; } setSec(int iSec)183 inline void setSec(int iSec) { _iSec = iSec; } getMillis() const184 inline int getMillis() const { return _iMillis; } setMillis(int iMillis)185 inline void setMillis(int iMillis) { _iMillis = iMillis; } instanceOf(const char * pName)186 virtual bool instanceOf(const char *pName) { 187 if (!strcmp(pName, "UtlInternalDate") ) return true ; 188 else return false; 189 } 190 addHour(int iHour)191 void addHour(int iHour) { 192 _iHour += iHour; 193 int iNbDays = _iHour / 24; 194 _iHour = _iHour % 24; 195 if (_iHour < 0) { 196 _iHour += 24; 197 iNbDays--; 198 } 199 addDay(iNbDays); 200 } 201 addMin(int iMin)202 void addMin(int iMin) { 203 _iMin += iMin; 204 int iNbHours = _iMin / 60; 205 _iMin = _iMin % 60; 206 if (_iMin < 0) { 207 _iMin += 60; 208 iNbHours--; 209 } 210 addHour(iNbHours); 211 } 212 addSec(int iSec)213 void addSec(int iSec) { 214 _iSec += iSec; 215 int iNbMins = _iSec / 60; 216 _iSec = _iSec % 60; 217 if (_iSec < 0) { 218 _iSec += 60; 219 iNbMins--; 220 } 221 addMin(iNbMins); 222 } 223 addMillis(int iMillis)224 void addMillis(int iMillis) { 225 _iMillis += iMillis; 226 int iNbSecs = _iMillis / 1000; 227 _iMillis = _iMillis % 1000; 228 if (_iMillis < 0) { 229 _iMillis += 1000; 230 iNbSecs--; 231 } 232 addSec(iNbSecs); 233 } 234 isLastDayOfMonth() const235 virtual bool isLastDayOfMonth() const { 236 int iDaysOfMonth = getNbDaysInMonth(_iMonth, _iYear); 237 return (getDay() == iDaysOfMonth); 238 } 239 setLastDayOfMonth()240 virtual void setLastDayOfMonth() { 241 int iDaysOfMonth = getNbDaysInMonth(_iMonth, _iYear); 242 setDay(iDaysOfMonth); 243 } 244 getString() const245 virtual std::string getString() const { 246 char tcString[32]; 247 std::string sMonth = _tsMonths[_iMonth - 1]; 248 sMonth = sMonth.substr(0, 3); 249 if ((_iHour > 0) || (_iMin > 0) || (_iSec > 0) || (_iMillis > 0)) { 250 sprintf(tcString, "%02d%s%d %02d:%02d:%02d.%03d", _iDay, sMonth.c_str(), _iYear, _iHour, _iMin, _iSec, _iMillis); 251 } else { 252 sprintf(tcString, "%02d%s%d", _iDay, sMonth.c_str(), _iYear); 253 } 254 return tcString; 255 } 256 getMCLDate() const257 std::string getMCLDate() const { 258 char sMCLString[16]; 259 std::string sMonth = _tsMonths[_iMonth - 1]; 260 sMonth = sMonth.substr(0, 3); 261 sprintf(sMCLString, "%d%s%d", _iDay, sMonth.c_str(), _iYear); 262 return sMCLString; 263 } 264 getFormattedDate(const std::string & sFormat) const265 std::string getFormattedDate(const std::string& sFormat) const { 266 std::string sDate; 267 std::string::size_type i = 0; 268 while (i < sFormat.size()) { 269 if (sFormat[i] == '%') { 270 i++; 271 switch(sFormat[i]) { 272 case 'Y': sDate += formatInteger(_iYear, 4);break; 273 case 'y': sDate += formatInteger(_iYear % 100, 2);break; 274 case 'b': sDate += std::string(_tsMonths[_iMonth - 1]).substr(0, 3);break; 275 case 'B': sDate += _tsMonths[_iMonth - 1];break; 276 case 'm': sDate += formatInteger(_iMonth, 2);break; 277 case 'd': sDate += formatInteger(_iDay, 2);break; 278 case 'e': sDate += formatInteger(_iDay, 1);break; 279 case 't': { 280 char sNumber[300]; 281 double dWingz = getWINGZDate(); 282 if (dWingz == floor(dWingz)) sprintf(sNumber, "%d", (int) dWingz); 283 else sprintf(sNumber, "%f", dWingz); 284 sDate += sNumber; 285 break; 286 } 287 case 'w': sDate += formatInteger(getWeekDay(), 1);break; 288 case 'W': sDate += std::string(_tsWeekDays[getWeekDay()]);break; 289 case 'H': sDate += formatInteger(_iHour, 2);break; 290 case 'I': sDate += formatInteger(((_iHour > 12) ? _iHour - 12: _iHour), 2);break; 291 case 'p': sDate += ((_iHour > 12) ? "PM": "AM");break; 292 case 'Q': 293 sDate += formatInteger(_iYear, 4) + "-" + formatInteger(_iMonth, 2) + "-" + formatInteger(_iDay, 2) + " " + formatInteger(_iHour, 2) + ":" + formatInteger(_iMin, 2) + ":" + formatInteger(_iSec, 2); 294 if (_iMillis != 0) sDate += "." + formatInteger(_iMillis, 3); 295 break; 296 case 'M': sDate += formatInteger(_iMin, 2);break; 297 case 'S': sDate += formatInteger(_iSec, 2);break; 298 case 'L': sDate += formatInteger(_iMillis, 3);break; 299 case '%': sDate += "%";break; 300 case 'j': 301 { 302 int iDays = _iDay; 303 int iMonth = 1; 304 while (iMonth < _iMonth) iDays += getNbDaysInMonth(iMonth++, _iYear); 305 sDate += formatInteger(iDays, 1); 306 } 307 break; 308 case 'D': sDate += formatInteger(_iMonth, 2) + "/" + formatInteger(_iDay, 2) + "/" + formatInteger(_iYear % 100, 2);break; 309 case 'r': sDate += formatInteger(((_iHour > 12) ? _iHour - 12: _iHour), 2) + ":" + formatInteger(_iMin, 2) + ":" + formatInteger(_iSec, 2) + ((_iHour > 12) ? " PM": " AM");break; 310 case 'T': sDate += formatInteger(_iHour, 2) + ":" + formatInteger(_iMin, 2) + ":" + formatInteger(_iSec, 2);break; 311 default: 312 throw UtlException("syntax error on date format \"" + sFormat + "\""); 313 } 314 } else sDate += sFormat[i]; 315 i++; 316 } 317 return sDate; 318 } 319 getDayWINGZDate() const320 int getDayWINGZDate() const { return (int) getWINGZDate(); } 321 getWINGZDate() const322 double getWINGZDate() const { 323 if (isInfinite()) return WINGZ_INFINITY; 324 int iWingzDate = 2; 325 int iDateYear = getYear(); 326 if (iDateYear < 1900) return -1.0; 327 328 int iYear = 1900; 329 while (iYear < iDateYear) { 330 bool b366 = isLeapYear(iYear); 331 if (b366) iWingzDate += 366; 332 else iWingzDate += 365; 333 iYear++; 334 } 335 336 int iMonth = 1; 337 int iDateMonth = getMonth(); 338 while (iMonth < iDateMonth) { 339 int iNbDays = getNbDaysInMonth(iMonth, iYear); 340 iWingzDate += iNbDays; 341 iMonth++; 342 } 343 344 iWingzDate += (getDay() - 1); 345 double dMillis = _iMillis; 346 double dSeconds = (dMillis / 1000.0) + _iSec + 60 * (_iMin + 60*_iHour); 347 double dWingzDate = iWingzDate; 348 dWingzDate += dSeconds / 86400.0; 349 350 return dWingzDate; 351 } 352 setWINGZDate(double dWINGZDate)353 void setWINGZDate(double dWINGZDate) { 354 if (dWINGZDate == WINGZ_INFINITY) { 355 _iYear = INFINITE_YEAR; 356 } else { 357 _iDay = 1; 358 _iMonth = 1; 359 _iYear =1900; 360 addDay((int) (dWINGZDate - 2.0)); 361 double dRemaining = dWINGZDate - floor(dWINGZDate); 362 dRemaining *= 24.0; 363 double dFloor = floor(dRemaining); 364 _iHour = (int) dFloor; 365 dRemaining -= dFloor; 366 dRemaining *= 60.0; 367 dFloor = floor(dRemaining); 368 _iMin = (int) dFloor; 369 dRemaining -= dFloor; 370 dRemaining *= 60.0; 371 dFloor = floor(dRemaining); 372 _iSec = (int) dFloor; 373 dRemaining -= dFloor; 374 dRemaining *= 1000.0; 375 double dMillis = dRemaining; 376 _iMillis = (int) floor(dMillis); 377 if (dMillis - _iMillis >= 0.5) { 378 _iMillis++; 379 if (_iMillis == 1000) { 380 _iMillis = 0; 381 _iSec++; 382 if (_iSec == 60) { 383 _iSec = 0; 384 _iMin++; 385 if (_iMin == 60) { 386 _iMin = 0; 387 _iHour++; 388 if (_iHour == 24) { 389 _iHour = 0; 390 _iDay++; 391 if (getNbDaysInMonth(_iMonth, _iYear) < _iDay) { 392 _iDay = 1; 393 _iMonth++; 394 if (_iMonth > 12) { 395 _iMonth = 1; 396 _iYear++; 397 } 398 } 399 } 400 } 401 } 402 } 403 } 404 } 405 } 406 getWinfrontDate() const407 int getWinfrontDate() const { 408 return getYear() * 10000 + getMonth() * 100 + getDay(); 409 } 410 setWinfrontDate(int iWinfrontDate)411 void setWinfrontDate(int iWinfrontDate) { 412 setDay(iWinfrontDate % 100); 413 iWinfrontDate /= 100; 414 setMonth(iWinfrontDate % 100); 415 iWinfrontDate /= 100; 416 setYear(iWinfrontDate); 417 _iHour = 0; 418 _iMin = 0; 419 _iSec = 0; 420 _iMillis = 0; 421 } 422 getNbDaysInMonth(int iMonth,int iYear)423 static int getNbDaysInMonth(int iMonth, int iYear) { 424 int iNbDays = _tNbDays[iMonth - 1]; 425 if ((iMonth == 2) && isLeapYear(iYear)) iNbDays = 29; 426 return iNbDays; 427 } 428 isLeapYear(int iYear)429 static bool isLeapYear(int iYear) { return (iYear%4 == 0) && ((iYear%100 != 0) || (iYear%400 == 0)); } 430 }; 431 432 433 const char* UtlInternalDate::_tsWeekDays[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}; 434 const char* UtlInternalDate::_tsMonths[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}; 435 int UtlInternalDate::_tNbDays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 436 437 class UtlVariableDate : public UtlInternalDate { 438 private: 439 int _iFrequency; 440 char _cUnit; 441 442 public: UtlVariableDate(int iFrequency,char cUnit)443 UtlVariableDate(int iFrequency, char cUnit) : _iFrequency(iFrequency), _cUnit(cUnit) { 444 char sErrorMessage[128]; 445 switch(_cUnit) { 446 case 'd': 447 case 'w': 448 case 'm': 449 case 'y': 450 _cUnit -= ' '; 451 case 'D': 452 case 'W': 453 case 'M': 454 case 'Y': 455 break; 456 default: 457 sprintf(sErrorMessage, "Undefined unit of variable date: '%c' for \"%d%c\"", cUnit, iFrequency, cUnit); 458 throw UtlException(sErrorMessage); 459 } 460 } ~UtlVariableDate()461 virtual ~UtlVariableDate() {} 462 copyInstance() const463 virtual UtlInternalDate* copyInstance() const { return new UtlVariableDate(_iFrequency, _cUnit); } 464 isAFixedDate() const465 virtual bool isAFixedDate() const { return false; } isAVariableDate() const466 virtual bool isAVariableDate() const { return true; } 467 getWeekDay() const468 virtual int getWeekDay() const { 469 UtlInternalDate date(UtlInternalDate::getDay(), UtlInternalDate::getMonth(), UtlInternalDate::getYear(), 0, 0, 0, 0, ""); 470 switch (_cUnit) { 471 case 'D': date.addDay(_iFrequency);break; 472 case 'W': date.addDay(7*_iFrequency);break; 473 case 'M': date.addMonth(_iFrequency);break; 474 case 'Y': date.addYear(_iFrequency);break; 475 } 476 return date.getWeekDay(); 477 } 478 getDay() const479 virtual int getDay() const { 480 UtlInternalDate date(UtlInternalDate::getDay(), UtlInternalDate::getMonth(), UtlInternalDate::getYear(), 0, 0, 0, 0, ""); 481 switch (_cUnit) { 482 case 'D': date.addDay(_iFrequency);break; 483 case 'W': date.addDay(7*_iFrequency);break; 484 case 'M': date.addMonth(_iFrequency);break; 485 case 'Y': date.addYear(_iFrequency);break; 486 } 487 return date.getDay(); 488 } 489 getMonth() const490 virtual int getMonth() const { 491 UtlInternalDate date(UtlInternalDate::getDay(), UtlInternalDate::getMonth(), UtlInternalDate::getYear(), 0, 0, 0, 0, ""); 492 switch (_cUnit) { 493 case 'D': date.addDay(_iFrequency);break; 494 case 'W': date.addDay(7*_iFrequency);break; 495 case 'M': date.addMonth(_iFrequency);break; 496 case 'Y': date.addYear(_iFrequency);break; 497 } 498 return date.getMonth(); 499 } 500 getYear() const501 virtual int getYear() const { 502 UtlInternalDate date(UtlInternalDate::getDay(), UtlInternalDate::getMonth(), UtlInternalDate::getYear(), 0, 0, 0, 0, ""); 503 switch (_cUnit) { 504 case 'D': date.addDay(_iFrequency);break; 505 case 'W': date.addDay(7*_iFrequency);break; 506 case 'M': date.addMonth(_iFrequency);break; 507 case 'Y': date.addYear(_iFrequency);break; 508 } 509 return date.getYear(); 510 } 511 getString() const512 virtual std::string getString() const { 513 char sString[16]; 514 sprintf(sString, "%d%c", _iFrequency, _cUnit); 515 return sString; 516 } 517 getFrequency() const518 virtual int getFrequency() const { 519 return _iFrequency ; 520 } 521 getUnit() const522 virtual char getUnit() const { 523 return _cUnit ; 524 } 525 instanceOf(const char * pName)526 virtual bool instanceOf(const char *pName) { 527 if (!strcmp(pName, "UtlVariableDate") ) return true ; 528 else return false; 529 } 530 }; 531 532 UtlDate()533 UtlDate::UtlDate() { 534 _pInternalDate = new UtlInternalDate(); 535 } 536 UtlDate(const UtlDate & date)537 UtlDate::UtlDate(const UtlDate& date) { 538 if (date._pInternalDate == NULL) _pInternalDate = NULL; 539 else _pInternalDate = date._pInternalDate->copyInstance(); 540 } 541 UtlDate(double dWINGZDate)542 UtlDate::UtlDate(double dWINGZDate) { 543 if (dWINGZDate <= 0.0) _pInternalDate = NULL; 544 else _pInternalDate = new UtlInternalDate(dWINGZDate); 545 } 546 UtlDate(int iWinfrontDate)547 UtlDate::UtlDate(int iWinfrontDate) { 548 _pInternalDate = new UtlInternalDate(iWinfrontDate); 549 } 550 UtlDate(int iDay,int iMonth,int iYear,int iHour,int iMin,int iSec,int iMillis)551 UtlDate::UtlDate(int iDay, int iMonth, int iYear, int iHour, int iMin, int iSec, int iMillis) { 552 _pInternalDate = new UtlInternalDate(iDay, iMonth, iYear, iHour, iMin, iSec, iMillis, ""); 553 } 554 UtlDate(int iFrequency,char cUnit)555 UtlDate::UtlDate(int iFrequency, char cUnit) { 556 _pInternalDate = new UtlVariableDate(iFrequency, cUnit); 557 } 558 ~UtlDate()559 UtlDate::~UtlDate() { 560 delete _pInternalDate; 561 } 562 isNull() const563 bool UtlDate::isNull() const { 564 return (_pInternalDate == NULL); 565 } 566 nullify()567 void UtlDate::nullify() { 568 if (_pInternalDate != NULL) delete _pInternalDate; 569 _pInternalDate = NULL; 570 } 571 isInfinite() const572 bool UtlDate::isInfinite() const { 573 if (_pInternalDate == NULL) return false; 574 return _pInternalDate->isInfinite(); 575 } 576 infinity()577 void UtlDate::infinity() { 578 if (_pInternalDate != NULL) delete _pInternalDate; 579 _pInternalDate = new UtlInternalDate(WINGZ_INFINITY); 580 } 581 copyInstance() const582 UtlDate* UtlDate::copyInstance() const { 583 return new UtlDate(*this); 584 } 585 operator =(const UtlDate & date)586 UtlDate& UtlDate::operator =(const UtlDate& date) { 587 if (&date == this) throw UtlException("a date can't assign itself"); 588 if (_pInternalDate != NULL) delete _pInternalDate; 589 if (date._pInternalDate == NULL) _pInternalDate = NULL; 590 else _pInternalDate = date._pInternalDate->copyInstance(); 591 return *this; 592 } 593 operator <(const UtlDate & date) const594 bool UtlDate::operator <(const UtlDate& date) const { 595 if (isNull() || date.isNull()) return false; 596 int iYear1 = getYear(); 597 int iYear2 = date.getYear(); 598 if (iYear1 == iYear2) { 599 int iMonth1 = getMonth(); 600 int iMonth2 = date.getMonth(); 601 if (iMonth1 != iMonth2) return (iMonth1 < iMonth2); 602 int iDay1 = getDay(); 603 int iDay2 = date.getDay(); 604 if (iDay1 != iDay2) return (iDay1 < iDay2); 605 int iHour1 = getHour(); 606 int iHour2 = date.getHour(); 607 if (iHour1 != iHour2) return (iHour1 < iHour2); 608 int iMin1 = getMin(); 609 int iMin2 = date.getMin(); 610 if (iMin1 != iMin2) return (iMin1 < iMin2); 611 int iSec1 = getSec(); 612 int iSec2 = date.getSec(); 613 if (iSec1 != iSec2) return (iSec1 < iSec2); 614 } else return (iYear1 < iYear2); 615 return getMillis() < date.getMillis(); 616 } 617 operator <=(const UtlDate & date) const618 bool UtlDate::operator <=(const UtlDate& date) const { 619 if (isNull() || date.isNull()) return false; 620 int iYear1 = getYear(); 621 int iYear2 = date.getYear(); 622 if (iYear1 == iYear2) { 623 int iMonth1 = getMonth(); 624 int iMonth2 = date.getMonth(); 625 if (iMonth1 != iMonth2) return (iMonth1 < iMonth2); 626 int iDay1 = getDay(); 627 int iDay2 = date.getDay(); 628 if (iDay1 != iDay2) return (iDay1 < iDay2); 629 int iHour1 = getHour(); 630 int iHour2 = date.getHour(); 631 if (iHour1 != iHour2) return (iHour1 < iHour2); 632 int iMin1 = getMin(); 633 int iMin2 = date.getMin(); 634 if (iMin1 != iMin2) return (iMin1 < iMin2); 635 int iSec1 = getSec(); 636 int iSec2 = date.getSec(); 637 if (iSec1 != iSec2) return (iSec1 < iSec2); 638 } else return (iYear1 < iYear2); 639 return getMillis() <= date.getMillis(); 640 } 641 operator ==(const UtlDate & date) const642 bool UtlDate::operator ==(const UtlDate& date) const { 643 if (isNull() || date.isNull()) return false; 644 return (getDay() == date.getDay()) && (getMonth() == date.getMonth()) && (getYear() == date.getYear()) && (getHour() == date.getHour()) && (getMin() == date.getMin()) && (getSec() == date.getSec()) && (getMillis() == date.getMillis()); 645 } 646 operator !=(const UtlDate & date) const647 bool UtlDate::operator !=(const UtlDate& date) const { 648 if (isNull() || date.isNull()) return false; 649 return (getDay() != date.getDay()) || (getMonth() != date.getMonth()) || (getYear() != date.getYear()) || (getHour() != date.getHour()) || (getMin() != date.getMin()) || (getSec() != date.getSec()) || (getMillis() != date.getMillis()); 650 } 651 operator >=(const UtlDate & date) const652 bool UtlDate::operator >=(const UtlDate& date) const { 653 if (isNull() || date.isNull()) return false; 654 int iYear1 = getYear(); 655 int iYear2 = date.getYear(); 656 if (iYear1 == iYear2) { 657 int iMonth1 = getMonth(); 658 int iMonth2 = date.getMonth(); 659 if (iMonth1 != iMonth2) return (iMonth1 > iMonth2); 660 int iDay1 = getDay(); 661 int iDay2 = date.getDay(); 662 if (iDay1 != iDay2) return (iDay1 > iDay2); 663 int iHour1 = getHour(); 664 int iHour2 = date.getHour(); 665 if (iHour1 != iHour2) return (iHour1 > iHour2); 666 int iMin1 = getMin(); 667 int iMin2 = date.getMin(); 668 if (iMin1 != iMin2) return (iMin1 > iMin2); 669 int iSec1 = getSec(); 670 int iSec2 = date.getSec(); 671 if (iSec1 != iSec2) return (iSec1 > iSec2); 672 } else return (iYear1 > iYear2); 673 return getMillis() >= date.getMillis(); 674 } 675 operator >(const UtlDate & date) const676 bool UtlDate::operator >(const UtlDate& date) const { 677 if (isNull() || date.isNull()) return false; 678 int iYear1 = getYear(); 679 int iYear2 = date.getYear(); 680 if (iYear1 == iYear2) { 681 int iMonth1 = getMonth(); 682 int iMonth2 = date.getMonth(); 683 if (iMonth1 != iMonth2) return (iMonth1 > iMonth2); 684 int iDay1 = getDay(); 685 int iDay2 = date.getDay(); 686 if (iDay1 != iDay2) return (iDay1 > iDay2); 687 int iHour1 = getHour(); 688 int iHour2 = date.getHour(); 689 if (iHour1 != iHour2) return (iHour1 > iHour2); 690 int iMin1 = getMin(); 691 int iMin2 = date.getMin(); 692 if (iMin1 != iMin2) return (iMin1 > iMin2); 693 int iSec1 = getSec(); 694 int iSec2 = date.getSec(); 695 if (iSec1 != iSec2) return (iSec1 > iSec2); 696 } else return (iYear1 > iYear2); 697 return getMillis() > date.getMillis(); 698 } 699 operator -(const UtlDate & date) const700 double UtlDate::operator -(const UtlDate& date) const { 701 if (isNull() || date.isNull()) return 0.0; 702 return getWINGZDate() - date.getWINGZDate(); 703 } 704 today()705 void UtlDate::today() { 706 if (_pInternalDate != NULL) delete _pInternalDate; 707 _pInternalDate = new UtlInternalDate(); 708 } 709 isAFixedDate() const710 bool UtlDate::isAFixedDate() const { 711 if (isNull()) return false; 712 return _pInternalDate->isAFixedDate(); 713 } isAVariableDate() const714 bool UtlDate::isAVariableDate() const { 715 if (isNull()) return false; 716 return _pInternalDate->isAVariableDate(); 717 } 718 getDay() const719 int UtlDate::getDay() const { 720 return _pInternalDate->getDay(); 721 } 722 getMonth() const723 int UtlDate::getMonth() const { 724 return _pInternalDate->getMonth(); 725 } 726 getYear() const727 int UtlDate::getYear() const { 728 return _pInternalDate->getYear(); 729 } 730 setDay(int iDay)731 void UtlDate::setDay(int iDay) { 732 _pInternalDate->setDay(iDay); 733 } 734 setMonth(int iMonth)735 void UtlDate::setMonth(int iMonth) { 736 _pInternalDate->setMonth(iMonth); 737 } 738 setYear(int iYear)739 void UtlDate::setYear(int iYear) { 740 _pInternalDate->setYear(iYear); 741 } 742 addDay(int iDay)743 void UtlDate::addDay(int iDay) { 744 _pInternalDate->addDay(iDay); 745 } 746 addMonth(int iMonth)747 void UtlDate::addMonth(int iMonth) { 748 _pInternalDate->addMonth(iMonth); 749 } 750 addYear(int iYear)751 void UtlDate::addYear(int iYear) { 752 _pInternalDate->addYear(iYear); 753 } 754 getHour() const755 int UtlDate::getHour() const { 756 return _pInternalDate->getHour(); 757 } 758 getMin() const759 int UtlDate::getMin() const { 760 return _pInternalDate->getMin(); 761 } 762 getSec() const763 int UtlDate::getSec() const { 764 return _pInternalDate->getSec(); 765 } 766 getMillis() const767 int UtlDate::getMillis() const { 768 return _pInternalDate->getMillis(); 769 } 770 isLastDayOfMonth() const771 bool UtlDate::isLastDayOfMonth() const { 772 return _pInternalDate->isLastDayOfMonth(); 773 } 774 setLastDayOfMonth()775 void UtlDate::setLastDayOfMonth() { 776 _pInternalDate->setLastDayOfMonth(); 777 } 778 ignoreHours()779 void UtlDate::ignoreHours() { 780 _pInternalDate->setHour(0); 781 _pInternalDate->setMin(0); 782 _pInternalDate->setSec(0); 783 _pInternalDate->setMillis(0); 784 } 785 setTime(int iHour,int iMin,int iSec,int iMillis)786 void UtlDate::setTime(int iHour, int iMin, int iSec, int iMillis) { 787 _pInternalDate->setTime(iHour, iMin, iSec, iMillis); 788 } 789 compareTime(const UtlDate & date) const790 int UtlDate::compareTime(const UtlDate& date) const { 791 int iHour1 = getHour(); 792 int iHour2 = date.getHour(); 793 if (iHour1 != iHour2) return (iHour1 - iHour2); 794 int iMin1 = getMin(); 795 int iMin2 = date.getMin(); 796 if (iMin1 != iMin2) return (iMin1 - iMin2); 797 int iSec1 = getSec(); 798 int iSec2 = date.getSec(); 799 if (iSec1 != iSec2) return (iSec1 - iSec2); 800 return getMillis() - date.getMillis(); 801 } 802 setHour(int iHour)803 void UtlDate::setHour(int iHour) { 804 _pInternalDate->setHour(iHour); 805 } 806 setMin(int iMin)807 void UtlDate::setMin(int iMin) { 808 _pInternalDate->setMin(iMin); 809 } 810 setSec(int iSec)811 void UtlDate::setSec(int iSec) { 812 _pInternalDate->setSec(iSec); 813 } 814 setMillis(int iMillis)815 void UtlDate::setMillis(int iMillis) { 816 _pInternalDate->setMillis(iMillis); 817 } 818 addHour(int iHour)819 void UtlDate::addHour(int iHour) { 820 _pInternalDate->addHour(iHour); 821 } 822 addMin(int iMin)823 void UtlDate::addMin(int iMin) { 824 _pInternalDate->addMin(iMin); 825 } 826 addSec(int iSec)827 void UtlDate::addSec(int iSec) { 828 _pInternalDate->addSec(iSec); 829 } 830 addMillis(int iMillis)831 void UtlDate::addMillis(int iMillis) { 832 _pInternalDate->addMillis(iMillis); 833 } 834 getString() const835 std::string UtlDate::getString() const { 836 if (isNull()) return "undated"; 837 return _pInternalDate->getString(); 838 } 839 getMCLDate() const840 std::string UtlDate::getMCLDate() const { 841 if (isNull()) return "undated"; 842 return _pInternalDate->getMCLDate(); 843 } 844 getFormattedDate(const std::string & sFormat) const845 std::string UtlDate::getFormattedDate(const std::string& sFormat) const { 846 return _pInternalDate->getFormattedDate(sFormat); 847 } 848 getDateFromFormat(const std::string & sDate,const std::string & sFormat)849 UtlDate UtlDate::getDateFromFormat(const std::string& sDate, const std::string& sFormat) { 850 UtlDate today; 851 today.ignoreHours(); 852 std::string::size_type i = 0; 853 std::string::size_type j = 0; 854 std::string sNumber; 855 while ((i < sFormat.size()) && (j < sDate.size())) { 856 if (sFormat[i] == '%') { 857 i++; 858 switch(sFormat[i]) { 859 case 'Y': 860 if (j + 4 > sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Y'"); 861 sNumber = sDate.substr(j, 4); 862 today.setYear(atoi(sNumber.c_str())); 863 j += 4; 864 break; 865 case 'y': 866 { 867 int iYear = getInteger(sDate, 2, j); 868 int iTodayShortYear = today.getYear() % 100; 869 if (iTodayShortYear > iYear) { 870 if (iTodayShortYear - iYear > 50) iYear += 100; 871 } else { 872 if (iYear - iTodayShortYear > 50) iYear -= 100; 873 } 874 iYear += (today.getYear() - iTodayShortYear); 875 today.setYear(iYear); 876 } 877 break; 878 case 'm': 879 today.setMonth(getInteger(sDate, 2, j)); 880 if ((today.getMonth() < 1) || (today.getMonth() > 12)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%m'"); 881 break; 882 case 'd': 883 today.setDay(getInteger(sDate, 2, j)); 884 if ((today.getDay() < 1) || (today.getDay() > 31)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%d'"); 885 break; 886 case 'H': 887 today.setHour(getInteger(sDate, 2, j)); 888 if ((today.getHour() < 0) || (today.getHour() > 23)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%H'"); 889 break; 890 case 'I': 891 if (j + 2 > sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%I'"); 892 sNumber = sDate.substr(j, 2); 893 today.setHour(atoi(sNumber.c_str())); 894 j += 2; 895 break; 896 case 'M': 897 today.setMin(getInteger(sDate, 2, j)); 898 if ((today.getMin() < 0) || (today.getMin() > 59)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%M'"); 899 break; 900 case 'S': 901 today.setSec(getInteger(sDate, 2, j)); 902 if ((today.getSec() < 0) || (today.getSec() > 59)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%S'"); 903 break; 904 case '%': break; 905 case 'D': 906 today.setMonth(getInteger(sDate, 2, j)); 907 if ((today.getMonth() < 1) || (today.getMonth() > 12)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%D -> %m'"); 908 if (sDate[j++] != '/') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%D -> '/' expected after %m'"); 909 today.setDay(getInteger(sDate, 2, j)); 910 if ((today.getDay() < 1) || (today.getDay() > 31)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%D -> %d'"); 911 if (sDate[j++] != '/') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%D -> '/' expected after %d'"); 912 { 913 int iYear = getInteger(sDate, 2, j); 914 if (iYear > 70) iYear += 1900; 915 else iYear += 2000; 916 today.setYear(iYear); 917 } 918 break; 919 case 'Q': 920 today.setYear(getInteger(sDate, 4, j)); 921 if (sDate[j++] != '-') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> '-' expected after %Y'"); 922 today.setMonth(getInteger(sDate, 2, j)); 923 if ((today.getMonth() < 1) || (today.getMonth() > 12)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> %m'"); 924 if (sDate[j++] != '-') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> '-' expected after %m'"); 925 today.setDay(getInteger(sDate, 2, j)); 926 if ((today.getDay() < 1) || (today.getDay() > 31)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> %d'"); 927 if (sDate[j++] != ' ') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> ' ' expected after %d'"); 928 today.setHour(getInteger(sDate, 2, j)); 929 if ((today.getHour() < 0) || (today.getHour() > 23)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> %H'"); 930 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> ':' expected after %H'"); 931 today.setMin(getInteger(sDate, 2, j)); 932 if ((today.getMin() < 0) || (today.getMin() > 59)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> %M'"); 933 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> ':' expected after %M'"); 934 today.setSec(getInteger(sDate, 2, j)); 935 if ((today.getSec() < 0) || (today.getSec() > 59)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> %S'"); 936 if (sDate[j] != '.') break; 937 j++; 938 // Be careful! 939 // Continue in sequence on case '%L'! 940 case 'L': 941 // Be careful! 942 // Don't move this case label and don't insert anything before case '%Q' 943 { 944 if (j >= sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%L'"); 945 char a = sDate[j]; 946 if ((a < '0') || (a > '9')) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%L'"); 947 int iMillis = 0; 948 int iLoop = 0; 949 do { 950 iMillis = 10*iMillis + (a - '0'); 951 a = sDate[++j]; 952 } while ((++iLoop < 3) && (a >= '0') && (a <= '9')); 953 today.setMillis(iMillis); 954 } 955 break; 956 case 'b': 957 if (j + 3 > sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%b'"); 958 sNumber = sDate.substr(j, 3); 959 { 960 int k; 961 for (k = 0; k < 12; k++) if (strnicmp(UtlInternalDate::_tsMonths[k], sNumber, 3) == 0) break; 962 if (k >= 12) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%b' -> unknow month = '" + sNumber + "'"); 963 today.setMonth(k + 1); 964 } 965 j += 3; 966 break; 967 case 'B': 968 { 969 int k; 970 int iLength; 971 for (k = 0; k < 12; k++) { 972 iLength = strlen(UtlInternalDate::_tsMonths[k]); 973 if (j + iLength <= sDate.size()) { 974 if (strnicmp(UtlInternalDate::_tsMonths[k], sDate.c_str() + j, iLength) == 0) break; 975 } 976 } 977 if (k >= 12) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%B' -> unknow month = '" + sNumber + "'"); 978 today.setMonth(k + 1); 979 j += iLength; 980 } 981 break; 982 case 't': 983 today.setWINGZDate(getDouble(sDate, 300, j)); 984 break; 985 case 'T': 986 today.setHour(getInteger(sDate, 2, j)); 987 if ((today.getHour() < 0) || (today.getHour() > 23)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> %H'"); 988 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> ':' expected after %H'"); 989 today.setMin(getInteger(sDate, 2, j)); 990 if ((today.getMin() < 0) || (today.getMin() > 59)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> %M'"); 991 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> ':' expected after %M'"); 992 today.setSec(getInteger(sDate, 2, j)); 993 if ((today.getSec() < 0) || (today.getSec() > 59)) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> %S'"); 994 break; 995 case '|': 996 // nothing to do 997 break; 998 case 'a': 999 case 'A': 1000 case 'e': 1001 case 'j': 1002 case 'p': 1003 case 'r': 1004 case 'U': 1005 case 'w': 1006 throw UtlException("date format \"... " + std::string(sFormat.c_str() + (i-1)) + "' not implemented yet"); 1007 default: 1008 throw UtlException("syntax error on date format \"" + sFormat + "\" for '%" + sFormat[i] + "'"); 1009 } 1010 } else j++; 1011 i++; 1012 } 1013 if (i < sFormat.size()) { 1014 if ((sFormat[i] != '%') || (sFormat[i + 1] != '|')) { 1015 throw UtlException("date format \"" + sFormat + "\" not applied on \"" + sDate + "\" completely"); 1016 } 1017 } 1018 return today; 1019 } 1020 addDateFromFormat(const std::string & sFormat,const std::string & sDate)1021 void UtlDate::addDateFromFormat(const std::string& sFormat, const std::string& sDate) { 1022 std::string::size_type i = 0; 1023 std::string::size_type j = 0; 1024 std::string sNumber; 1025 while ((i < sFormat.size()) && (j < sDate.size())) { 1026 if (sFormat[i] == '%') { 1027 i++; 1028 int iSigned = ((sDate[j] == '-') ? 1 : 0); 1029 switch(sFormat[i]) { 1030 case 'Y': 1031 if (j + 4 + iSigned > sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Y'"); 1032 sNumber = sDate.substr(j, 4 + iSigned); 1033 addYear(atoi(sNumber.c_str())); 1034 j += 4 + iSigned; 1035 break; 1036 case 'y': 1037 addYear(getInteger(sDate, 2 + iSigned, j)); 1038 break; 1039 case 'm': 1040 addMonth(getInteger(sDate, 2 + iSigned, j)); 1041 break; 1042 case 'd': 1043 addDay(getInteger(sDate, 2 + iSigned, j)); 1044 break; 1045 case 'H': 1046 addHour(getInteger(sDate, 2 + iSigned, j)); 1047 break; 1048 case 'I': 1049 if (j + 2 + iSigned > sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%I'"); 1050 sNumber = sDate.substr(j, 2 + iSigned); 1051 addHour(atoi(sNumber.c_str())); 1052 j += 2 + iSigned; 1053 break; 1054 case 'M': 1055 addMin(getInteger(sDate, 2 + iSigned, j)); 1056 break; 1057 case 'S': 1058 addSec(getInteger(sDate, 2 + iSigned, j)); 1059 break; 1060 case '%': break; 1061 case 'D': 1062 addMonth(getInteger(sDate, 2 + iSigned, j)); 1063 if (sDate[j++] != '/') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%D -> '/' expected after %m'"); 1064 iSigned = ((sDate[j] == '-') ? 1 : 0); 1065 addDay(getInteger(sDate, 2 + iSigned, j)); 1066 if (sDate[j++] != '/') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%D -> '/' expected after %d'"); 1067 iSigned = ((sDate[j] == '-') ? 1 : 0); 1068 addYear(getInteger(sDate, 2 + iSigned, j)); 1069 break; 1070 case 'Q': 1071 addYear(getInteger(sDate, 4 + iSigned, j)); 1072 if (sDate[j++] != '-') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> '-' expected after %Y'"); 1073 iSigned = ((sDate[j] == '-') ? 1 : 0); 1074 addMonth(getInteger(sDate, 2 + iSigned, j)); 1075 if (sDate[j++] != '-') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> '-' expected after %m'"); 1076 iSigned = ((sDate[j] == '-') ? 1 : 0); 1077 addDay(getInteger(sDate, 2 + iSigned, j)); 1078 if (sDate[j++] != ' ') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> ' ' expected after %d'"); 1079 iSigned = ((sDate[j] == '-') ? 1 : 0); 1080 addHour(getInteger(sDate, 2 + iSigned, j)); 1081 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> ':' expected after %H'"); 1082 iSigned = ((sDate[j] == '-') ? 1 : 0); 1083 addMin(getInteger(sDate, 2 + iSigned, j)); 1084 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%Q -> ':' expected after %M'"); 1085 iSigned = ((sDate[j] == '-') ? 1 : 0); 1086 addSec(getInteger(sDate, 2 + iSigned, j)); 1087 if (sDate[j] != '.') break; 1088 j++; 1089 iSigned = ((sDate[j] == '-') ? 1 : 0); 1090 // Be careful! 1091 // Continue in sequence on case '%L'! 1092 case 'L': 1093 // Be careful! 1094 // Don't move this case label and don't insert anything before case '%Q' 1095 { 1096 if (iSigned != 0) j++; 1097 if (j >= sDate.size()) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%L'"); 1098 char a = sDate[j]; 1099 if ((a < '0') || (a > '9')) throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%L'"); 1100 int iMillis = 0; 1101 int iLoop = 0; 1102 do { 1103 iMillis = 10*iMillis + (a - '0'); 1104 a = sDate[++j]; 1105 } while ((++iLoop < 3) && (a >= '0') && (a <= '9')); 1106 if (iSigned != 0) iMillis = -iMillis; 1107 addMillis(iMillis); 1108 } 1109 break; 1110 case 't': 1111 setWINGZDate(getWINGZDate() + getDouble(sDate, 300, j)); 1112 break; 1113 case 'T': 1114 addHour(getInteger(sDate, 2 + iSigned, j)); 1115 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> ':' expected after %H'"); 1116 iSigned = ((sDate[j] == '-') ? 1 : 0); 1117 addMin(getInteger(sDate, 2 + iSigned, j)); 1118 if (sDate[j++] != ':') throw UtlException("syntax error on date format: format \"" + sFormat + "\" doesn't match with date '" + sDate + "' for '%T -> ':' expected after %M'"); 1119 iSigned = ((sDate[j] == '-') ? 1 : 0); 1120 addSec(getInteger(sDate, 2 + iSigned, j)); 1121 break; 1122 case '|': 1123 // nothing to do 1124 break; 1125 case 'a': 1126 case 'A': 1127 case 'b': 1128 case 'B': 1129 case 'e': 1130 case 'j': 1131 case 'p': 1132 case 'r': 1133 case 'U': 1134 case 'w': 1135 throw UtlException("date format \"... " + std::string(sFormat.c_str() + (i-1)) + "' has no sense here"); 1136 default: 1137 throw UtlException("syntax error on date format \"" + sFormat + "\" for '%" + sFormat[i] + "'"); 1138 } 1139 } else j++; 1140 i++; 1141 } 1142 if (i < sFormat.size()) { 1143 if ((sFormat[i] != '%') || (sFormat[i + 1] != '|')) { 1144 throw UtlException("date format \"" + sFormat + "\" not applied on \"" + sDate + "\" completely"); 1145 } 1146 } 1147 } 1148 getDayWINGZDate() const1149 int UtlDate::getDayWINGZDate() const { 1150 return _pInternalDate->getDayWINGZDate(); 1151 } 1152 getWINGZDate() const1153 double UtlDate::getWINGZDate() const { 1154 if (_pInternalDate == NULL) return 0.0; 1155 return _pInternalDate->getWINGZDate(); 1156 } 1157 setWINGZDate(double dWINGZDate)1158 void UtlDate::setWINGZDate(double dWINGZDate) { 1159 delete _pInternalDate; 1160 if (dWINGZDate <= 0.0) _pInternalDate = NULL; 1161 else _pInternalDate = new UtlInternalDate(dWINGZDate); 1162 } 1163 1164 getInteger(const std::string & sValue,int iNbMaxOfDigits,std::string::size_type & iCursor)1165 int UtlDate::getInteger(const std::string& sValue, int iNbMaxOfDigits, std::string::size_type& iCursor) { 1166 bool bSigned; 1167 char a = sValue[iCursor]; 1168 if (a == '-') { 1169 bSigned = true; 1170 a = sValue[++iCursor]; 1171 iNbMaxOfDigits--; 1172 } else { 1173 bSigned = false; 1174 } 1175 if ((a < '0') || (a > '9')) { 1176 if (bSigned) --iCursor; 1177 return 0; 1178 } 1179 int iNumber = 0; 1180 do { 1181 iNumber *= 10; 1182 iNumber += (int) (a - '0'); 1183 iCursor++; 1184 iNbMaxOfDigits--; 1185 if (iCursor >= sValue.size()) break; 1186 a = sValue[iCursor]; 1187 } while ((a >= '0') && (a <= '9') && (iNbMaxOfDigits > 0)); 1188 if (bSigned) iNumber = -iNumber; 1189 return iNumber; 1190 } 1191 1192 getDouble(const std::string & sValue,int iNbMaxOfDigits,std::string::size_type & iCursor)1193 double UtlDate::getDouble(const std::string& sValue, int iNbMaxOfDigits, std::string::size_type& iCursor) { 1194 bool bSigned; 1195 char a = sValue[iCursor]; 1196 if (a == '-') { 1197 bSigned = true; 1198 a = sValue[++iCursor]; 1199 iNbMaxOfDigits--; 1200 } else { 1201 bSigned = false; 1202 } 1203 if ((a < '0') || (a > '9')) { 1204 if (bSigned) --iCursor; 1205 return 0.0; 1206 } 1207 double dNumber = 0.0; 1208 do { 1209 dNumber *= 10.0; 1210 dNumber += (double) ((int) (a - '0')); 1211 iCursor++; 1212 iNbMaxOfDigits--; 1213 if (iCursor >= sValue.size()) return (bSigned) ? -dNumber : dNumber; 1214 a = sValue[iCursor]; 1215 } while ((a >= '0') && (a <= '9') && (iNbMaxOfDigits > 0)); 1216 if ((a == '.') && (iNbMaxOfDigits > 0)) { 1217 iCursor++; 1218 a = sValue[iCursor]; 1219 double dPower = 0.1; 1220 while ((a >= '0') && (a <= '9') && (iNbMaxOfDigits > 0)) { 1221 dNumber += dPower * (double) ((int) (a - '0')); 1222 dPower *= 0.1; 1223 iCursor++; 1224 iNbMaxOfDigits--; 1225 if (iCursor >= sValue.size()) return dNumber; 1226 a = sValue[iCursor]; 1227 } 1228 } 1229 return (bSigned) ? -dNumber : dNumber; 1230 } 1231 1232 getFrequency()1233 int UtlDate::getFrequency() { 1234 if (_pInternalDate==NULL) { 1235 return 0; 1236 } 1237 else { 1238 if (_pInternalDate->instanceOf("UtlVariableDate")) { 1239 UtlVariableDate *pDateCast= (UtlVariableDate *) _pInternalDate; 1240 return pDateCast->getFrequency(); 1241 } 1242 else { 1243 return 0; 1244 } 1245 1246 } 1247 } 1248 getUnit()1249 char UtlDate::getUnit() { 1250 if (_pInternalDate==NULL) { 1251 return 0; 1252 } 1253 else { 1254 if (_pInternalDate->instanceOf("UtlVariableDate")) { 1255 UtlVariableDate *pDateCast= (UtlVariableDate *) _pInternalDate; 1256 return pDateCast->getUnit(); 1257 } 1258 else { 1259 return 0; 1260 } 1261 1262 } 1263 } 1264 getComment() const1265 const std::string& UtlDate::getComment() const { 1266 static std::string sEmpty = ""; 1267 if (_pInternalDate == NULL) return sEmpty; 1268 return _pInternalDate->getComment(); 1269 } 1270 setComment(const std::string & sComment)1271 void UtlDate::setComment(const std::string& sComment) { 1272 if (_pInternalDate != NULL) { 1273 _pInternalDate->setComment(sComment); 1274 } 1275 } 1276 } 1277