(file) Return to CIMDateTime.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2