1 mike 1.10 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.22 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.10 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.22 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.22 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.10 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.22 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.10 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
|
26 kumpf 1.14 // Modified By: Sushma Fernandes, Hewlett-Packard Company
|
27 kumpf 1.17 // (sushma_fernandes@hp.com)
28 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
29 mike 1.10 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 sage 1.23 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
33 #include <Pegasus/Common/Config.h>
34 #endif
35
|
36 mike 1.10 #include <cctype>
|
37 mday 1.31.2.1 #include <cstdlib>
38 #include <cstdio>
|
39 kumpf 1.17 #include <time.h>
|
40 mday 1.19 #include "CIMDateTime.h"
|
41 mday 1.31.2.1 #include "Exception.h"
42 #include "Array.h"
|
43 mike 1.10
|
44 kumpf 1.14 #if defined(PEGASUS_OS_TYPE_WINDOWS)
45 # include <Pegasus/Common/CIMDateTimeWindows.cpp>
46 #elif defined(PEGASUS_OS_TYPE_UNIX)
47 # include <Pegasus/Common/CIMDateTimeUnix.cpp>
48 #elif defined(PEGASUS_OS_TYPE_NSK)
49 # include <Pegasus/Common/CIMDateTimeNsk.cpp>
50 #else
51 # error "Unsupported platform"
52 #endif
53
54 PEGASUS_USING_STD;
55
|
56 mike 1.10 PEGASUS_NAMESPACE_BEGIN
57
58 #define PEGASUS_ARRAY_T CIMDateTime
59 # include "ArrayImpl.h"
60 #undef PEGASUS_ARRAY_T
61
|
62 karl 1.16 // ATTN: P3 KS 04/17/02 Need methods for determining inequalities.
|
63 mike 1.11
|
64 karl 1.16 // ATTN: P3 KS 04/17/02 Need methods for extracting components (e.g., minutes, hours)?
|
65 mike 1.11
|
66 karl 1.16 // ATTN: P3 KS 04/17/02 Needs constructor that creates from individual elements(year,...)
|
67 mike 1.10
68 static const char _NULL_INTERVAL_TYPE_STRING[] = "00000000000000.000000:000";
|
69 karl 1.12 static const char _NULL_DATE_TYPE_STRING[] = "00000000000000.000000-000";
|
70 mike 1.10
|
71 kumpf 1.21 class CIMDateTimeRep
72 {
73 public:
74 enum { FORMAT_LENGTH = 25 };
75
76 //
77 // Length of the string required to store only the date and time without
78 // the UTC sign and UTC offset.
79 // Format is yyyymmddhhmmss.
80 // Note : The size does not include the null byte.
81 //
82 enum { DATE_TIME_LENGTH = 14 };
83
84 //
85 // Length of the string required to store the formatted date and time
86 // Format is yyyy:mm:dd:hh:mm:ss.
87 //
88 enum { FORMATTED_DATE_TIME = 20 };
89
90 char data[FORMAT_LENGTH + 1];
91 };
92 kumpf 1.21
93
|
94 mike 1.10 CIMDateTime::CIMDateTime()
95 {
|
96 kumpf 1.21 _rep = new CIMDateTimeRep();
|
97 mike 1.10 clear();
98 }
99
|
100 mday 1.31.2.1 CIMDateTime::CIMDateTime(const char* str)
|
101 mike 1.10 {
|
102 kumpf 1.21 _rep = new CIMDateTimeRep();
103 if (!_set(str))
104 {
105 delete _rep;
|
106 mday 1.31.2.1 throw BadDateTimeFormat();
|
107 kumpf 1.21 }
|
108 mike 1.10 }
109
110 CIMDateTime::CIMDateTime(const CIMDateTime& x)
111 {
|
112 kumpf 1.21 _rep = new CIMDateTimeRep();
113 memcpy(_rep->data, x._rep->data, sizeof(_rep->data));
|
114 mike 1.10 }
115
116 CIMDateTime& CIMDateTime::operator=(const CIMDateTime& x)
117 {
118 if (&x != this)
|
119 kumpf 1.21 memcpy(_rep->data, x._rep->data, sizeof(_rep->data));
|
120 mike 1.10
121 return *this;
|
122 kumpf 1.17 }
123
124 CIMDateTime::~CIMDateTime()
125 {
|
126 kumpf 1.21 delete _rep;
|
127 mike 1.10 }
128
|
129 mday 1.31.2.1 Boolean CIMDateTime::isNull() const
|
130 mike 1.10 {
|
131 mday 1.31.2.1 return strcmp(_rep->data, _NULL_INTERVAL_TYPE_STRING) == 0;
132 }
133
134 const char* CIMDateTime::getString() const
135 {
136 return _rep->data;
|
137 mike 1.10 }
138
139 void CIMDateTime::clear()
140 {
|
141 kumpf 1.21 strcpy(_rep->data, _NULL_INTERVAL_TYPE_STRING);
|
142 mike 1.10 }
143
|
144 mday 1.31.2.1 Boolean CIMDateTime::_set(const char* str)
|
145 mike 1.10 {
146 clear();
147
148 // Be sure the incoming string is the proper length:
149
|
150 kumpf 1.21 if (strlen(str) != CIMDateTimeRep::FORMAT_LENGTH)
|
151 mike 1.10 return false;
152
153 // Determine the type (date or interval); examine the 21st character;
154 // it must be one of ':' (interval), '+' (date), or '-' (date).
155
156 const Uint32 SIGN_OFFSET = 21;
157 const Uint32 DOT_OFFSET = 14;
158
159 Boolean isInterval = strcmp(&str[SIGN_OFFSET], ":000") == 0;
160
161 if (!isInterval && str[SIGN_OFFSET] != '+' && str[SIGN_OFFSET] != '-')
162 return false;
163
164 // Check for the decimal place:
165
166 if (str[DOT_OFFSET] != '.')
167 return false;
168
169 // Check to see if other characters are digits:
170
|
171 kumpf 1.21 for (Uint32 i = 0; i < CIMDateTimeRep::FORMAT_LENGTH; i++)
|
172 mike 1.10 {
173 if (i != DOT_OFFSET && i != SIGN_OFFSET && !isdigit(str[i]))
174 return false;
175 }
176
177 // Check to see if the month and day are in range (date only):
178
179 char buffer[16];
180
181 if (!isInterval)
182 {
183 // Get the month:
184
185 sprintf(buffer, "%2.2s", str + 4);
186 long month = atoi(buffer);
187
188 if (month == 0 || month > 12)
189 return false;
190
191 // Get the day:
192
193 mike 1.10 sprintf(buffer, "%2.2s", str + 6);
194 long day = atoi(buffer);
195
196 if (day == 0 || day > 31)
197 return false;
198 }
199
200 // Check the hours and minutes:
201
202 sprintf(buffer, "%2.2s", str + 8);
203 long hours = atoi(buffer);
204
|
205 mday 1.31.2.1 if (hours > 24)
|
206 mike 1.10 return false;
207
208 sprintf(buffer, "%2.2s", str + 10);
209 long minutes = atoi(buffer);
210
211 if (minutes > 59)
212 return false;
213
214 sprintf(buffer, "%2.2s", str + 12);
215 long seconds = atoi(buffer);
216
217 if (seconds > 59)
218 return false;
219
|
220 kumpf 1.21 memcpy(_rep->data, str, sizeof(_rep->data));
|
221 mike 1.10
222 return true;
223 }
224
|
225 mday 1.31.2.1 void CIMDateTime::set(const char* str)
|
226 mike 1.10 {
227 if (!_set(str))
|
228 mday 1.31.2.1 throw BadDateTimeFormat();
229 }
230
231 CIMDateTime CIMDateTime::clone() const
232 {
233 return CIMDateTime(*this);
234 }
235
236 PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const CIMDateTime& x)
237 {
238 return os << x.getString();
|
239 mike 1.10 }
240
241 Boolean operator==(const CIMDateTime& x, const CIMDateTime& y)
242 {
|
243 mday 1.31.2.1 return memcmp(x._rep->data, y._rep->data, sizeof(x._rep->data)) == 0;
|
244 kumpf 1.14 }
245
|
246 mday 1.31.2.1 void CIMDateTime::formatDateTime(char* dateTimeStr, tm* tm)
|
247 kumpf 1.14 {
248 Uint32 index = 0, index1 = 0;
249 long year = 0;
250 char buffer[16];
251
252 // Initialize the components of tm structure
253 tm->tm_year = 0;
254 tm->tm_mon = 0;
255 tm->tm_mday = 0;
256 tm->tm_hour = 0;
257 tm->tm_min = 0;
258 tm->tm_sec = 0;
259 tm->tm_isdst = 0;
260 tm->tm_wday = 0;
261 tm->tm_yday = 0;
262
263 // Extract the year.
264 sprintf(buffer, "%4.4s", dateTimeStr);
265 year = atoi(buffer);
266 year = year - 1900;
267 tm->tm_year = year;
268 kumpf 1.14
269 // Extract the Month.
270 sprintf(buffer, "%2.2s", dateTimeStr + 4);
271 tm->tm_mon = atoi(buffer);
272
273 // Extract the Day.
274 sprintf(buffer, "%2.2s", dateTimeStr + 6);
275 tm->tm_mday = atoi(buffer);
276
277 // Extract the Hour.
278 sprintf(buffer, "%2.2s", dateTimeStr + 8);
279 tm->tm_hour = atoi(buffer);
280
281 // Extract the Minutes.
282 sprintf(buffer, "%2.2s", dateTimeStr + 10);
283 tm->tm_min = atoi(buffer);
284
285 // Extract the Seconds.
286 sprintf(buffer, "%2.2s", dateTimeStr + 12);
287 tm->tm_sec = atoi(buffer);
288 }
289 kumpf 1.14
290 Boolean CIMDateTime::isInterval()
291 {
|
292 mday 1.31.2.1 const char* str;
|
293 kumpf 1.14 const Uint32 SIGN_OFFSET = 21;
294
|
295 mday 1.31.2.1 str = getString();
296 Boolean isInterval = strcmp(&str[SIGN_OFFSET], ":000") == 0 ;
|
297 kumpf 1.14
298 return isInterval;
299 }
300
|
301 kumpf 1.20 Sint64 CIMDateTime::getDifference(CIMDateTime startTime, CIMDateTime finishTime)
|
302 kumpf 1.14 {
303 const char* startDateTimeCString;
304 const char* finishDateTimeCString;
305 char* dateTimeOnly;
306 struct tm tmvalStart;
307 struct tm tmvalFinish;
|
308 kumpf 1.20 Sint64 differenceInSeconds = 0;
309 time_t timeStartInSeconds;
310 time_t timeFinishInSeconds;
311 char sign;
312 Uint32 offset;
313 char buffer[4];
|
314 kumpf 1.14
315 //
316 // Get the dates in CString form
317 //
|
318 mday 1.31.2.1 startDateTimeCString = startTime.getString();
319 finishDateTimeCString = finishTime.getString();
|
320 kumpf 1.14
321 //
322 // Check if the startTime or finishTime are intervals
323 //
|
324 kumpf 1.20 if (startTime.isInterval() && finishTime.isInterval())
325 {
326 char intervalBuffer[9];
|
327 mday 1.31.2.1 Uint32 startIntervalDays;
328 Uint32 startIntervalHours;
329 Uint32 startIntervalMinutes;
330 Uint32 startIntervalSeconds;
331 Uint32 finishIntervalDays;
332 Uint32 finishIntervalHours;
333 Uint32 finishIntervalMinutes;
334 Uint32 finishIntervalSeconds;
335 Uint64 startIntervalInSeconds;
336 Uint64 finishIntervalInSeconds;
337 Sint64 intervalDifferenceInSeconds;
|
338 kumpf 1.20
339 // Parse the start time interval and get the days, minutes, hours
340 // and seconds
341
342 // Extract the days.
343 sprintf(intervalBuffer, "%8.8s", startDateTimeCString);
344 startIntervalDays = atoi(intervalBuffer);
345
346 // Extract the Hour.
347 sprintf(intervalBuffer, "%2.2s", startDateTimeCString + 8);
348 startIntervalHours = atoi(intervalBuffer);
349
350 // Extract the Minutes.
351 sprintf(intervalBuffer, "%2.2s", startDateTimeCString + 10);
352 startIntervalMinutes = atoi(intervalBuffer);
353
354 // Extract the Seconds.
355 sprintf(intervalBuffer, "%2.2s", startDateTimeCString + 12);
356 startIntervalSeconds = atoi(intervalBuffer);
357
358 // Parse the finish time interval and get the days, minutes, hours
359 kumpf 1.20 // and seconds
360
361 // Extract the days.
362 sprintf(intervalBuffer, "%8.8s", finishDateTimeCString);
363 finishIntervalDays = atoi(intervalBuffer);
364
365 // Extract the Hour.
366 sprintf(intervalBuffer, "%2.2s", finishDateTimeCString + 8);
367 finishIntervalHours = atoi(intervalBuffer);
368
369 // Extract the Minutes.
370 sprintf(intervalBuffer, "%2.2s", finishDateTimeCString + 10);
371 finishIntervalMinutes = atoi(intervalBuffer);
372
373 // Extract the Seconds.
374 sprintf(intervalBuffer, "%2.2s", finishDateTimeCString + 12);
375 finishIntervalSeconds = atoi(intervalBuffer);
376
377 // Convert all values to seconds and compute the start and finish
378 // intervals in seconds.
|
379 mday 1.31.2.1 startIntervalInSeconds = (Uint64)((startIntervalDays*86400) +
380 (startIntervalHours*3600) +
381 (startIntervalMinutes*60) +
382 startIntervalSeconds) ;
383
384 finishIntervalInSeconds = (Uint64)((finishIntervalDays*86400) +
385 (finishIntervalHours*3600) +
386 (finishIntervalMinutes*60) +
387 finishIntervalSeconds) ;
|
388 kumpf 1.20
389 // Get the difference.
|
390 mday 1.31.2.1 intervalDifferenceInSeconds =(Sint64)(finishIntervalInSeconds -
391 startIntervalInSeconds);
|
392 kumpf 1.20
|
393 mday 1.31.2.1 return intervalDifferenceInSeconds;
|
394 kumpf 1.20 }
395 else if ( startTime.isInterval() || finishTime.isInterval() )
|
396 kumpf 1.14 {
|
397 mday 1.31.2.1 throw BadFormat();
|
398 kumpf 1.14 }
399
400 //
401 // Copy only the Start date and time in to the dateTimeOnly string
402 //
|
403 kumpf 1.21 dateTimeOnly = new char [CIMDateTimeRep::FORMATTED_DATE_TIME];
404 strncpy( dateTimeOnly, startDateTimeCString, CIMDateTimeRep::DATE_TIME_LENGTH );
405 dateTimeOnly[CIMDateTimeRep::DATE_TIME_LENGTH] = 0;
|
406 kumpf 1.14 formatDateTime(dateTimeOnly ,&tmvalStart);
407
408 //
409 // Copy only the Finish date and time in to the dateTimeOnly string
410 //
|
411 kumpf 1.21 strncpy( dateTimeOnly, finishDateTimeCString, CIMDateTimeRep::DATE_TIME_LENGTH );
412 dateTimeOnly[CIMDateTimeRep::DATE_TIME_LENGTH] = 0;
|
413 kumpf 1.14 formatDateTime( dateTimeOnly, &tmvalFinish );
414
|
415 kumpf 1.20 // Convert local time to seconds since the epoch
416 timeStartInSeconds = mktime(&tmvalStart);
417 timeFinishInSeconds = mktime(&tmvalFinish);
418
419 // Convert start time to UTC
420 // Get the sign and UTC offset.
421 sign = startDateTimeCString[21];
422 sprintf(buffer, "%3.3s", startDateTimeCString + 22);
423 offset = atoi(buffer);
424
425 if ( sign == '+' )
426 {
427 // Convert the offset from minutes to seconds and subtract it from
428 // Start time
429 timeStartInSeconds = timeStartInSeconds - ( offset * 60 );
430 }
431 else
432 {
433 // Convert the offset from minutes to seconds and add it to
434 // Start time
435 timeStartInSeconds = timeStartInSeconds + (offset * 60);
436 kumpf 1.20 }
437
438 // Convert finish time to UTC
439 // Get the sign and UTC offset.
440 sign = finishDateTimeCString[21];
441 sprintf(buffer, "%3.3s", finishDateTimeCString + 22);
442 offset = atoi(buffer);
443
444 if ( sign == '+' )
445 {
446 // Convert the offset from minutes to seconds and subtract it from
447 // finish time
448 timeFinishInSeconds = timeFinishInSeconds - ( offset * 60 );
449 }
450 else
451 {
452 // Convert the offset from minutes to seconds and add it to
453 // finish time
454 timeFinishInSeconds = timeFinishInSeconds + (offset * 60);
455 }
456
|
457 kumpf 1.14 //
458 // Get the difference between the two times
459 //
|
460 kumpf 1.20 differenceInSeconds = (Sint64) difftime( timeFinishInSeconds, timeStartInSeconds );
|
461 kumpf 1.14
462 delete []dateTimeOnly;
|
463 mday 1.31.2.1 return differenceInSeconds;
|
464 mike 1.10 }
465
466 PEGASUS_NAMESPACE_END
|