rvm 1.08
|
00001 #include "config.h" 00002 00003 #include <iostream> 00004 // #include <sstream> 00005 #include <iomanip> 00006 #include <string> 00007 #include <cstring> 00008 #include <cctype> 00009 00010 #ifdef HAVE_TIME_H 00011 #include <time.h> 00012 #endif 00013 #ifdef HAVE_SYS_TYPES_H 00014 #include <sys/types.h> 00015 #endif 00016 00017 #include "asserts.h" 00018 #include "error.h" 00019 #include "estring.h" 00020 #include "tstamp.h" 00021 00022 /** C'tor */ 00023 timestamp::timestamp() 00024 { 00025 clear(); 00026 set(); 00027 } 00028 00029 /** C'tor */ 00030 timestamp::timestamp(const timestamp& a_t) 00031 { 00032 clear(); 00033 assign(a_t); 00034 } 00035 00036 /** C'tor */ 00037 timestamp::timestamp( 00038 const int a_year, 00039 const int a_month, 00040 const int a_day, 00041 const int a_hour, 00042 const int a_minute, 00043 const int a_second 00044 ) 00045 { 00046 clear(); 00047 assign(a_year,a_month,a_day,a_hour,a_minute,a_second); 00048 } 00049 00050 /** C'tor */ 00051 timestamp::timestamp(const std::string& a_s) 00052 { 00053 clear(); 00054 assign(a_s); 00055 } 00056 00057 /** Set the timestamp to the current time and date */ 00058 void timestamp::set(void) 00059 { 00060 time_t t = 0; 00061 struct tm* tm_ptr = 0; 00062 00063 t = time(0); 00064 if (t == -1) 00065 throw(ERROR(errno,"Could not retrieve current time")); 00066 tm_ptr = localtime(&t); 00067 if (tm_ptr == 0) 00068 throw(ERROR(errno,"Could not convert current time to local time")); 00069 m_year = tm_ptr->tm_year + 1900; 00070 m_month = tm_ptr->tm_mon + 1; 00071 m_day = tm_ptr->tm_mday; 00072 m_hour = tm_ptr->tm_hour; 00073 m_minute = tm_ptr->tm_min; 00074 m_second = tm_ptr->tm_sec; 00075 m_resolution = resolution_day; 00076 } 00077 00078 /** Set the timestamp to the value of another timestamp */ 00079 void timestamp::assign(const timestamp& a_t) 00080 { 00081 m_year = a_t.year(); 00082 m_month = a_t.month(); 00083 m_day = a_t.day(); 00084 m_hour = a_t.hour(); 00085 m_minute = a_t.minute(); 00086 m_second = a_t.second(); 00087 m_resolution = a_t.resolution(); 00088 } 00089 00090 /** Set the timestamp */ 00091 void timestamp::assign( 00092 const int a_year, 00093 const int a_month, 00094 const int a_day, 00095 const int a_hour, 00096 const int a_minute, 00097 const int a_second 00098 ) 00099 { 00100 std::string es; 00101 00102 if ((a_year < 0) || (a_year > 9999)) { 00103 TRY_nomem(es = "Invalid year: \""); 00104 TRY_nomem(es += estring(a_year)); 00105 TRY_nomem(es += "\""); 00106 00107 throw(ERROR(0,es)); 00108 } 00109 m_year = a_year; 00110 00111 if ((a_month > 12) || (a_month < 1)) { 00112 TRY_nomem(es = "Invalid month: \""); 00113 TRY_nomem(es += estring(a_month)); 00114 TRY_nomem(es += "\""); 00115 00116 throw(ERROR(0,es)); 00117 } 00118 m_month = a_month; 00119 00120 if ((a_day > 31) || (a_day < 1)) { 00121 TRY_nomem(es = "Invalid day: \""); 00122 TRY_nomem(es += estring(a_day)); 00123 TRY_nomem(es += "\""); 00124 00125 throw(ERROR(0,es)); 00126 } 00127 m_day = a_day; 00128 00129 if ((a_hour < 0) || (a_hour > 23)) { 00130 TRY_nomem(es = "Invalid hour: \""); 00131 TRY_nomem(es += estring(a_hour)); 00132 TRY_nomem(es += "\""); 00133 00134 throw(ERROR(0,es)); 00135 } 00136 m_hour = a_hour; 00137 00138 if ((a_minute < 0) || (a_minute > 59)) { 00139 TRY_nomem(es = "Invalid minute: \""); 00140 TRY_nomem(es += estring(a_minute)); 00141 TRY_nomem(es += "\""); 00142 00143 throw(ERROR(0,es)); 00144 } 00145 m_minute = a_minute; 00146 00147 if ((a_second < 0) || (a_second > 59)) { 00148 TRY_nomem(es = "Invalid second: \""); 00149 TRY_nomem(es += estring(a_second)); 00150 TRY_nomem(es += "\""); 00151 00152 throw(ERROR(0,es)); 00153 } 00154 m_second = a_second; 00155 } 00156 00157 /** Set the timestamp from a string */ 00158 void timestamp::assign(const std::string& a_s) 00159 { 00160 std::string bes; 00161 std::string es; 00162 std::string ies; 00163 00164 int l_year = -1; 00165 int l_month = -1; 00166 int l_day = -1; 00167 int l_hour = -1; 00168 int l_minute = -1; 00169 int l_second = -1; 00170 resolution_type r = resolution_day; 00171 00172 TRY_nomem(es = "Invalid timestamp string: \""); 00173 TRY_nomem(es += a_s); 00174 TRY_nomem(es += "\""); 00175 00176 if (!is_timestamp(a_s)) 00177 throw(ERROR(0,es)); 00178 00179 TRY_nomem(bes = "Parse error converting string to timestamp: \""); 00180 TRY_nomem(bes += a_s); 00181 TRY_nomem(bes += "\" "); 00182 00183 TRY_nomem(es = bes + "Invalid year"); 00184 if (a_s.size() >= 4) 00185 { 00186 estring str; 00187 00188 r = resolution_year; 00189 TRY_nomem(str = a_s.substr(0,4)); 00190 TRY(l_year = str,ies); 00191 } 00192 else 00193 throw(ERROR(0,es)); 00194 00195 if (a_s.size() == 4) { 00196 assign(l_year,1,1,0,0,0); 00197 resolution(r); 00198 return; 00199 } 00200 00201 TRY_nomem(es = bes + "Invalid month"); 00202 if (a_s.size() >= 7) 00203 { 00204 estring str; 00205 00206 r = resolution_month; 00207 TRY_nomem(str = a_s.substr(5,2)); 00208 TRY(l_month = str,ies); 00209 } 00210 else 00211 throw(ERROR(0,es)); 00212 00213 if (a_s.size() == 7) { 00214 assign(l_year,l_month,1,0,0,0); 00215 resolution(r); 00216 return; 00217 } 00218 00219 TRY_nomem(es = bes + "Invalid day"); 00220 if (a_s.size() >= 10) 00221 { 00222 estring str; 00223 00224 r = resolution_day; 00225 TRY_nomem(str = a_s.substr(8,2)); 00226 TRY(l_day = str,ies); 00227 } 00228 else 00229 throw(ERROR(0,es)); 00230 00231 if (a_s.size() == 10) { 00232 assign(l_year,l_month,l_day,0,0,0); 00233 resolution(r); 00234 return; 00235 } 00236 00237 TRY_nomem(es = bes + "Invalid hour"); 00238 if (a_s.size() >= 13) 00239 { 00240 estring str; 00241 00242 r = resolution_hour; 00243 TRY_nomem(str = a_s.substr(11,2)); 00244 TRY(l_hour = str,ies); 00245 } 00246 else 00247 throw(ERROR(0,es)); 00248 00249 if (a_s.size() == 13) { 00250 assign(l_year,l_month,l_day,l_hour,0,0); 00251 resolution(r); 00252 return; 00253 } 00254 00255 TRY_nomem(es = bes + "Invalid minute"); 00256 if (a_s.size() >= 15) 00257 { 00258 estring str; 00259 00260 r = resolution_minute; 00261 TRY_nomem(str = a_s.substr(13,2)); 00262 TRY(l_minute = str,ies); 00263 } 00264 else 00265 throw(ERROR(0,es)); 00266 00267 if (a_s.size() == 15) { 00268 assign(l_year,l_month,l_day,l_hour,l_minute,0); 00269 resolution(r); 00270 return; 00271 } 00272 00273 TRY_nomem(es = bes + "Invalid second"); 00274 if (a_s.size() == 17) 00275 { 00276 estring str; 00277 00278 r = resolution_second; 00279 TRY_nomem(str = a_s.substr(15,2)); 00280 TRY(l_second = str,ies); 00281 } 00282 else 00283 throw(ERROR(0,es)); 00284 00285 assign(l_year,l_month,l_day,l_hour,l_minute,l_second); 00286 resolution(r); 00287 } 00288 00289 /** Clear the timestamp */ 00290 void timestamp::clear(void) 00291 { 00292 m_year = 0; 00293 m_month = 0; 00294 m_day = 0; 00295 m_hour = 0; 00296 m_minute = 0; 00297 m_second = 0; 00298 m_resolution = resolution_day; 00299 } 00300 00301 /** Set the timestamp resolution */ 00302 void timestamp::resolution(timestamp::resolution_type a_r) 00303 { 00304 m_resolution = a_r; 00305 } 00306 00307 /** Generate a string */ 00308 const std::string timestamp::make_str_(const int a_resolution) const 00309 { 00310 std::string bes; 00311 std::string es; 00312 std::string str; 00313 estring tmp_str; 00314 00315 TRY_nomem(es = "Could not create timestamp string"); 00316 00317 if (a_resolution >= resolution_year) { 00318 tmp_str.width(4); 00319 tmp_str.align(estring::right); 00320 tmp_str.left_fillchar('0'); 00321 TRY_nomem(es = bes + ", error converting year"); 00322 TRY(tmp_str = year(),es); 00323 TRY_nomem(str += tmp_str.fmt_str()); 00324 tmp_str.reset(); 00325 } 00326 00327 if (a_resolution >= resolution_month) { 00328 TRY_nomem(es = bes); 00329 TRY(str += "-",es); 00330 tmp_str.width(2); 00331 tmp_str.align(estring::right); 00332 tmp_str.left_fillchar('0'); 00333 TRY_nomem(es = bes + ", error converting month"); 00334 TRY(tmp_str = month(),es); 00335 TRY_nomem(str += tmp_str.fmt_str()); 00336 tmp_str.reset(); 00337 } 00338 00339 if (a_resolution >= resolution_day) { 00340 TRY_nomem(es = bes); 00341 TRY(str += "-",es); 00342 tmp_str.width(2); 00343 tmp_str.align(estring::right); 00344 tmp_str.left_fillchar('0'); 00345 TRY_nomem(es = bes + ", error converting day"); 00346 TRY(tmp_str = day(),es); 00347 TRY_nomem(str += tmp_str.fmt_str()); 00348 tmp_str.reset(); 00349 } 00350 00351 if (a_resolution >= resolution_hour) { 00352 TRY_nomem(es = bes); 00353 TRY(str += ".",es); 00354 tmp_str.width(2); 00355 tmp_str.align(estring::right); 00356 tmp_str.left_fillchar('0'); 00357 TRY_nomem(es = bes + ", error converting hour"); 00358 TRY(tmp_str = hour(),es); 00359 TRY_nomem(str += tmp_str.fmt_str()); 00360 tmp_str.reset(); 00361 } 00362 00363 if (a_resolution >= resolution_minute) { 00364 tmp_str.width(2); 00365 tmp_str.align(estring::right); 00366 tmp_str.left_fillchar('0'); 00367 TRY_nomem(es = bes + ", error converting minute"); 00368 TRY(tmp_str = minute(),es); 00369 TRY_nomem(str += tmp_str.fmt_str()); 00370 tmp_str.reset(); 00371 } 00372 00373 if (a_resolution >= resolution_second) { 00374 tmp_str.width(2); 00375 tmp_str.align(estring::right); 00376 tmp_str.left_fillchar('0'); 00377 TRY_nomem(es = bes + ", error converting second"); 00378 TRY(tmp_str = second(),es); 00379 TRY_nomem(str += tmp_str.fmt_str()); 00380 tmp_str.reset(); 00381 } 00382 00383 return(str); 00384 } 00385 00386 /** Generate a string */ 00387 const std::string timestamp::str(void) const 00388 { 00389 std::string str; 00390 00391 TRY_nomem(str = make_str_(m_resolution)); 00392 00393 return(str); 00394 } 00395 00396 /** Generate a string */ 00397 const std::string timestamp::str( 00398 const timestamp::resolution_type a_resolution) const 00399 { 00400 std::string str; 00401 00402 TRY_nomem(str = make_str_(a_resolution)); 00403 00404 return(str); 00405 } 00406 00407 /** Return the timestamp second */ 00408 int timestamp::second(void) const 00409 { 00410 return(m_second); 00411 } 00412 00413 /** Return the timestamp minute */ 00414 int timestamp::minute(void) const 00415 { 00416 return(m_minute); 00417 } 00418 00419 /** Return the timestamp hour */ 00420 int timestamp::hour(void) const 00421 { 00422 return(m_hour); 00423 } 00424 00425 /** Return the timestamp day */ 00426 int timestamp::day(void) const 00427 { 00428 return(m_day); 00429 } 00430 00431 /** Return the timestamp month */ 00432 int timestamp::month(void) const 00433 { 00434 return(m_month); 00435 } 00436 00437 /** Return the timestamp year */ 00438 int timestamp::year(void) const 00439 { 00440 return(m_year); 00441 } 00442 00443 /** Return the timestamp resolution */ 00444 timestamp::resolution_type timestamp::resolution(void) const 00445 { 00446 return(m_resolution); 00447 } 00448 00449 /** Assignment */ 00450 timestamp& timestamp::operator = (const timestamp& a_t) 00451 { 00452 assign(a_t); 00453 00454 return(*this); 00455 } 00456 00457 /** Assignment */ 00458 timestamp& timestamp::operator = (const std::string& a_s) 00459 { 00460 assign(a_s); 00461 00462 return(*this); 00463 } 00464 00465 /** Comparison */ 00466 bool timestamp::operator < (const timestamp& a_t) const 00467 { 00468 resolution_type r; 00469 bool value; 00470 00471 r = std::min(m_resolution, a_t.resolution()); 00472 value = (str(r) < a_t.str(r)); 00473 00474 return(value); 00475 } 00476 00477 /** Comparison */ 00478 bool timestamp::operator > (const timestamp& a_t) const 00479 { 00480 resolution_type r; 00481 bool value; 00482 00483 r = std::min(m_resolution, a_t.resolution()); 00484 value = (str(r) > a_t.str(r)); 00485 00486 return(value); 00487 } 00488 00489 /** Comparison */ 00490 bool timestamp::operator == (const timestamp& a_t) const 00491 { 00492 resolution_type r; 00493 bool value; 00494 00495 r = std::min(m_resolution, a_t.resolution()); 00496 value = (str(r) == a_t.str(r)); 00497 00498 return(value); 00499 } 00500 00501 /** Return true if the string is a valid timestamp */ 00502 bool is_timestamp(const std::string& a_s) 00503 { 00504 estring str; 00505 int i; 00506 00507 if (a_s.size() < 4) { 00508 return(false); 00509 } 00510 if (!isdigit(a_s[0])) { 00511 return(false); 00512 } 00513 if (!isdigit(a_s[1])) { 00514 return(false); 00515 } 00516 if (!isdigit(a_s[2])) { 00517 return(false); 00518 } 00519 if (!isdigit(a_s[3])) { 00520 return(false); 00521 } 00522 TRY_nomem(str = a_s.substr(0,4)); 00523 try { 00524 i = str; 00525 } 00526 catch(...) { 00527 return(false); 00528 } 00529 if ((i < 0) || (i > 9999)) { 00530 return(false); 00531 } 00532 if (a_s.size() == 4) { 00533 return(true); 00534 } 00535 00536 if (a_s.size() < 7) { 00537 return(false); 00538 } 00539 if (a_s[4] != '-') { 00540 return(false); 00541 } 00542 if (!isdigit(a_s[5])) { 00543 return(false); 00544 } 00545 if (!isdigit(a_s[6])) { 00546 return(false); 00547 } 00548 TRY_nomem(str = a_s.substr(5,2)); 00549 try { 00550 i = str; 00551 } 00552 catch(...) { 00553 return(false); 00554 } 00555 if ((i < 1) || (i > 12)) { 00556 return(false); 00557 } 00558 if (a_s.size() == 7) { 00559 return(true); 00560 } 00561 00562 if (a_s.size() < 10) { 00563 return(false); 00564 } 00565 if (a_s[7] != '-') { 00566 return(false); 00567 } 00568 if (!isdigit(a_s[8])) { 00569 return(false); 00570 } 00571 if (!isdigit(a_s[9])) { 00572 return(false); 00573 } 00574 TRY_nomem(str = a_s.substr(8,2)); 00575 try { 00576 i = str; 00577 } 00578 catch(...) { 00579 return(false); 00580 } 00581 if ((i < 1) || (i > 31)) { 00582 return(false); 00583 } 00584 if (a_s.size() == 10) { 00585 return(true); 00586 } 00587 00588 if (a_s.size() < 13) { 00589 return(false); 00590 } 00591 if (a_s[10] != '.') { 00592 return(false); 00593 } 00594 if (!isdigit(a_s[11])) { 00595 return(false); 00596 } 00597 if (!isdigit(a_s[12])) { 00598 return(false); 00599 } 00600 TRY_nomem(str = a_s.substr(11,2)); 00601 try { 00602 i = str; 00603 } 00604 catch(...) { 00605 return(false); 00606 } 00607 if ((i < 0) || (i > 23)) { 00608 return(false); 00609 } 00610 if (a_s.size() == 13) { 00611 return(true); 00612 } 00613 00614 if (a_s.size() < 15) { 00615 return(false); 00616 } 00617 if (!isdigit(a_s[13])) { 00618 return(false); 00619 } 00620 if (!isdigit(a_s[14])) { 00621 return(false); 00622 } 00623 TRY_nomem(str = a_s.substr(13,2)); 00624 try { 00625 i = str; 00626 } 00627 catch(...) { 00628 return(false); 00629 } 00630 if ((i < 0) || (i > 59)) { 00631 return(false); 00632 } 00633 if (a_s.size() == 15) { 00634 return(true); 00635 } 00636 00637 if (a_s.size() < 17) { 00638 return(false); 00639 } 00640 if (!isdigit(a_s[15])) { 00641 return(false); 00642 } 00643 if (!isdigit(a_s[16])) { 00644 return(false); 00645 } 00646 TRY_nomem(str = a_s.substr(15,2)); 00647 try { 00648 i = str; 00649 } 00650 catch(...) { 00651 return(false); 00652 } 00653 if ((i < 0) || (i > 59)) { 00654 return(false); 00655 } 00656 if (a_s.size() == 17) { 00657 return(true); 00658 } 00659 00660 return(false); 00661 } 00662