00001 #include "config.h"
00002
00003 #include <iostream>
00004
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
00023 timestamp::timestamp()
00024 {
00025 clear();
00026 set();
00027 }
00028
00029
00030 timestamp::timestamp(const timestamp& a_t)
00031 {
00032 clear();
00033 assign(a_t);
00034 }
00035
00036
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
00051 timestamp::timestamp(const std::string& a_s)
00052 {
00053 clear();
00054 assign(a_s);
00055 }
00056
00057
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
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
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
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
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
00302 void timestamp::resolution(timestamp::resolution_type a_r)
00303 {
00304 m_resolution = a_r;
00305 }
00306
00307
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
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
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
00408 int timestamp::second(void) const
00409 {
00410 return(m_second);
00411 }
00412
00413
00414 int timestamp::minute(void) const
00415 {
00416 return(m_minute);
00417 }
00418
00419
00420 int timestamp::hour(void) const
00421 {
00422 return(m_hour);
00423 }
00424
00425
00426 int timestamp::day(void) const
00427 {
00428 return(m_day);
00429 }
00430
00431
00432 int timestamp::month(void) const
00433 {
00434 return(m_month);
00435 }
00436
00437
00438 int timestamp::year(void) const
00439 {
00440 return(m_year);
00441 }
00442
00443
00444 timestamp::resolution_type timestamp::resolution(void) const
00445 {
00446 return(m_resolution);
00447 }
00448
00449
00450 timestamp& timestamp::operator = (const timestamp& a_t)
00451 {
00452 assign(a_t);
00453
00454 return(*this);
00455 }
00456
00457
00458 timestamp& timestamp::operator = (const std::string& a_s)
00459 {
00460 assign(a_s);
00461
00462 return(*this);
00463 }
00464
00465
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
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
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
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