rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tstamp.cc
Go to the documentation of this file.
1 #include "config.h"
2 
3 #include <iostream>
4 // #include <sstream>
5 #include <iomanip>
6 #include <string>
7 #include <cstring>
8 #include <cctype>
9 
10 #ifdef HAVE_TIME_H
11 #include <time.h>
12 #endif
13 #ifdef HAVE_SYS_TYPES_H
14 #include <sys/types.h>
15 #endif
16 
17 #include "asserts.h"
18 #include "error.h"
19 #include "estring.h"
20 #include "tstamp.h"
21 
22 /** C'tor */
24 {
25  clear();
26  set();
27 }
28 
29 /** C'tor */
31 {
32  clear();
33  assign(a_t);
34 }
35 
36 /** C'tor */
38  const int a_year,
39  const int a_month,
40  const int a_day,
41  const int a_hour,
42  const int a_minute,
43  const int a_second
44  )
45 {
46  clear();
47  assign(a_year,a_month,a_day,a_hour,a_minute,a_second);
48 }
49 
50 /** C'tor */
51 timestamp::timestamp(const std::string& a_s)
52 {
53  clear();
54  assign(a_s);
55 }
56 
57 /** Set the timestamp to the current time and date */
58 void timestamp::set(void)
59 {
60  time_t t = 0;
61  struct tm* tm_ptr = 0;
62 
63  t = time(0);
64  if (t == -1)
65  throw(ERROR(errno,"Could not retrieve current time"));
66  tm_ptr = localtime(&t);
67  if (tm_ptr == 0)
68  throw(ERROR(errno,"Could not convert current time to local time"));
69  m_year = tm_ptr->tm_year + 1900;
70  m_month = tm_ptr->tm_mon + 1;
71  m_day = tm_ptr->tm_mday;
72  m_hour = tm_ptr->tm_hour;
73  m_minute = tm_ptr->tm_min;
74  m_second = tm_ptr->tm_sec;
76 }
77 
78 /** Set the timestamp to the value of another timestamp */
79 void timestamp::assign(const timestamp& a_t)
80 {
81  m_year = a_t.year();
82  m_month = a_t.month();
83  m_day = a_t.day();
84  m_hour = a_t.hour();
85  m_minute = a_t.minute();
86  m_second = a_t.second();
87  m_resolution = a_t.resolution();
88 }
89 
90 /** Set the timestamp */
92  const int a_year,
93  const int a_month,
94  const int a_day,
95  const int a_hour,
96  const int a_minute,
97  const int a_second
98  )
99 {
100  std::string es;
101 
102  if ((a_year < 0) || (a_year > 9999)) {
103  TRY_nomem(es = "Invalid year: \"");
104  TRY_nomem(es += estring(a_year));
105  TRY_nomem(es += "\"");
106 
107  throw(ERROR(0,es));
108  }
109  m_year = a_year;
110 
111  if ((a_month > 12) || (a_month < 1)) {
112  TRY_nomem(es = "Invalid month: \"");
113  TRY_nomem(es += estring(a_month));
114  TRY_nomem(es += "\"");
115 
116  throw(ERROR(0,es));
117  }
118  m_month = a_month;
119 
120  if ((a_day > 31) || (a_day < 1)) {
121  TRY_nomem(es = "Invalid day: \"");
122  TRY_nomem(es += estring(a_day));
123  TRY_nomem(es += "\"");
124 
125  throw(ERROR(0,es));
126  }
127  m_day = a_day;
128 
129  if ((a_hour < 0) || (a_hour > 23)) {
130  TRY_nomem(es = "Invalid hour: \"");
131  TRY_nomem(es += estring(a_hour));
132  TRY_nomem(es += "\"");
133 
134  throw(ERROR(0,es));
135  }
136  m_hour = a_hour;
137 
138  if ((a_minute < 0) || (a_minute > 59)) {
139  TRY_nomem(es = "Invalid minute: \"");
140  TRY_nomem(es += estring(a_minute));
141  TRY_nomem(es += "\"");
142 
143  throw(ERROR(0,es));
144  }
145  m_minute = a_minute;
146 
147  if ((a_second < 0) || (a_second > 59)) {
148  TRY_nomem(es = "Invalid second: \"");
149  TRY_nomem(es += estring(a_second));
150  TRY_nomem(es += "\"");
151 
152  throw(ERROR(0,es));
153  }
154  m_second = a_second;
155 }
156 
157 /** Set the timestamp from a string */
158 void timestamp::assign(const std::string& a_s)
159 {
160  std::string bes;
161  std::string es;
162  std::string ies;
163 
164  int l_year = -1;
165  int l_month = -1;
166  int l_day = -1;
167  int l_hour = -1;
168  int l_minute = -1;
169  int l_second = -1;
171 
172  TRY_nomem(es = "Invalid timestamp string: \"");
173  TRY_nomem(es += a_s);
174  TRY_nomem(es += "\"");
175 
176  if (!is_timestamp(a_s))
177  throw(ERROR(0,es));
178 
179  TRY_nomem(bes = "Parse error converting string to timestamp: \"");
180  TRY_nomem(bes += a_s);
181  TRY_nomem(bes += "\" ");
182 
183  TRY_nomem(es = bes + "Invalid year");
184  if (a_s.size() >= 4)
185  {
186  estring str;
187 
188  r = resolution_year;
189  TRY_nomem(str = a_s.substr(0,4));
190  TRY(l_year = str,ies);
191  }
192  else
193  throw(ERROR(0,es));
194 
195  if (a_s.size() == 4) {
196  assign(l_year,1,1,0,0,0);
197  resolution(r);
198  return;
199  }
200 
201  TRY_nomem(es = bes + "Invalid month");
202  if (a_s.size() >= 7)
203  {
204  estring str;
205 
206  r = resolution_month;
207  TRY_nomem(str = a_s.substr(5,2));
208  TRY(l_month = str,ies);
209  }
210  else
211  throw(ERROR(0,es));
212 
213  if (a_s.size() == 7) {
214  assign(l_year,l_month,1,0,0,0);
215  resolution(r);
216  return;
217  }
218 
219  TRY_nomem(es = bes + "Invalid day");
220  if (a_s.size() >= 10)
221  {
222  estring str;
223 
224  r = resolution_day;
225  TRY_nomem(str = a_s.substr(8,2));
226  TRY(l_day = str,ies);
227  }
228  else
229  throw(ERROR(0,es));
230 
231  if (a_s.size() == 10) {
232  assign(l_year,l_month,l_day,0,0,0);
233  resolution(r);
234  return;
235  }
236 
237  TRY_nomem(es = bes + "Invalid hour");
238  if (a_s.size() >= 13)
239  {
240  estring str;
241 
242  r = resolution_hour;
243  TRY_nomem(str = a_s.substr(11,2));
244  TRY(l_hour = str,ies);
245  }
246  else
247  throw(ERROR(0,es));
248 
249  if (a_s.size() == 13) {
250  assign(l_year,l_month,l_day,l_hour,0,0);
251  resolution(r);
252  return;
253  }
254 
255  TRY_nomem(es = bes + "Invalid minute");
256  if (a_s.size() >= 15)
257  {
258  estring str;
259 
260  r = resolution_minute;
261  TRY_nomem(str = a_s.substr(13,2));
262  TRY(l_minute = str,ies);
263  }
264  else
265  throw(ERROR(0,es));
266 
267  if (a_s.size() == 15) {
268  assign(l_year,l_month,l_day,l_hour,l_minute,0);
269  resolution(r);
270  return;
271  }
272 
273  TRY_nomem(es = bes + "Invalid second");
274  if (a_s.size() == 17)
275  {
276  estring str;
277 
278  r = resolution_second;
279  TRY_nomem(str = a_s.substr(15,2));
280  TRY(l_second = str,ies);
281  }
282  else
283  throw(ERROR(0,es));
284 
285  assign(l_year,l_month,l_day,l_hour,l_minute,l_second);
286  resolution(r);
287 }
288 
289 /** Clear the timestamp */
291 {
292  m_year = 0;
293  m_month = 0;
294  m_day = 0;
295  m_hour = 0;
296  m_minute = 0;
297  m_second = 0;
299 }
300 
301 /** Set the timestamp resolution */
303 {
304  m_resolution = a_r;
305 }
306 
307 /** Generate a string */
308 const std::string timestamp::make_str_(const int a_resolution) const
309 {
310  std::string bes;
311  std::string es;
312  std::string str;
313  estring tmp_str;
314 
315  TRY_nomem(es = "Could not create timestamp string");
316 
317  if (a_resolution >= resolution_year) {
318  tmp_str.width(4);
319  tmp_str.align(estring::right);
320  tmp_str.left_fillchar('0');
321  TRY_nomem(es = bes + ", error converting year");
322  TRY(tmp_str = year(),es);
323  TRY_nomem(str += tmp_str.fmt_str());
324  tmp_str.reset();
325  }
326 
327  if (a_resolution >= resolution_month) {
328  TRY_nomem(es = bes);
329  TRY(str += "-",es);
330  tmp_str.width(2);
331  tmp_str.align(estring::right);
332  tmp_str.left_fillchar('0');
333  TRY_nomem(es = bes + ", error converting month");
334  TRY(tmp_str = month(),es);
335  TRY_nomem(str += tmp_str.fmt_str());
336  tmp_str.reset();
337  }
338 
339  if (a_resolution >= resolution_day) {
340  TRY_nomem(es = bes);
341  TRY(str += "-",es);
342  tmp_str.width(2);
343  tmp_str.align(estring::right);
344  tmp_str.left_fillchar('0');
345  TRY_nomem(es = bes + ", error converting day");
346  TRY(tmp_str = day(),es);
347  TRY_nomem(str += tmp_str.fmt_str());
348  tmp_str.reset();
349  }
350 
351  if (a_resolution >= resolution_hour) {
352  TRY_nomem(es = bes);
353  TRY(str += ".",es);
354  tmp_str.width(2);
355  tmp_str.align(estring::right);
356  tmp_str.left_fillchar('0');
357  TRY_nomem(es = bes + ", error converting hour");
358  TRY(tmp_str = hour(),es);
359  TRY_nomem(str += tmp_str.fmt_str());
360  tmp_str.reset();
361  }
362 
363  if (a_resolution >= resolution_minute) {
364  tmp_str.width(2);
365  tmp_str.align(estring::right);
366  tmp_str.left_fillchar('0');
367  TRY_nomem(es = bes + ", error converting minute");
368  TRY(tmp_str = minute(),es);
369  TRY_nomem(str += tmp_str.fmt_str());
370  tmp_str.reset();
371  }
372 
373  if (a_resolution >= resolution_second) {
374  tmp_str.width(2);
375  tmp_str.align(estring::right);
376  tmp_str.left_fillchar('0');
377  TRY_nomem(es = bes + ", error converting second");
378  TRY(tmp_str = second(),es);
379  TRY_nomem(str += tmp_str.fmt_str());
380  tmp_str.reset();
381  }
382 
383  return(str);
384 }
385 
386 /** Generate a string */
387 const std::string timestamp::str(void) const
388 {
389  std::string str;
390 
392 
393  return(str);
394 }
395 
396 /** Generate a string */
397 const std::string timestamp::str(
398  const timestamp::resolution_type a_resolution) const
399 {
400  std::string str;
401 
402  TRY_nomem(str = make_str_(a_resolution));
403 
404  return(str);
405 }
406 
407 /** Return the timestamp second */
408 int timestamp::second(void) const
409 {
410  return(m_second);
411 }
412 
413 /** Return the timestamp minute */
414 int timestamp::minute(void) const
415 {
416  return(m_minute);
417 }
418 
419 /** Return the timestamp hour */
420 int timestamp::hour(void) const
421 {
422  return(m_hour);
423 }
424 
425 /** Return the timestamp day */
426 int timestamp::day(void) const
427 {
428  return(m_day);
429 }
430 
431 /** Return the timestamp month */
432 int timestamp::month(void) const
433 {
434  return(m_month);
435 }
436 
437 /** Return the timestamp year */
438 int timestamp::year(void) const
439 {
440  return(m_year);
441 }
442 
443 /** Return the timestamp resolution */
445 {
446  return(m_resolution);
447 }
448 
449 /** Assignment */
451 {
452  assign(a_t);
453 
454  return(*this);
455 }
456 
457 /** Assignment */
458 timestamp& timestamp::operator = (const std::string& a_s)
459 {
460  assign(a_s);
461 
462  return(*this);
463 }
464 
465 /** Comparison */
466 bool timestamp::operator < (const timestamp& a_t) const
467 {
468  resolution_type r;
469  bool value;
470 
471  r = std::min(m_resolution, a_t.resolution());
472  value = (str(r) < a_t.str(r));
473 
474  return(value);
475 }
476 
477 /** Comparison */
478 bool timestamp::operator > (const timestamp& a_t) const
479 {
480  resolution_type r;
481  bool value;
482 
483  r = std::min(m_resolution, a_t.resolution());
484  value = (str(r) > a_t.str(r));
485 
486  return(value);
487 }
488 
489 /** Comparison */
490 bool timestamp::operator == (const timestamp& a_t) const
491 {
492  resolution_type r;
493  bool value;
494 
495  r = std::min(m_resolution, a_t.resolution());
496  value = (str(r) == a_t.str(r));
497 
498  return(value);
499 }
500 
501 /** Return true if the string is a valid timestamp */
502 bool is_timestamp(const std::string& a_s)
503 {
504  estring str;
505  int i;
506 
507  if (a_s.size() < 4) {
508  return(false);
509  }
510  if (!isdigit(a_s[0])) {
511  return(false);
512  }
513  if (!isdigit(a_s[1])) {
514  return(false);
515  }
516  if (!isdigit(a_s[2])) {
517  return(false);
518  }
519  if (!isdigit(a_s[3])) {
520  return(false);
521  }
522  TRY_nomem(str = a_s.substr(0,4));
523  try {
524  i = str;
525  }
526  catch(...) {
527  return(false);
528  }
529  if ((i < 0) || (i > 9999)) {
530  return(false);
531  }
532  if (a_s.size() == 4) {
533  return(true);
534  }
535 
536  if (a_s.size() < 7) {
537  return(false);
538  }
539  if (a_s[4] != '-') {
540  return(false);
541  }
542  if (!isdigit(a_s[5])) {
543  return(false);
544  }
545  if (!isdigit(a_s[6])) {
546  return(false);
547  }
548  TRY_nomem(str = a_s.substr(5,2));
549  try {
550  i = str;
551  }
552  catch(...) {
553  return(false);
554  }
555  if ((i < 1) || (i > 12)) {
556  return(false);
557  }
558  if (a_s.size() == 7) {
559  return(true);
560  }
561 
562  if (a_s.size() < 10) {
563  return(false);
564  }
565  if (a_s[7] != '-') {
566  return(false);
567  }
568  if (!isdigit(a_s[8])) {
569  return(false);
570  }
571  if (!isdigit(a_s[9])) {
572  return(false);
573  }
574  TRY_nomem(str = a_s.substr(8,2));
575  try {
576  i = str;
577  }
578  catch(...) {
579  return(false);
580  }
581  if ((i < 1) || (i > 31)) {
582  return(false);
583  }
584  if (a_s.size() == 10) {
585  return(true);
586  }
587 
588  if (a_s.size() < 13) {
589  return(false);
590  }
591  if (a_s[10] != '.') {
592  return(false);
593  }
594  if (!isdigit(a_s[11])) {
595  return(false);
596  }
597  if (!isdigit(a_s[12])) {
598  return(false);
599  }
600  TRY_nomem(str = a_s.substr(11,2));
601  try {
602  i = str;
603  }
604  catch(...) {
605  return(false);
606  }
607  if ((i < 0) || (i > 23)) {
608  return(false);
609  }
610  if (a_s.size() == 13) {
611  return(true);
612  }
613 
614  if (a_s.size() < 15) {
615  return(false);
616  }
617  if (!isdigit(a_s[13])) {
618  return(false);
619  }
620  if (!isdigit(a_s[14])) {
621  return(false);
622  }
623  TRY_nomem(str = a_s.substr(13,2));
624  try {
625  i = str;
626  }
627  catch(...) {
628  return(false);
629  }
630  if ((i < 0) || (i > 59)) {
631  return(false);
632  }
633  if (a_s.size() == 15) {
634  return(true);
635  }
636 
637  if (a_s.size() < 17) {
638  return(false);
639  }
640  if (!isdigit(a_s[15])) {
641  return(false);
642  }
643  if (!isdigit(a_s[16])) {
644  return(false);
645  }
646  TRY_nomem(str = a_s.substr(15,2));
647  try {
648  i = str;
649  }
650  catch(...) {
651  return(false);
652  }
653  if ((i < 0) || (i > 59)) {
654  return(false);
655  }
656  if (a_s.size() == 17) {
657  return(true);
658  }
659 
660  return(false);
661 }
662 
Timestamp object.
Definition: tstamp.h:13
int m_day
Definition: tstamp.h:70
void clear(void)
Clear the timestamp.
Definition: tstamp.cc:290
resolution_type resolution(void) const
Return the timestamp resolution.
Definition: tstamp.cc:444
timestamp()
C'tor.
Definition: tstamp.cc:23
int year(void) const
Return the timestamp year.
Definition: tstamp.cc:438
int day(void) const
Return the timestamp day.
Definition: tstamp.cc:426
An extended string class.
Definition: estring.h:52
void reset(void)
Erase and reinitialize.
Definition: estring.cc:421
int m_month
Definition: tstamp.h:69
resolution_type m_resolution
Definition: tstamp.h:74
int month(void) const
Return the timestamp month.
Definition: tstamp.cc:432
Right-justified.
Definition: estring.h:66
char left_fillchar(const char a_char)
Set the fill character used to padd the left side of a formatted string.
Definition: estring.cc:603
bool operator<(const timestamp &a_t) const
Comparison.
Definition: tstamp.cc:466
int m_second
Definition: tstamp.h:73
bool operator>(const timestamp &a_t) const
Comparison.
Definition: tstamp.cc:478
void assign(const timestamp &a_t)
Set the timestamp to the value of another timestamp.
Definition: tstamp.cc:79
#define TRY_nomem(code)
Definition: error.h:144
value_type fmt_str(void)
Generate a formatted string.
Definition: estring.cc:688
int second(void) const
Return the timestamp second.
Definition: tstamp.cc:408
int m_minute
Definition: tstamp.h:72
int m_hour
Definition: tstamp.h:71
#define TRY(code, es)
Definition: error.h:126
void resolution(resolution_type a_r)
Set the timestamp resolution.
Definition: tstamp.cc:302
void set(void)
Set the timestamp to the current time and date.
Definition: tstamp.cc:58
bool is_timestamp(const std::string &a_s)
Return true if the string is a valid timestamp.
Definition: tstamp.cc:502
timestamp & operator=(const timestamp &a_t)
Assignment.
Definition: tstamp.cc:450
const std::string make_str_(const int a_resolution) const
Generate a string.
Definition: tstamp.cc:308
size_type width(const size_type a_l)
Set the width of a formatted string.
Definition: estring.cc:446
int hour(void) const
Return the timestamp hour.
Definition: tstamp.cc:420
resolution_type
Definition: tstamp.h:16
alignment align(const alignment a_alignment)
Set the alignment used for formatted strings.
Definition: estring.cc:471
bool operator==(const timestamp &a_t) const
Comparison.
Definition: tstamp.cc:490
const std::string str(void) const
Generate a string.
Definition: tstamp.cc:387
#define ERROR(e, s)
Definition: error.h:120
int m_year
Definition: tstamp.h:68
int minute(void) const
Return the timestamp minute.
Definition: tstamp.cc:414