1 /*****************************************************************************/
2 /* Software Testing Automation Framework (STAF)                              */
3 /* (C) Copyright IBM Corp. 2001                                              */
4 /*                                                                           */
5 /* This software is licensed under the Eclipse Public License (EPL) V1.0.    */
6 /*****************************************************************************/
7 
8 #ifndef STAF_TimestampInlImpl
9 #define STAF_TimestampInlImpl
10 
11 #include "STAF.h"
12 #include "STAFTimestamp.h"
13 #include "STAFString.h"
14 #include "STAFException.h"
15 
16 // Begin definitions for STAFTimestamp
17 
STAFTimestamp(time_t aTime)18 STAF_INLINE STAFTimestamp::STAFTimestamp(time_t aTime) : fTime(aTime)
19 { /* Do Nothing */ }
20 
21 
STAFTimestamp(const STAFString & aString,const STAFString & seps)22 STAF_INLINE STAFTimestamp::STAFTimestamp(const STAFString &aString,
23                                          const STAFString &seps)
24 {
25     // Get current time
26     unsigned int osRC = 0;
27     struct tm theTime = { 0 };
28     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime,
29                                           STAFTimestamp::now().getImpl(), &osRC);
30 
31     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
32 
33     // Set the time to 00:00:00 by default
34     theTime.tm_hour = 0;
35     theTime.tm_min = 0;
36     theTime.tm_sec = 0;
37     theTime.tm_isdst = -1;
38 
39     // Split the input into date and time
40     //
41     // If we can't find the separator then we assume the string is just a time
42     // if we can find a colon in it, otherwise we assume it is just a date
43 
44     STAFString dateString;
45     STAFString timeString;
46     unsigned int sepLoc = aString.findFirstOf(seps);
47 
48     if (sepLoc != STAFString::kNPos)
49     {
50         dateString = aString.subString(0, sepLoc);
51         timeString = aString.subString(sepLoc + aString.sizeOfChar(sepLoc));
52     }
53     else if (aString.find(kUTF8_COLON) != STAFString::kNPos)
54     {
55         timeString = aString;
56     }
57     else
58     {
59         dateString = aString;
60     }
61 
62     // Calculate date stuff first
63 
64     unsigned int slashCount = dateString.count(kUTF8_SLASH);
65     unsigned int firstSlash = dateString.find(kUTF8_SLASH);
66     unsigned int secondSlash = dateString.findLastOf(kUTF8_SLASH);
67 
68     if ((dateString.length() > 0) &&
69     	(((slashCount == 0) && (dateString.length() == 8)) ||
70           (((slashCount == 2) && (firstSlash == 2) && (secondSlash == 5) &&
71             ((dateString.length() == 8) || (dateString.length() == 10))))))
72     {
73         STAFString yearString;
74         STAFString monthString;
75         STAFString dayString;
76 
77         if (slashCount == 0)
78         {
79             yearString = dateString.subString(0, 4);
80             monthString = dateString.subString(4, 2);
81             dayString = dateString.subString(6);
82         }
83         else
84         {
85             monthString = dateString.subString(0, 2);
86             dayString = dateString.subString(3, 2);
87             yearString = dateString.subString(6);
88         }
89 
90         try
91         {
92             theTime.tm_year = yearString.asUInt();
93             theTime.tm_mon  = monthString.asUInt() - 1;
94             theTime.tm_mday = dayString.asUInt();
95         }
96         catch (STAFException)
97         {
98             STAFTimestampInvalidDateException error("STAFTimestamp(string)");
99             THROW_STAF_EXCEPTION(error);
100         }
101 
102         if (!isValidDate(theTime.tm_year, theTime.tm_mon + 1, theTime.tm_mday))
103         {
104             STAFTimestampInvalidDateException error("STAFTimestamp(string)");
105             THROW_STAF_EXCEPTION(error);
106         }
107 
108         if (theTime.tm_year < 90) theTime.tm_year += 100;
109         else theTime.tm_year -= 1900;
110     }
111     else if (dateString.length() > 0)
112     {
113         STAFTimestampInvalidDateException error("STAFTimestamp(string)");
114         THROW_STAF_EXCEPTION(error);
115     }
116 
117     // Now do time stuff
118 
119     unsigned int colonCount = timeString.count(kUTF8_COLON);
120     unsigned int firstColon = timeString.find(kUTF8_COLON);
121     unsigned int secondColon = timeString.findLastOf(kUTF8_COLON);
122 
123     if ((timeString.length() > 0) &&
124         (((colonCount == 0) && (timeString.length() == 2)) ||
125           ((colonCount == 1) && (firstColon == 2) && timeString.length() == 5) ||
126           ((colonCount == 2) && (firstColon == 2) && (secondColon == 5) &&
127            (timeString.length() == 8))))
128     {
129         theTime.tm_hour = 0;
130         theTime.tm_min  = 0;
131         theTime.tm_sec  = 0;
132 
133         STAFString hourString = timeString.subString(0, 2);
134         STAFString minString = timeString.subString(3, 2);
135         STAFString secString = timeString.subString(6);
136 
137         if ((!hourString.isDigits()) ||
138             ((minString.length() > 0) && !minString.isDigits()) ||
139             ((secString.length() > 0) && !secString.isDigits()))
140         {
141             STAFTimestampInvalidTimeException error("STAFTimestamp(string)");
142             THROW_STAF_EXCEPTION(error);
143         }
144 
145         theTime.tm_hour = hourString.asUInt();
146 
147         if (colonCount > 0) theTime.tm_min = minString.asUInt();
148         if (colonCount > 1) theTime.tm_sec = secString.asUInt();
149 
150         if (!isValidTime(theTime.tm_hour, theTime.tm_min, theTime.tm_sec))
151         {
152             STAFTimestampInvalidTimeException error("STAFTimestamp(string)");
153             THROW_STAF_EXCEPTION(error);
154         }
155     }
156     else if (timeString.length() > 0)
157     {
158         STAFTimestampInvalidTimeException error("STAFTimestamp(string)");
159         THROW_STAF_EXCEPTION(error);
160     }
161 
162     // Now try to get a time_t
163     fTime = mktime(&theTime);
164 
165     if (fTime == -1)
166     {
167         STAFTimestampInvalidDateTimeException error("STAFTimestamp(string)");
168         THROW_STAF_EXCEPTION(error);
169     }
170 }
171 
172 
STAFTimestamp(unsigned int year,unsigned int month,unsigned int day,unsigned int hour,unsigned int minute,unsigned int second)173 STAF_INLINE STAFTimestamp::STAFTimestamp(unsigned int year, unsigned int month,
174                                          unsigned int day,  unsigned int hour,
175                                          unsigned int minute,
176                                          unsigned int second)
177 {
178     if (!isValidDate(year, month, day))
179     {
180         STAFTimestampInvalidDateException error("STAFTimestamp(y,m,d,h,m,s)");
181         THROW_STAF_EXCEPTION(error);
182     }
183 
184     if (!isValidTime(hour, minute, second))
185     {
186         STAFTimestampInvalidTimeException error("STAFTimestamp(y,m,d,h,m,s)");
187         THROW_STAF_EXCEPTION(error);
188     }
189 
190     struct tm aTime = { 0 };
191 
192     if (year < 90) aTime.tm_year = year + 100;
193     else if (year < 1900) aTime.tm_year = year;
194     else aTime.tm_year = year - 1900;
195 
196     aTime.tm_mon  = month - 1;
197     aTime.tm_mday = day;
198     aTime.tm_hour = hour;
199     aTime.tm_min  = minute;
200     aTime.tm_sec  = second;
201     aTime.tm_isdst = -1;
202 
203     // Now try to get a time_t
204     fTime = mktime(&aTime);
205 
206     if (fTime == -1)
207     {
208         STAFTimestampInvalidDateTimeException error(
209             "STAFTimestamp(y,m,d,h,m,s)");
210         THROW_STAF_EXCEPTION(error);
211     }
212 }
213 
214 
now()215 STAF_INLINE STAFTimestamp STAFTimestamp::now()
216 {
217     return STAFTimestamp();
218 }
219 
220 
isValidTimestampString(const STAFString & aString,const STAFString & dateTimeSeps)221 STAF_INLINE bool STAFTimestamp::isValidTimestampString(
222                  const STAFString &aString, const STAFString &dateTimeSeps)
223 {
224     try
225     {
226         STAFTimestamp test(aString, dateTimeSeps);
227     }
228     catch (STAFTimestampInvalidDateTimeException)
229     {
230         return false;
231     }
232 
233     return true;
234 }
235 
236 
isValidTimestampData(unsigned int year,unsigned int month,unsigned int day,unsigned int hour,unsigned int minute,unsigned int second)237 STAF_INLINE bool STAFTimestamp::isValidTimestampData(unsigned int year,
238     unsigned int month, unsigned int day,  unsigned int hour,
239     unsigned int minute, unsigned int second)
240 {
241     try
242     {
243         STAFTimestamp test(year, month, day, hour, minute, second);
244     }
245     catch (STAFTimestampInvalidDateTimeException)
246     {
247         return false;
248     }
249 
250     return true;
251 }
252 
253 
getElapsedTime(unsigned int seconds)254 STAF_INLINE STAFString STAFTimestamp::getElapsedTime(unsigned int seconds)
255 {
256     if (seconds != 0)
257     {
258         return STAFString(getTimeFormat(seconds/60/60)) + ":" +
259             getTimeFormat(seconds/60 % 60) + ":" +
260             getTimeFormat(seconds % 60);
261     }
262     else
263     {
264         return "00:00:00";
265     }
266 }
267 
268 
asString(const char * format) const269 STAF_INLINE STAFString STAFTimestamp::asString(const char *format) const
270 {
271     char timeString[18] = { 0 };
272     unsigned int osRC = 0;
273 
274     STAFRC_t rc = STAFThreadSafeLocalTimeString(timeString,
275                   sizeof(timeString), format, fTime, &osRC);
276 
277     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTimeString", osRC);
278 
279     return STAFString(timeString);
280 }
281 
282 
operator -(const STAFTimestamp & rhs) const283 STAF_INLINE unsigned int STAFTimestamp::operator-(
284                          const STAFTimestamp &rhs) const
285 {
286     return (unsigned int)difftime(fTime, rhs.fTime);
287 }
288 
289 
asSecondsPastMidnight() const290 STAF_INLINE unsigned int STAFTimestamp::asSecondsPastMidnight() const
291 {
292     struct tm theTime = { 0 };
293     unsigned int osRC = 0;
294     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
295 
296     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
297 
298     return (theTime.tm_hour * 3600) + (theTime.tm_min * 60) + theTime.tm_sec;
299 }
300 
301 
getYear() const302 STAF_INLINE unsigned int STAFTimestamp::getYear() const
303 {
304     struct tm theTime = { 0 };
305     unsigned int osRC = 0;
306     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
307 
308     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
309 
310     return theTime.tm_year + 1900;
311 }
312 
313 
getMonth() const314 STAF_INLINE unsigned int STAFTimestamp::getMonth() const
315 {
316     struct tm theTime = { 0 };
317     unsigned int osRC = 0;
318     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
319 
320     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
321 
322     return theTime.tm_mon + 1;
323 }
324 
325 
getDay() const326 STAF_INLINE unsigned int STAFTimestamp::getDay() const
327 {
328     struct tm theTime = { 0 };
329     unsigned int osRC = 0;
330     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
331 
332     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
333 
334     return theTime.tm_mday;
335 }
336 
337 
getHour() const338 STAF_INLINE unsigned int STAFTimestamp::getHour() const
339 {
340     struct tm theTime = { 0 };
341     unsigned int osRC = 0;
342     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
343 
344     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
345 
346     return theTime.tm_hour;
347 }
348 
349 
getMinute() const350 STAF_INLINE unsigned int STAFTimestamp::getMinute() const
351 {
352     struct tm theTime = { 0 };
353     unsigned int osRC = 0;
354     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
355 
356     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
357 
358     return theTime.tm_min;
359 }
360 
361 
getSecond() const362 STAF_INLINE unsigned int STAFTimestamp::getSecond() const
363 {
364     struct tm theTime = { 0 };
365     unsigned int osRC = 0;
366     STAFRC_t rc = STAFThreadSafeLocalTime(&theTime, fTime, &osRC);
367 
368     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
369 
370     return theTime.tm_sec;
371 }
372 
373 
operator <(const STAFTimestamp & rhs) const374 STAF_INLINE bool STAFTimestamp::operator<(const STAFTimestamp &rhs) const
375 {
376     struct tm myTime = { 0 };
377     struct tm rhsTime = { 0 };
378     unsigned int osRC = 0;
379     STAFRC_t rc = STAFThreadSafeLocalTime(&myTime, fTime, &osRC);
380 
381     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
382 
383     rc = STAFThreadSafeLocalTime(&rhsTime, rhs.fTime, &osRC);
384 
385     STAFTimestampException::checkRC(rc, "STAFThreadSafeLocalTime", osRC);
386 
387     if (myTime.tm_year < rhsTime.tm_year) return true;
388     else if (rhsTime.tm_year < myTime.tm_year) return false;
389 
390     if (myTime.tm_mon < rhsTime.tm_mon) return true;
391     else if (rhsTime.tm_mon < myTime.tm_mon) return false;
392 
393     if (myTime.tm_mday < rhsTime.tm_mday) return true;
394     else if (rhsTime.tm_mday < myTime.tm_mday) return false;
395 
396     if (myTime.tm_hour < rhsTime.tm_hour) return true;
397     else if (rhsTime.tm_hour < myTime.tm_hour) return false;
398 
399     if (myTime.tm_min < rhsTime.tm_min) return true;
400     else if (rhsTime.tm_min < myTime.tm_min) return false;
401 
402     if (myTime.tm_sec < rhsTime.tm_sec) return true;
403 
404     return false;
405 }
406 
407 
getImpl() const408 STAF_INLINE time_t STAFTimestamp::getImpl() const
409 { return fTime; }
410 
411 
isValidDate(unsigned int year,unsigned int month,unsigned int day)412 STAF_INLINE bool STAFTimestamp::isValidDate(unsigned int year,
413                                             unsigned int month,
414                                             unsigned int day)
415 {
416     static unsigned int daysInMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30,
417                                             31, 30, 31 };
418 
419     if (year > 9999) return false;
420     if ((month > 12) || (month < 1)) return false;
421     if (day > daysInMonth[month - 1]) return false;
422 
423     if ((month == 2) && (day == 29))
424     {
425         if ((year % 400) == 0) return true;
426         if ((year % 100) == 0) return false;
427         if ((year % 4) == 0) return true;
428 
429         return false;
430     }
431 
432     return true;
433 }
434 
435 
isValidTime(unsigned int hour,unsigned int min,unsigned int sec)436 STAF_INLINE bool STAFTimestamp::isValidTime(unsigned int hour, unsigned int min,
437                                             unsigned int sec)
438 {
439     if (hour > 23) return false;
440     if (min > 59) return false;
441     if (sec > 59) return false;
442 
443     return true;
444 }
445 
446 
getTimeFormat(unsigned int input)447 STAF_INLINE STAFString STAFTimestamp::getTimeFormat(unsigned int input)
448 {
449     STAFString in = STAFString(input);
450 
451     if (in.length() == 1)
452         return "0" + in;
453     else
454         return in;
455 }
456 
457 
458 // Begin definitions for STAFRelativeTime
459 
STAFRelativeTime()460 STAF_INLINE STAFRelativeTime::STAFRelativeTime()
461 {
462     unsigned int osRC = 0;
463     STAFRC_t rc = STAFTimestampGetRelativeTime(&fRelTime, &osRC);
464 
465     STAFTimestampException::checkRC(rc, "STAFTimestampGetRelativeTime", osRC);
466 }
467 
468 
operator -(const STAFRelativeTime & rhs)469 STAF_INLINE unsigned int STAFRelativeTime::operator-(const STAFRelativeTime &rhs)
470 {
471     unsigned int diffInMillis = 0;
472     STAFRC_t rc = STAFTimestampGetRelativeTimeDifference(fRelTime, rhs.fRelTime,
473                                                          &diffInMillis);
474 
475     STAFTimestampException::checkRC(rc, "STAFTimestampGetRelativeTimeDifference",
476                                     0);
477 
478     return diffInMillis;
479 }
480 
481 
~STAFRelativeTime()482 STAF_INLINE STAFRelativeTime::~STAFRelativeTime()
483 {
484     STAFTimestampFreeRelativeTime(&fRelTime);
485 }
486 
487 #endif
488