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

Diff for /pegasus/src/Pegasus/Common/CIMDateTime.cpp between version 1.70 and 1.71

version 1.70, 2006/08/16 19:31:25 version 1.71, 2006/09/14 20:11:13
Line 28 
Line 28 
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // //
 //============================================================================== //==============================================================================
 // Author: Mike Brasher (mbrasher@bmc.com)  
 //  
 // Modified By: Sushma Fernandes, Hewlett-Packard Company  
 //                  (sushma_fernandes@hp.com)  
 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)  
 //              Carol Ann Krug Graves, Hewlett-Packard Company  
 //                (carolann_graves@hp.com)  
 //              Willis White (whiwill@ibm.com) PEP #192  
 //              Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)  
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include <time.h>  #include <cstring>
 #include <math.h>  #include <cassert>
 #include <errno.h>  #include <fstream>
 #include "CIMDateTime.h" #include "CIMDateTime.h"
 #include "InternalException.h"  #include "Exception.h"
 #include <Pegasus/Common/AutoPtr.h>  #include "PegasusAssert.h"
 #include <Pegasus/Common/Tracer.h>  
 #include <Pegasus/Common/MessageLoader.h> //l10n  
 #include <Pegasus/Common/PegasusAssert.h>  
   
   
  
 #if defined(PEGASUS_OS_TYPE_WINDOWS)  #if defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
 # include <Pegasus/Common/CIMDateTimeWindows.cpp>  # include <sys/time.h>
 #elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)  #elif defined(PEGASUS_OS_TYPE_WINDOWS)
 # include <Pegasus/Common/CIMDateTimePOSIX.cpp>  # include <sstream>
   # include <iomanip>
   # include <windows.h>
   # include <time.h>
 #else #else
 # error "Unsupported platform"  # error "unsupported platform"
 #endif #endif
  
 PEGASUS_USING_STD; PEGASUS_USING_STD;
Line 68 
Line 57 
 # include "ArrayImpl.h" # include "ArrayImpl.h"
 #undef PEGASUS_ARRAY_T #undef PEGASUS_ARRAY_T
  
 // ATTN: P3 KS 04/17/02 Need methods for determining inequalities.  //==============================================================================
   //
 // ATTN: P3 KS 04/17/02 Need methods for extracting components (e.g., minutes, hours)?  // CIMDateTimeRep
   //
 // ATTN: P3 KS 04/17/02 Needs constructor that creates from individual elements(year,...)  //==============================================================================
   
 static const char _NULL_INTERVAL_TYPE_STRING[] = "00000000000000.000000:000";  
 static const char _NULL_DATE_TYPE_STRING[] = "00000000000000.000000-000";  
 static const Uint64 _TEN_THOUSAND_YEARS = PEGASUS_UINT64_LITERAL(315569520000000000);  
 static const Uint64 _HUNDRED_MILLION_DAYS = PEGASUS_UINT64_LITERAL(8640000000000000000);  
 static const Uint64 _ONE_DAY = PEGASUS_UINT64_LITERAL(86400000000);  
 static const Uint64 _ONE_HOUR = PEGASUS_UINT64_LITERAL(3600000000);  
 static const Uint64 _ONE_MINUTE = 60000000;  
 static const Uint64 _ONE_SECOND = 1000000;  
   
 static const Uint32 _DAYS_IN_YEAR_0 = 366;  
   
 // The number of days preceding the (zero-based) specified month (for  
 // non-leap years)  
 static const Uint32 _MONTH_DAYS[12] =  
     {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};  
   
  
  /* the CIMDateTimeRep class holds the data for the CIMDateTime class as it's protected  
 data members.It also allows for "setting" and "getting" of individual components of  
 date time.  
 */  
 class CIMDateTimeRep class CIMDateTimeRep
 { {
 public: public:
     String microSec;  
     String seconds;  
     String minutes;  
     String hours;  
     String days;  
     String month;  
     String year;  
     String utcOffSet;  
   
     enum { FORMAT_LENGTH = 25 };  
  
     //      // Number of microseconds elapsed since January 1, 1 BCE.
     // Length of the string required to store only the date and time without      Uint64 usec;
     // the UTC sign and UTC offset.  
     // Format is yyyymmddhhmmss.  
     // Note : The size does not include the null byte.  
     //  
     enum { DATE_TIME_LENGTH = 14 };  
  
     //      // UTC offset
     // Length of the string required to store the  formatted date and time      Uint32 utcOffset;
     // Format is yyyy:mm:dd:hh:mm:ss.  
     //  
     enum { FORMATTED_DATE_TIME = 20 };  
  
     //char buffer_day [5];      // ':' for intervals. '-' or '+' for time stamps.
     //    sprintf(yearbuf, "%4d", (days_rem+1));   // day of the month is never 0 (1-31)      Uint16 sign;
     //    ye_mo_da = ye_mo.append(buffer_day);  
  
       // Number of wild characters ('*') used to initialize this object.
       Uint16 numWildcards;
   };
  
     char data[FORMAT_LENGTH + 1];  //==============================================================================
   //
   // Local constants.
   //
   //==============================================================================
  
   // Julian day of "1 BCE January 1".
   static const Uint32 JULIAN_ONE_BCE = 1721060;
  
     /* Checks for correctness and sets the MicroSeconds value of CIMDateTimeRep  // Number of microseconds in one second.
     */  static const Uint64 SECOND = 1000000;
     Uint16 set_microSec(const String & mS);  
  
     /* Checks for correctness and sets the UTC offset of CIMDateTimeRep  // Number of microseconds in one minute.
     */  static const Uint64 MINUTE = 60 * SECOND;
     Boolean set_utcOffSet(const String & uOff);  
  
     /*Changes the CIMDateTimeRep data member data[] .  // Number of microseconds in one hour.
     @param value - value to be inserted into data[]  static const Uint64 HOUR = 60 * MINUTE;
     @param index - position in data[] to start inserting the value  
     @param size - size of the value paramiter (number of characters  
     */  
     void set_data(const String & value, Uint32 index, Uint32 size);  
  
   // Number of microseconds in one day.
   static const Uint64 DAY = 24 * HOUR;
  
     /* these set functions are not used yet.  // Number of microseconds in ten thousand years.
     when they become used the enum CIMDateTime::Field should be moved to CIMDateTimeRep  static const Uint64 TEN_THOUSAND_YEARS =
     */      PEGASUS_UINT64_LITERAL(315569520000000000);
     void set_seconds(const String & sec);  
     void set_minutes(const String & min);  
     void set_hours(const String & ho);  
     void set_days(const String & da);  
     void set_month(const String & mon);  
     void set_year(const String & ye);  
  
     void copy(const CIMDateTimeRep * cTR);  // Number of microseconds in one million days.
   static const Uint64 HUNDRED_MILLION_DAYS =
       PEGASUS_UINT64_LITERAL(8640000000000000000);
  
  };  // Adding this to the POSIX 1970 microseconds epoch produces a 1 BCE epoch
   // as used by this class.
   static const Uint64 POSIX_1970_EPOCH_OFFSET  =
       PEGASUS_UINT64_LITERAL(62167201200000000);
  
   //==============================================================================
   //
   // Local functions.
   //
   //==============================================================================
  
 /* this method  copies the all the information from one CIMDateTimeRep to another  /** Returns true if argument is a leap year.
 */ */
 void CIMDateTimeRep::copy(const CIMDateTimeRep * cTR)  static inline bool _isLeapYear(Uint32 year)
 { {
     //cout << "Start of Rep::copy" << endl;      return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
     microSec = cTR->microSec;  
     seconds = cTR->seconds;  
     minutes = cTR->minutes;  
     hours = cTR->hours;  
     days = cTR->days;  
     month = cTR->month;  
     year = cTR->year;  
     utcOffSet = cTR->utcOffSet;  
     memcpy(data, cTR->data, sizeof(data));  
     //cout << "end of Rep::copy" << endl <<endl;  
 }  
   
 /* set_microSec checks the format of the string that will be  
 used as the micro seconds value. If the format is correct it sets the  
 micro seconds value  
 */  
 Uint16 CIMDateTimeRep::set_microSec(const String & mS)  
 {  
     //  String fin_data = sum_data.append(mS.subString(21,4));  
   
     //cout << "begining of set_microSec" << endl;  
     Uint32 ast_post;  
   
     ast_post = mS.find("*");  
     if (ast_post == PEG_NOT_FOUND) {  
         set_data(mS, 15, 6);  
         microSec = mS;  
         return 2;  
     }  
   
    // cout << "after find  block" << endl;  
     Uint32 sub_len = 6 - ast_post;  
     String ast = "******";  
     String in_comp = mS.subString(ast_post, sub_len);  
     if (!String::compare(in_comp, ast, sub_len)){  
         set_data(mS, 15, 6);  
         microSec = mS;  
         return 0;  
     }  
     else{  
        // cout << "error in set_microSec - this is the value " << mS << endl;  
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
           "Error in CIMDateTimeRep::set_microSec - '*' was found in micor second string");  
         return 1;  
     }  
 } }
  
   /** Calculates the number of days in a given month, accounting for leap year.
 /*set_data set the data member CIMDateTimeRep::set_data  
 */ */
 void CIMDateTimeRep::set_data(const String & value, Uint32 index, Uint32 size)  static Uint32 _getDaysPerMonth(Uint32 year, Uint32 month)
 { {
     for (Uint32 i=0; i < size; i++) {      static char _daysPerMonth[] =
         data[index+i] = (char) value[i];  
     }  
 }  
   
   
 /* the following 6 methods are not used  
 */  
 void CIMDateTimeRep::set_seconds(const String & sec)  
 { {
     seconds = sec;          31, /* JAN */
 }          28, /* FEB */
           31, /* MAR */
           30, /* APR */
           31, /* MAY */
           30, /* JUN */
           31, /* JUL */
           31, /* AUG */
           30, /* SEP */
           31, /* OCT */
           30, /* NOV */
           31, /* DEC */
       };
  
 void CIMDateTimeRep::set_minutes(const String & min)      // If February:
 {  
     minutes = min;  
 }  
  
 void CIMDateTimeRep::set_hours(const String & ho)      if (month == 2 && _isLeapYear(year))
 {          return 29;
     hours = ho;  
 }  
  
 void CIMDateTimeRep::set_days(const String & da)      return _daysPerMonth[month - 1];
 {  
     days = da;  
 } }
  
 void CIMDateTimeRep::set_month(const String & mon)  /** Convert month, day, and year to a Julian day (in the Gregorian calendar).
       Return julian day.
   */
   static inline Uint32 _toJulianDay(Uint32 year, Uint32 month, Uint32 day)
 { {
     month = mon;      // Formula adapted from "FREQUENTLY ASKED QUESTIONS ABOUT CALENDARS"
 }      // (see http://www.tondering.dk/claus/calendar.html).
  
 void CIMDateTimeRep::set_year(const String & ye)      int a = (14 - month)/12;
 {      int y = year+4800-a;
     year = ye;      int m = month + 12*a - 3;
       return day + (153*m+2)/5 + y*365 + y/4 - y/100 + y/400 - 32045;
 } }
  
 /* set_utcOffSet checks the format of the string representing the UTC  /** Convert a Julian day number (in the Gregorian calendar) to year, month,
 offset if it is correct it sets the data member CIMDateTimeRep::utcOffSet      and day.
 */ */
 Boolean CIMDateTimeRep::set_utcOffSet(const String & uOffSet)  static inline void _fromJulianDay(
       Uint32 jd, Uint32& year, Uint32& month, Uint32& day)
 { {
     if (uOffSet.size() != 4) {      // Formula adapted from "FREQUENTLY ASKED QUESTIONS ABOUT CALENDARS"
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,      // (see http://www.tondering.dk/claus/calendar.html).
               "The size of the UTC offset is %d but is but it should be 4", uOffSet.size());  
         return false;  
     }  
  
     Char16 ch_one = uOffSet[0];      int a = jd + 32044;
     if (ch_one != ':' && ch_one != '+' && ch_one != '-') {      int b = (4*a+3)/146097;
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,      int c = a - (b*146097)/4;
         "The UTC off set must begin with a ':' or '+' or '-'. The value of the first character of UTC offset is %u", static_cast<Uint16>(ch_one));      int d = (4*c+3)/1461;
         return false;      int e = c - (1461*d)/4;
       int m = (5*e+2)/153;
       day   = e - (153*m+2)/5 + 1;
       month = m + 3 - 12*(m/10);
       year  = b*100 + d - 4800 + m/10;
     }     }
  
     // the UTC must not have asterisks in it  /** Optimized version of _strToUint32() for n=2 case.
     Uint32 spot = uOffSet.find("*");  */
     if (spot != PEG_NOT_FOUND)  static inline bool _strToUint32_n2(const Uint16* s, Uint32& x)
     {     {
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,      Uint32 c0 = s[0] - '0';
                       "'*' was found in the UTC offset this is not allowed");  
         return false;  
     }  
  
       if (c0 > 9)
     String uOff_num = uOffSet.subString(1,3);  
     for (int i=0; i < 3; i++)  
     {  
         if ((uOff_num[i] < '0') || (uOff_num[i] > '9'))  
         {  
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                  "Format is wrong - UTC offset contains non digit character.");  
             return false;             return false;
         }  
     }  
  
     // intervals (:) must have 000 utc offset      Uint32 c1 = s[1] - '0';
     if ((ch_one == (char)':') && !String::equal(uOff_num, "000"))  
     {      if (c1 > 9)
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                       "Trying to incorrectly set a intervals time zone");  
         return false;         return false;
     }  
  
     utcOffSet =  uOffSet;      x = 10 * c0 + c1;
     set_data(uOffSet, 21, 4);   // change _rep->data to reflect changes made  
  
     return true;     return true;
 } }
  
   /** Powers of ten.
   */
   static const Uint32 _tens[] =
   {
       1,
       10,
       100,
       1000,
       10000,
       100000,
       1000000,
       10000000,
   };
  
 /*Constructor  /** Convert the next n digits to integer. Return true on success. Return
       false if a non-digit was encountered in the first n characters. Don't
       call with n > 8.
 */ */
 CIMDateTime::CIMDateTime()  static inline bool _strToUint32(const Uint16* s, size_t n, Uint32& x)
 { {
     _rep = new CIMDateTimeRep();      switch (n)
     AutoPtr<CIMDateTimeRep> rep(_rep);      {
           case 2:
               return _strToUint32_n2(s, x);
  
     clear();          default:
           {
               x = 0;
  
     rep.release();              const Uint32* m = _tens;
 }  
  
 /*Takes properly formated string and creates a CIMDateTime out of it              for (const Uint16* p = &s[n]; n--; )
 */  
 CIMDateTime::CIMDateTime(const String & str)  
 { {
     _rep = new CIMDateTimeRep();                  Uint16 c = *--p - '0';
     AutoPtr<CIMDateTimeRep> rep(_rep);  
  
     if (!_set(str))                  if (c > 9)
     {                      return false;
         throw InvalidDateTimeFormatException();  
                   x += *m++ * c;
     }     }
  
     rep.release();              return true;
           }
       }
 } }
  
 /*Copy constructor  /** Parse the integer component pointed to by s. Return WILDCARD if s consists
       entirely of '*' characters. Returns the integer if it consists entirely
       of digits. Throw exception if digits and '*' are mixed. Also throw
       exception if digits are encountered when priorWildcards parameter is true.
 */ */
 CIMDateTime::CIMDateTime(const CIMDateTime& x)  static inline Uint32 _parseComponent(
       const Uint16*& s, size_t n, bool& priorWildcards)
 { {
     _rep = new CIMDateTimeRep();      // Check whether all characters are '*'.
     AutoPtr<CIMDateTimeRep> rep(_rep);  
  
     _rep->copy(x._rep);      if (*s == '*')
       {
     rep.release();          bool allWild = true;
 }  
  
 CIMDateTime::CIMDateTime(Uint64 microSec, Boolean interval)          for (size_t i = 0; i < n; i++)
 { {
     if (microSec >= _TEN_THOUSAND_YEARS && !interval)              if (s[i] != '*')
     {     {
         MessageLoaderParms parms(                  allWild = false;
             "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",                  break;
             "Cannot create a CIMDateTime time stamp beyond the year 10,000");              }
         throw DateTimeOutOfRangeException(parms);  
     }     }
  
     if (microSec >= _HUNDRED_MILLION_DAYS && interval)          if (allWild)
     {     {
         MessageLoaderParms parms(              s += n;
             "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",              priorWildcards = true;
             "Cannot create a CIMDateTime interval greater than 100 million "              return Uint32(-1);
                 "days");          }
         throw DateTimeOutOfRangeException(parms);  
     }     }
  
     Uint32 year = 0;      if (priorWildcards)
     Uint32 month = 0;          throw InvalidDateTimeFormatException();
     Uint32 day = 0;  
     Uint32 hour = 0;  
     Uint32 minute = 0;  
     Uint32 second = 0;  
     Uint32 microsecond = 0;  
     char buffer[26];  
   
     microsecond = microSec % 1000000;  
     microSec /= 1000000;  
   
     second = microSec % 60;  
     microSec /= 60;  
   
     minute = microSec % 60;  
     microSec /= 60;  
  
     hour = microSec % 24;      Uint32 x;
     microSec /= 24;  
  
     if (interval)      if (!_strToUint32(s, n, x))
     {          throw InvalidDateTimeFormatException();
         day = microSec;  
  
         sprintf(      s += n;
             buffer,      return x;
             "%08u%02u%02u%02u.%06u:000",  
             day,  
             hour,  
             minute,  
             second,  
             microsecond);  
     }     }
     else  
   /** Return true if all characters of the string are asterisks.
   */
   static inline bool _allAsterisks(const Uint16* s, size_t n)
     {     {
         Uint32 daysRemaining = microSec;      for (size_t i = 0; i < n; i++)
         if (daysRemaining >= _DAYS_IN_YEAR_0)  
         {         {
             const Uint32 _DAYS_IN_400_YEARS = 146097;          if (s[i] != '*')
             const Uint32 _DAYS_IN_100_YEARS = 36524;              return false;
             const Uint32 _DAYS_IN_4_YEARS = 1461;      }
  
             // Account for year 0      return true;
             year = 1;  }
             daysRemaining -= _DAYS_IN_YEAR_0;  
  
             year += (daysRemaining / _DAYS_IN_400_YEARS) * 400;  /** Parse the microseconds component of the given string (6 characters).
             daysRemaining -=      Set numSignificantMicrosecondDigits to the number of leading significant
                 daysRemaining / _DAYS_IN_400_YEARS * _DAYS_IN_400_YEARS;      digits (non-asterisks). Note that once an asterisk is encountered, all
       subsequent characters must be asterisks. Returns the number of
       microseconds. Throws an exception if priorWildcards is true and any digits
       are encountered or if digits occurs after asterisks.
   */
   static Uint32 _parseMicroseconds(
       const Uint16*& s,
       bool priorWildcards,
       Uint16& numSignificantDigits)
   {
       static const Uint32 _mult[] = { 100000, 10000, 1000, 100, 10, 1, };
  
             year += (daysRemaining / _DAYS_IN_100_YEARS) * 100;      // If wildcards encountered in previous components, then the first
             daysRemaining -=      // character must be an asterisk.
                 daysRemaining / _DAYS_IN_100_YEARS * _DAYS_IN_100_YEARS;  
  
             year += (daysRemaining / _DAYS_IN_4_YEARS) * 4;      if (priorWildcards && s[0] != '*')
             daysRemaining -=          throw InvalidDateTimeFormatException();
                 daysRemaining / _DAYS_IN_4_YEARS * _DAYS_IN_4_YEARS;  
  
             year += daysRemaining / 365;      // Examine characters left to right.
             daysRemaining -= daysRemaining / 365 * 365;  
         }  
  
         // Determine whether this is a leap year      numSignificantDigits = 0;
         Boolean leapYear =      Uint32 x = 0;
             (((year%4 == 0) && (year%100 != 0)) || (year%400 == 0));  
  
         // Calculate the month      for (size_t i = 0; i < 6; i++)
         for (Uint32 m = 12; m > 0; m--)  
         {         {
             Uint32 monthDays = _MONTH_DAYS[m-1];          Uint32 c = s[i] - '0';
             if ((m > 2) && leapYear)  
           if (c < 10)
             {             {
                 monthDays += 1;              // A digit:
               x += c * _mult[i];
             }             }
           else if (c == Uint32('*' - '0'))
           {
               // An asterisk:
               numSignificantDigits = Uint16(i);
   
               // All remaining characters must be asterisks.
   
               if (!_allAsterisks(s + i, 6 - i))
                   throw InvalidDateTimeFormatException();
  
             if (daysRemaining >= monthDays)              s += 6;
               return x;
           }
           else
             {             {
                 month = m;              // An illegal character.
                 daysRemaining -= monthDays;              throw InvalidDateTimeFormatException();
                 break;  
             }             }
         }         }
  
         // Calculate the day (days of the month start with 1)      numSignificantDigits = 6;
         day = daysRemaining + 1;      s += 6;
       return x;
         sprintf(  
             buffer,  
             "%04u%02u%02u%02u%02u%02u.%06u+000",  
             year,  
             month,  
             day,  
             hour,  
             minute,  
             second,  
             microsecond);  
     }     }
  
     _rep = new CIMDateTimeRep();  /** Similar to strcmp() but accounts for wildcards. Compares the first twenty
     AutoPtr<CIMDateTimeRep> rep(_rep);      five corresponding characters of s1 and s2. Returns the first non-zero
       difference, unless one of the characters is an asterisk, in which case
       it proceeds to the next character. The return value has the following
       meaning:
  
     if (!_set(String(buffer)))            0 : s1 is lexographically equal to s2
           < 0 : s1 is lexographically less than s2
           > 0 : s1 is lexographically greather than s2
   */
   static int _matchTimeStampStrings(const char* s1, const char* s2)
     {     {
         PEGASUS_ASSERT(false);      for (size_t i = 0; i < 25; i++)
       {
           char c1 = s1[i];
           char c2 = s2[i];
   
           if (c1 == '*' || c2 == '*')
               continue;
   
           int r = c1 - c2;
   
           if (r)
               return r;
     }     }
  
     rep.release();      // Identical
       return 0;
 } }
  
 /*copies CIMDateTimeRep from passed in paramiter to the the callers CIMDateTimeRep  /** Normalize timestamps by including the utcOffset in the usec member and
 effectivly copies value of one CIMDateTime to another. All data in held in      then setting utcOffset to zero.
 CIMDateTimeRep  
 */ */
 CIMDateTime& CIMDateTime::operator=(const CIMDateTime& x)  static inline void _normalize(CIMDateTimeRep* in)
 { {
     //cout << "in copy constructor" << cout;      if (in->sign != ':')
     if (&x != this){      {
         _rep->copy(x._rep);          // DDDDDDDDHHMMSS.MMMMMM:000
     }  
         //memcpy(_rep->data, x._rep->data, sizeof(_rep->data));  
  
     return *this;          Uint64 hours = (in->utcOffset / 60) * HOUR;
 }          Uint64 minutes = (in->utcOffset % 60) * MINUTE;
  
 CIMDateTime::~CIMDateTime()          // If minutes not wildcarded.
 {          // Else if hours not wildcarded.
     delete _rep;  
 }  
  
 /* retruns a string holding the CIMDateTime value          if (in->numWildcards < 10)
 */  
 String CIMDateTime::toString () const  
 { {
     return String (_rep->data);              if (in->sign == '+')
                   in->usec -= hours + minutes;
               else
                   in->usec += hours + minutes;
 } }
           else if (in->numWildcards < 12)
 /* sets a CIMDateTime to a zero valued interval  
 */  
 void CIMDateTime::clear()  
 { {
    //cout << "this is the start of the clear method" << endl;              if (in->sign == '+')
    strcpy(_rep->data, _NULL_INTERVAL_TYPE_STRING);                  in->usec -= hours;
     String blank = "";              else
     String str = String("000000");                  in->usec += hours;
     Uint16 dum = _rep->set_microSec(str);  
     _rep->set_seconds("00");  
     _rep->set_minutes("00");  
     _rep->set_hours("00");  
     _rep->set_days("00");  
     _rep->set_utcOffSet(String(":000"));  
    //cout << "end of the clear method" << endl << endl;  
   
 } }
  
           in->utcOffset = 0;
           in->sign = '+';
       }
   }
  
 /* this is one of the only ways to create a CIMDateTime object most of the constructors  /** Converts the representation object to microseconds. For intervals, this
 call this method. It checks the value of each filed and returns false if any of them do      quantity is the same as usec member. Time stamps are normalized so that
 not have the correct format      the usec component contains the UTF offset.
 */ */
 Boolean CIMDateTime::_set(const String & dateTimeStr)  static Uint64 _toMicroSeconds(const CIMDateTimeRep* rep)
 { {
     clear();      if (rep->sign == ':')
     CString dtStr = dateTimeStr.getCString();          return rep->usec;
     const char* str = dtStr;  
   
  
     // Be sure the incoming string is the proper length:      CIMDateTimeRep tmp = *rep;
     if (dateTimeStr.size() != CIMDateTimeRep::FORMAT_LENGTH){      _normalize(&tmp);
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,      return tmp.usec;
               "CIMDateTime object string is not of the proper length");  
         return false;  
     }     }
  
   /** Converts a CIMDateTimeRep representation to its canonical string
       representation as defined in the "CIM infrastructure Specification".
       Note that this implementation preserves any wildcard characters used
       to initially create the CIMDateTime object.
   */
   static void _toCStr(const CIMDateTimeRep* rep, char buffer[26])
   {
       if (rep->sign == ':')
       {
           // Extract components:
  
     // Determine the type (date or interval); examine the 21st character;          Uint64 usec = rep->usec;
     // it must be one of ':' (interval), '+' (date), or '-' (date)          Uint32 microseconds = Uint32(usec % SECOND);
     const Uint32 SIGN_OFFSET = 21;          Uint32 seconds = Uint32((usec / SECOND) % 60);
     const Uint32 DOT_OFFSET = 14;          Uint32 minutes = Uint32((usec / MINUTE) % 60);
     Boolean isInterval = (dateTimeStr[SIGN_OFFSET] == ':');          Uint32 hours = Uint32((usec / HOUR) % 24);
           Uint32 days = Uint32((usec / DAY));
     if (!isInterval && dateTimeStr[SIGN_OFFSET] != '+' && dateTimeStr[SIGN_OFFSET] != '-'){  
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
              "CIMDateTime object has an incorrect format.");  
         return false;  
     }  
   
  
     // Check for the decimal place:          // Format the string.
  
     if (dateTimeStr[DOT_OFFSET] != '.'){          sprintf(
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,              buffer,
              "Incorrect Format - CIMDateTime object dosen't have decimal point in position 14");              "%08u%02u%02u%02u.%06u:000",
         return false;              Uint32(days),
               Uint32(hours),
               Uint32(minutes),
               Uint32(seconds),
               Uint32(microseconds));
     }     }
       else
       {
           // Extract components:
  
           Uint64 usec = rep->usec;
           Uint32 microseconds = Uint32(usec % SECOND);
           Uint32 seconds = Uint32((usec / SECOND) % 60);
           Uint32 minutes = Uint32((usec / MINUTE) % 60);
           Uint32 hours = Uint32((usec / HOUR) % 24);
           Uint32 days = Uint32((usec / DAY));
           Uint32 jd = Uint32(days + JULIAN_ONE_BCE);
   
           // Convert back from julian to year/month/day:
   
           Uint32 year;
           Uint32 month;
           Uint32 day;
           _fromJulianDay(jd, year, month, day);
  
           // Format the string.
  
     // Check to see if other characters are digits or astrisks (*)          sprintf(
               buffer,
               "%04u%02u%02u%02u%02u%02u.%06u%c%03d",
               Uint32(year),
               Uint32(month),
               Uint32(day),
               Uint32(hours),
               Uint32(minutes),
               Uint32(seconds),
               Uint32(microseconds),
               rep->sign,
               rep->utcOffset);
       }
   
       // Fill buffer with '*' chars (if any).
       {
           char* first = buffer + 20;
           char* last = buffer + 20 - rep->numWildcards;
   
           if (rep->numWildcards > 6)
               last--;
   
           for (; first != last; first--)
           {
               if (*first != '.')
                   *first = '*';
           }
       }
   }
   
   /** This table is used to convert integers between 0 and 99 (inclusive) to
       a char16 array, with zero padding.
   */
   static Uint16 _intToStrTable[][2] =
   {
       { '0', '0', },
       { '0', '1', },
       { '0', '2', },
       { '0', '3', },
       { '0', '4', },
       { '0', '5', },
       { '0', '6', },
       { '0', '7', },
       { '0', '8', },
       { '0', '9', },
       { '1', '0', },
       { '1', '1', },
       { '1', '2', },
       { '1', '3', },
       { '1', '4', },
       { '1', '5', },
       { '1', '6', },
       { '1', '7', },
       { '1', '8', },
       { '1', '9', },
       { '2', '0', },
       { '2', '1', },
       { '2', '2', },
       { '2', '3', },
       { '2', '4', },
       { '2', '5', },
       { '2', '6', },
       { '2', '7', },
       { '2', '8', },
       { '2', '9', },
       { '3', '0', },
       { '3', '1', },
       { '3', '2', },
       { '3', '3', },
       { '3', '4', },
       { '3', '5', },
       { '3', '6', },
       { '3', '7', },
       { '3', '8', },
       { '3', '9', },
       { '4', '0', },
       { '4', '1', },
       { '4', '2', },
       { '4', '3', },
       { '4', '4', },
       { '4', '5', },
       { '4', '6', },
       { '4', '7', },
       { '4', '8', },
       { '4', '9', },
       { '5', '0', },
       { '5', '1', },
       { '5', '2', },
       { '5', '3', },
       { '5', '4', },
       { '5', '5', },
       { '5', '6', },
       { '5', '7', },
       { '5', '8', },
       { '5', '9', },
       { '6', '0', },
       { '6', '1', },
       { '6', '2', },
       { '6', '3', },
       { '6', '4', },
       { '6', '5', },
       { '6', '6', },
       { '6', '7', },
       { '6', '8', },
       { '6', '9', },
       { '7', '0', },
       { '7', '1', },
       { '7', '2', },
       { '7', '3', },
       { '7', '4', },
       { '7', '5', },
       { '7', '6', },
       { '7', '7', },
       { '7', '8', },
       { '7', '9', },
       { '8', '0', },
       { '8', '1', },
       { '8', '2', },
       { '8', '3', },
       { '8', '4', },
       { '8', '5', },
       { '8', '6', },
       { '8', '7', },
       { '8', '8', },
       { '8', '9', },
       { '9', '0', },
       { '9', '1', },
       { '9', '2', },
       { '9', '3', },
       { '9', '4', },
       { '9', '5', },
       { '9', '6', },
       { '9', '7', },
       { '9', '8', },
       { '9', '9', },
   };
  
     for (Uint32 i = 0; i < CIMDateTimeRep::FORMAT_LENGTH; i++)  /** Convert integer x to a zero-padded char16 string. Legal for x less than
       100000000.
   */
   static inline void _intToChar16String(Uint32 x, Uint16*& str, size_t numDigits)
     {     {
         if (!((i == DOT_OFFSET) || (i == SIGN_OFFSET) ||      if (numDigits == 2)
               ((dateTimeStr[i] >= '0') && (dateTimeStr[i] <= '9')) ||  
               (dateTimeStr[i] == '*')))  
         {         {
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,          str[0] = _intToStrTable[x][0];
                     "CIMdateTime object has an incorrect format.");          str[1] = _intToStrTable[x][1];
             return false;          str += 2;
         }          return;
     }     }
  
       while (numDigits--)
     // Check to see if the month and day are in range (date only):  
   
     String buffer;  
     Field ans;  
   
     if (!isInterval)  
     {     {
       //get year          Uint32 d = _tens[numDigits];
       /* need to check that the field is valid as far as astrisk (*) are concerned */          Uint32 n = x / d;
       buffer = dateTimeStr.subString(0,4);          x %= d;
       ans = fieldcheck(buffer, _rep->year);          *str++ = n + '0';
       if (ans == SOME_WILD_CARDS){  
           Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                "CIMDateTime - Format of the string is incorrect. ");  
           return false;  
       }  
       else if (ans == ONLY_WILD_CARDS) {  
           if (!restOfFields(4,dateTimeStr)){  
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the string is incorrect. All fields after the year \  
                             field should be wild cards.");  
               return false;  
           }           }
       }       }
  
         // Get the month:  static void _toChar16Str(const CIMDateTimeRep* rep, Char16* data_)
         buffer = dateTimeStr.subString(4,2);  {
         ans = fieldcheck(buffer, _rep->month);      Uint16* data = (Uint16*)data_;
         if (ans == SOME_WILD_CARDS) {  
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the month field is incorrect.s");  
            //cout << "one was returned form fieldcheck" << endl << endl;  
             return false;           // month field has both wildcards and digits  
         }  
   
         else if (ans == ONLY_DIGITS) {          // month field has only digits  
             long month = atoi(buffer.getCString());  
   
             // Allow for zero month - default value processing  
             if (month == 0 || month > 12) {  
                 Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the string is incorrect. Month fild is out of range");  
                 return false;  
             }  
         }  
         else if (ans == ONLY_WILD_CARDS) {  
           if (!restOfFields(6,dateTimeStr)){  
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the string is incorrect. All fields after the month \  
                         field should ve wild cards.");  
               return false;  
           }  
         }  
   
   
         // Get the day:  
   
         buffer = dateTimeStr.subString(6,2);  
         ans = fieldcheck(buffer, _rep->days);  
         if (ans == SOME_WILD_CARDS) {  
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the day field is incorrect.");  
             return false;           // month field has both wildcards and digits  
         }  
  
         else if (ans == ONLY_DIGITS) {          // month field has only digits      if (rep->sign == ':')
       {
           // DDDDDDDDHHMMSS.MMMMMM:000
  
             long day = atoi(buffer.getCString());          Uint64 usec = rep->usec;
           Uint32 microseconds = Uint32(usec % SECOND);
           Uint32 seconds = Uint32((usec / SECOND) % 60);
           Uint32 minutes = Uint32((usec / MINUTE) % 60);
           Uint32 hours = Uint32((usec / HOUR) % 24);
           Uint32 days = Uint32((usec / DAY));
  
             // Allow for zero day - 0 "day" values are only allowed for default object          _intToChar16String(days, data, 8);
             /*ATTN: this does not check for the number of days in a          _intToChar16String(hours, data, 2);
             particular month          _intToChar16String(minutes, data, 2);
             */          _intToChar16String(seconds, data, 2);
             if (day == 0 || day > 31){          *data++ = '.';
                 Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,          _intToChar16String(microseconds, data, 6);
                         "CIMDateTime - Format of the string is incorrect. Day field is incorrect");          data[0] = ':';
                 return false;          data[1] = '0';
             }          data[2] = '0';
          }          data[3] = '0';
         else if (ans == ONLY_WILD_CARDS) {  
           if (!restOfFields(6,dateTimeStr)){  
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the string is incorrect. All fields after day field \  
                             should be only wild cards.");  
               return false;  
           }  
         }         }
       else
       {
           // YYYYMMDDHHMMSS.MMMMMMSUTC
  
         //get UTC off set   for a Time Stamp          Uint64 usec = rep->usec;
           Uint32 microseconds = Uint32(usec % SECOND);
           Uint32 seconds = Uint32((usec / SECOND) % 60);
           Uint32 minutes = Uint32((usec / MINUTE) % 60);
           Uint32 hours = Uint32((usec / HOUR) % 24);
           Uint32 days = Uint32((usec / DAY));
           Uint32 jd = Uint32(days + JULIAN_ONE_BCE);
           Uint32 year;
           Uint32 month;
           Uint32 day;
           _fromJulianDay(jd, year, month, day);
  
         buffer = dateTimeStr.subString(21,4);          _intToChar16String(year, data, 4);
         _rep->utcOffSet = buffer;          _intToChar16String(month, data, 2);
         Uint32 spot = buffer.find("*");          _intToChar16String(day, data, 2);
         //cout << "before if" << endl;          _intToChar16String(hours, data, 2);
         if(spot != PEG_NOT_FOUND){  // the UTC must not have astricks in it          _intToChar16String(minutes, data, 2);
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,          _intToChar16String(seconds, data, 2);
                 "CIMDateTime - Format of the is incorrect. UTC offset should not have \          *data++ = '.';
                           a wild card in it.");          _intToChar16String(microseconds, data, 6);
             return false;          *data++ = rep->sign;
           _intToChar16String(rep->utcOffset, data, 3);
         }         }
  
     }  //end of if(!interval)      // Fill buffer with '*' chars (if any).
       {
           Uint16* first = (Uint16*)data_ + 20;
           Uint16* last = (Uint16*)data_ + 20 - rep->numWildcards;
  
     else{     //Object is an Interval          if (rep->numWildcards > 6)
               last--;
  
         //get days if object is an interval          for (; first != last; first--)
         buffer = dateTimeStr.subString(0,8);          {
         ans = fieldcheck(buffer, _rep->days);              if (*first != '.')
         if (ans == SOME_WILD_CARDS) {                  *first = '*';
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the object is incorrect. Day field must be have all \  
                           wild cards or no wild cards.");  
             return false;  
         }         }
         else if (ans == ONLY_WILD_CARDS) {  
           if (!restOfFields(8,dateTimeStr)){  
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                   "CIMDateTime - Format of the object is incorrect. All fields after day field \  
                             should be wild cards.");  
               return false;  
           }           }
         }         }
  
                       //ATTN: this block MAY not be needed  /** Compares the two CIMDateTime representations. The return value is one of
         // check to make sure UTC for Intervals it '000'      the following.
         buffer = dateTimeStr.subString(21,4);  
         _rep->utcOffSet = buffer;  
         if (!String::equal(_rep->utcOffSet, ":000"))  
         {  
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                    "CIMDateTime - Format of the object is incorrect. Can not set the \  
                           the UTC off set of an Interval");  
            // cout << "interval UTC offset is worng" << endl;  
             return false;  
         }  
  
           0   : x is equal to y
           < 0 : x is less than y
           > 0 : x is greater than y
  
     }      This function throws TypeMismatchException if x and y are not of the
       same type (time stamps or intervals).
  
     //cout << "after is interval block" << endl;      Algorithm: If both representations have zero numWildcards members, then
       the comparison is simply _toMicroSeconds(x) - _toMicroSeconds(y). If either
       has a non-zero numWildcards member, then they are converted to to canonical
       string format and compared lexographically with _matchTimeStampStrings().
       If so, then time stamps must be normalized (usec must be adjusted for the
       sign and utcOffset).
   */
   static int _compare(const CIMDateTimeRep* x, const CIMDateTimeRep* y)
   {
       bool xIsInterval = x->sign == ':';
       bool yIsInterval = y->sign == ':';
  
     // Check the hours and minutes:      if (xIsInterval != yIsInterval)
     buffer = dateTimeStr.subString(8,2);      {
     ans = fieldcheck(buffer, _rep->hours);          MessageLoaderParms parms(
     if (ans == SOME_WILD_CARDS) {              "Common.CIMDateTime.INVALID_OPERATION_COMP_DIF",
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,              "Trying to compare CIMDateTime objects of differing types");
                    "CIMDateTime - Format of the object is incorrect.Hour field must have all \          throw TypeMismatchException(parms);
                           wild cards or no wild cards.");  
         return false;           // hour field has both wildcards and digits  
      }  
   
     else if (ans == ONLY_DIGITS) {          // hour field has only digits  
         long hours = atoi(buffer.getCString());  
   
         if (hours > 23) {  
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                    "CIMDateTime - Format of the object is incorrect. Hour value is out of range");  
             return false;  
         }         }
  
     }      if (x->numWildcards == 0 && y->numWildcards == 0)
       {
           Uint64 xm = _toMicroSeconds(x);
           Uint64 ym = _toMicroSeconds(y);
  
     else if (ans == ONLY_WILD_CARDS) {          if (xm < ym)
           if (!restOfFields(10,dateTimeStr)){              return -1;
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,          else if (xm > ym)
                 "CIMDateTime - Format of the object is incorrect. All fields after the hour field \              return 1;
                             should be wild cards.");  
               return false;  
           }  
      }  
  
           return 0;
       }
       else
       {
           if (!xIsInterval)
           {
               // Normalize before comparing.
  
    //cout << "this is after getting hours" << endl;              CIMDateTimeRep x1 = *x;
               _normalize(&x1);
  
     buffer = dateTimeStr.subString(10,2);              CIMDateTimeRep y1 = *y;
     ans = fieldcheck(buffer, _rep->minutes);              _normalize(&y1);
     if (ans == SOME_WILD_CARDS) {  
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                    "CIMDateTime - Format of the object is incorrect.Minute field must have all \  
                           wild cards or no wild cards.");  
         return false;           // minutes field has both wildcards and digits  
     }  
   
     else if (ans == ONLY_DIGITS) {          // minutes field has only digits  
         long minutes = atoi(buffer.getCString());  
   
         if (minutes > 59) {  
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                    "CIMDateTime - Format of the object is incorrect.Minute value is out of range");  
             return false;  
  
               char s1[26];
               char s2[26];
               _toCStr(&x1, s1);
               _toCStr(&y1, s2);
               return _matchTimeStampStrings(s1, s2);
         }         }
           else
           {
               char s1[26];
               char s2[26];
               _toCStr(x, s1);
               _toCStr(y, s2);
               return _matchTimeStampStrings(s1, s2);
     }     }
   
     else if (ans == ONLY_WILD_CARDS) {  
           if (!restOfFields(12,dateTimeStr)){  
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the object is incorrect. All fields after the minute \  
                             field should be wild cards.");  
               return false;  
           }           }
       }       }
  
   //==============================================================================
   //
   // CIMDateTime
   //
   //==============================================================================
  
   const Uint32 CIMDateTime::WILDCARD = Uint32(-1);
  
     // cout << "before getting seconds" << endl;  CIMDateTime::CIMDateTime()
   {
     buffer = dateTimeStr.subString(12,2);      _rep = new CIMDateTimeRep;
     ans = fieldcheck(buffer, _rep->seconds);      memset(_rep, 0, sizeof(CIMDateTimeRep));
     if (ans == SOME_WILD_CARDS) {      _rep->sign = ':';
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                    "CIMDateTime - Format of the object is incorrect.Second field must have all \  
                           wild cards or no wild cards.");  
         return false;           // seconds field has both wildcards and digits  
     }     }
  
   CIMDateTime::CIMDateTime(const CIMDateTime& x)
     else if (ans == ONLY_DIGITS) {          // minutes field has only digits  {
         long seconds = atoi(buffer.getCString());      _rep = new CIMDateTimeRep;
         if (seconds > 59){      memcpy(_rep, x._rep, sizeof(CIMDateTimeRep));
             Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                    "CIMDateTime - Format of the object is incorrect.Minute value is out of range");  
             return false;  
         }         }
  
   CIMDateTime::CIMDateTime(const String& str)
   {
       _rep = new CIMDateTimeRep;
       set(str);
     }     }
     else if (ans == ONLY_WILD_CARDS) {  
           if (!restOfFields(14,dateTimeStr)){  
               Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,  
                 "CIMDateTime - Format of the object is incorrect. All fields after the seconds \  
                             field should have wild cards.");  
               return false;  
           }  
       }  
   
  
     //get micro Seconds  CIMDateTime::CIMDateTime(Uint64 usec, Boolean isInterval)
     String buffer_micro = dateTimeStr.subString(15,6);  {
     Uint32 answ = _rep->set_microSec(buffer_micro);      if (!isInterval && usec >= TEN_THOUSAND_YEARS)
     if (answ == 1) {      {
          Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,          MessageLoaderParms parms(
                 "CIMDateTime - Format of micro seconds field is incorrect");              "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
         return false;              "Cannot create a CIMDateTime time stamp beyond the year 10,000");
           throw DateTimeOutOfRangeException(parms);
     }     }
  
       if (isInterval && usec >= HUNDRED_MILLION_DAYS)
       {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "Cannot create a CIMDateTime interval greater than 100 million "
               "days");
           throw DateTimeOutOfRangeException(parms);
       }
  
     memcpy(_rep->data, str, sizeof(_rep->data));      _rep = new CIMDateTimeRep;
       _rep->usec = usec;
     return true;      _rep->utcOffset = 0;
       _rep->sign = isInterval ? ':' : '+';
       _rep->numWildcards = 0;
   }
   
   CIMDateTime::CIMDateTime(
       Uint32 year,
       Uint32 month,
       Uint32 day,
       Uint32 hours,
       Uint32 minutes,
       Uint32 seconds,
       Uint32 microseconds,
       Uint32 numSignificantMicrosecondDigits,
       Sint32 utcOffset)
   {
       _rep = new CIMDateTimeRep;
       setTimeStamp(year, month, day, hours, minutes, seconds, microseconds,
           numSignificantMicrosecondDigits, utcOffset);
   }
   
   CIMDateTime::CIMDateTime(
       Uint32 days,
       Uint32 hours,
       Uint32 minutes,
       Uint32 seconds,
       Uint32 microseconds,
       Uint32 numSignificantMicrosecondDigits)
   {
       _rep = new CIMDateTimeRep;
       setInterval(days, hours, minutes, seconds, microseconds,
           numSignificantMicrosecondDigits);
 } }
  
   CIMDateTime::CIMDateTime(CIMDateTimeRep* rep) : _rep(rep)
   {
   }
  
   CIMDateTime::~CIMDateTime()
   {
       delete _rep;
   }
  
 /* If a field has a wild card then all the fields with lower significance  CIMDateTime& CIMDateTime::operator=(const CIMDateTime& x)
     should have wild cards. This method makes sure of this.  
 */  
 Boolean CIMDateTime::restOfFields(Uint32 start_position,const String & inStr)  
 { {
     String splatCDT = "**************.******";      if (this != &x)
     Uint32 placeNum = splatCDT.size() - start_position;          memcpy(_rep, x._rep, sizeof(CIMDateTimeRep));
  
     String comp = splatCDT.subString(start_position, placeNum);      return *this;
     String in_comp = inStr.subString(start_position, placeNum);  
     if (String::compare(comp, in_comp))  
         return false;  
     else  
         return true;  
 } }
  
   void CIMDateTime::clear()
   {
       memset(_rep, 0, sizeof(CIMDateTimeRep));
       _rep->sign = ':';
   }
  
   
 /*this method is just a public rapper for the _set command  
 */  
 void CIMDateTime::set(const String & str) void CIMDateTime::set(const String & str)
 { {
     if (!_set(str)){      clear();
         throw InvalidDateTimeFormatException();  
     }  
 }  
  
       if (str.size() != 25)
           throw InvalidDateTimeFormatException();
  
       const Uint16* s = (const Uint16*)str.getChar16Data();
       Uint16 sign = s[21];
  
 /*public rapper for _toMicroSeconds      if (sign == ':')
 converts object to UTC then it calculates the number of microseconds in the converted object  
 */  
 Uint64 CIMDateTime::toMicroSeconds() const  
 { {
           bool priorWildcards = false;
  
     CIMDateTime un_norm;          // It's an interval of the form "DDDDDDDDHHMMSS.MMMMMM:000"
     //un_norm._rep = new CIMDateTimeRep();  
     un_norm._rep->copy(_rep);  
   
     un_norm.convertToUTC();  
   
     const Uint64 norm_micSec = un_norm._toMicroSeconds();  
  
     return (norm_micSec);          // Parse days:
 }  
  
           Uint32 days = _parseComponent(s, 8, priorWildcards);
           Uint32 hours = _parseComponent(s, 2, priorWildcards);
           Uint32 minutes = _parseComponent(s, 2, priorWildcards);
           Uint32 seconds = _parseComponent(s, 2, priorWildcards);
  
 // Returns the number of microseconds represented by a CIMDateTime object          // Skip over dot:
 Uint64 CIMDateTime::_toMicroSeconds()  
 {  
     Uint64 microseconds = 0;  
  
     // Retrieve the microseconds component from the CIMDateTime object          if (*s++ != '.')
     Uint32 microsecondsSplatIndex = _rep->microSec.find('*');              throw InvalidDateTimeFormatException();
     Uint32 microsecondsComponent = 0;  
     if (microsecondsSplatIndex == PEG_NOT_FOUND)  
     {  
         microsecondsComponent = atol(_rep->microSec.getCString());  
     }  
     else if (microsecondsSplatIndex > 0)  
     {  
         String subMic = _rep->microSec.subString(0, microsecondsSplatIndex);  
         microsecondsComponent = (Uint32)atol(subMic.getCString()) *  
             (Uint32)pow((double)10,(double)(6-microsecondsSplatIndex));  
     }  
     else  
     {  
         microsecondsComponent = 0;  
     }  
     microseconds += microsecondsComponent;  
  
     // Retrieve the seconds component from the CIMDateTime object          // Parse microseconds:
     if (_rep->seconds.find('*') == PEG_NOT_FOUND)  
     {  
         Uint64 secondsComponent = atol(_rep->seconds.getCString());  
         microseconds += secondsComponent * 1000000;  
     }  
  
     // Retrieve the minutes component from the CIMDateTime object          Uint16 numSignificantMicrosecondDigits;
     if (_rep->minutes.find('*') == PEG_NOT_FOUND)          Uint32 microseconds = _parseMicroseconds(
     {              s, priorWildcards, numSignificantMicrosecondDigits);
         Uint64 minutesComponent = atol(_rep->minutes.getCString());  
         microseconds += minutesComponent * _ONE_MINUTE;  
     }  
  
     // Retrieve the hours component from the CIMDateTime object          // Skip over ':'.
     if (_rep->hours.find('*') == PEG_NOT_FOUND)  
     {  
         Uint64 hoursComponent = atol(_rep->hours.getCString());  
         microseconds += hoursComponent * _ONE_HOUR;  
     }  
  
     if (isInterval())          s++;
     {  
         // Retrieve the days component from the CIMDateTime object  
         if (_rep->days.find('*') == PEG_NOT_FOUND)  
         {  
             Uint64 daysComponent = atol(_rep->days.getCString());  
             microseconds += daysComponent * _ONE_DAY;  
         }  
     }  
     else  
     {  
         // Retrieve the day component from the CIMDateTime object  
         if (_rep->days.find('*') == PEG_NOT_FOUND)  
         {  
             Uint64 dayComponent = atol(_rep->days.getCString());  
             microseconds += (dayComponent-1) * _ONE_DAY;  
         }  
  
         // Retrieve the month and year components from the CIMDateTime object          // Expect "000".
         if (_rep->year.find('*') == PEG_NOT_FOUND)  
         {  
             Uint64 yearComponent = atol(_rep->year.getCString());  
  
             // Retrieve the month component from the CIMDateTime object.          if (!(s[0] == '0' && s[1] == '0' && s[2] == '0'))
             if (_rep->month.find('*') == PEG_NOT_FOUND)              throw InvalidDateTimeFormatException();
             {  
                 Uint32 monthComponent = atol(_rep->month.getCString());  
                 PEGASUS_ASSERT((monthComponent > 0) && (monthComponent < 13));  
  
                 Uint32 monthDays = _MONTH_DAYS[monthComponent-1];          // Set representation:
                 if ((monthComponent > 2) && ((yearComponent%400 == 0) ||  
                     ((yearComponent%4 == 0) && (yearComponent%100 != 0))))  
                 {  
                     // Add the leap day  
                     monthDays += 1;  
                 }  
  
                 // Convert months to days and then to microseconds          setInterval(
                 microseconds += monthDays * _ONE_DAY;              days,
               hours,
               minutes,
               seconds,
               microseconds,
               numSignificantMicrosecondDigits);
             }             }
       else if (sign == '-' || sign == '+')
             if (yearComponent > 0)  
             {             {
                 // Convert years into microseconds, factoring in leap years          bool priorWildcards = false;
                 yearComponent -= 1;  
                 microseconds +=  
                     (_DAYS_IN_YEAR_0 +  
                      yearComponent/400 * 146097 +  
                      yearComponent%400/100 * 36524 +  
                      yearComponent%100/4 * 1461 +  
                      yearComponent%4 * 365) *  
                     _ONE_DAY;  
             }  
         }  
     }  
  
     return microseconds;          // It's a time stamp of the form "YYYYMMDDHHMMSS.MMMMMMSUTC"
 }  
  
           // Parse year, month, day, hours, minutes, seconds:
  
 /*compare two CIMDateTime objects for equality          Uint32 year = _parseComponent(s, 4, priorWildcards);
 */          Uint32 month = _parseComponent(s, 2, priorWildcards);
 Boolean operator==(const CIMDateTime& x, const CIMDateTime& y)          Uint32 day = _parseComponent(s, 2, priorWildcards);
 {          Uint32 hours = _parseComponent(s, 2, priorWildcards);
     return x.equal (y);          Uint32 minutes = _parseComponent(s, 2, priorWildcards);
 }          Uint32 seconds = _parseComponent(s, 2, priorWildcards);
  
           // Skip over dot:
  
           if (*s++ != '.')
               throw InvalidDateTimeFormatException();
  
 /* converts Time Stamps to their UTC (GMT) representation. For Intervals          // Parse microseconds:
     it does nothing.  
 */  
 void CIMDateTime::convertToUTC()  
 {  
  
     if (isInterval()) {          Uint16 numSignificantMicrosecondDigits;
         return;    //no conversion should not be done on Intervals          Uint32 microseconds = _parseMicroseconds(
     }              s, priorWildcards, numSignificantMicrosecondDigits);
  
     Uint64 normNum = 0;          // Skip over sign:
  
     Uint64 un_normNum = this->_toMicroSeconds();          s++;
  
    // Uint32 unnor = un_normNum/PEGASUS_UINT64_LITERAL(1000000000);          // Parse UTF offset.
    // Uint32 runnor = un_normNum%PEGASUS_UINT64_LITERAL(1000000000);  
  
     // get UTC offSet and change it in microseconds          Uint32 utcOffset;
     String utcOS = _rep->utcOffSet.subString(1,3);  
     Uint32 offSet = atol((utcOS).getCString());  
     Uint64 offSet_hor = (offSet/60) * _ONE_HOUR;  
     Uint64 offSet_min = (offSet%60) * _ONE_MINUTE;  
     String mesO = "overflow has occurred in normalization";  
     MessageLoaderParms parmsOv("Common.CIMDateTime.UTC_OVERFLOW",  
         "overflow has occurred during conversion to UTC");  
     MessageLoaderParms parmsUn("Common.CIMDateTime.UTC_UNDERFLOW",  
         "underflow has occurred during conversion to UTC");  
  
     char sign;   // Get the sign and UTC offset.          if (!_strToUint32(s, 3, utcOffset))
     sign = _rep->data[21];              throw InvalidDateTimeFormatException();
  
     //if there are no wild cards in the minute postion then the entire utc offSet          // Set representation:
     //will effect the CIMDateTime value  
  
     if (_rep->minutes.find('*') == PEG_NOT_FOUND) {          setTimeStamp(
         if ( sign == '-' ) {              year,
             if (_TEN_THOUSAND_YEARS < (un_normNum + (offSet_hor + offSet_min))){              month,
                // cout << " this is value " << this->toString() << endl;              day,
                 throw DateTimeOutOfRangeException(parmsOv);              hours,
             }              minutes,
             normNum = un_normNum + (offSet_hor + offSet_min);              seconds,
         }              microseconds,
         else{              numSignificantMicrosecondDigits,
             if (un_normNum < (offSet_hor + offSet_min)) {              sign == '+' ? utcOffset : -Sint16(utcOffset));
                 throw DateTimeOutOfRangeException(parmsUn);  
             }             }
              normNum = un_normNum - (offSet_hor + offSet_min);      else
       {
           throw InvalidDateTimeFormatException();
         }         }
     }     }
  
     //if the hours section has no wild cards but the minutes section does then only on hour  void CIMDateTime::setTimeStamp(
     //position will be effected by the uct off Set      Uint32 year,
     else if (_rep->hours.find('*') == PEG_NOT_FOUND) {      Uint32 month,
         if ( sign == '-' ) {      Uint32 day,
             if (_TEN_THOUSAND_YEARS < (un_normNum + (offSet_hor))){      Uint32 hours,
                 throw DateTimeOutOfRangeException(parmsOv);      Uint32 minutes,
             }      Uint32 seconds,
              normNum = un_normNum + (offSet_hor);      Uint32 microseconds,
         }      Uint32 numSignificantMicrosecondDigits,
         else{      Sint32 utcOffset)
             if (un_normNum < (offSet_hor)) {  {
                 throw DateTimeOutOfRangeException(parmsUn);      clear();
             }  
              normNum = un_normNum - (offSet_hor);  
         }  
     }  
     else{ //if this block is executed then the utc offSet has no effect on CIMDateTime value  
         normNum = un_normNum;  
     }  
  
       Uint32 numWildcards = 0;
  
     CIMDateTime norm_CDT = CIMDateTime(normNum,false);      // Check Year:
  
     this->_rep->copy(norm_CDT._rep);  
  
     return;      if (year == WILDCARD)
       {
           year = 0;
           numWildcards = 20;
 } }
       else if (year > 9999)
   
 /*returns true if object is an interval.  Note: This method exists only for  
   compatibility reasons.  It is superceded by the "const" form of the method.  
 */  
 Boolean CIMDateTime::isInterval()  
 { {
     return ((const CIMDateTime*)this)->isInterval();          MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "year is greater than 9999");
           throw DateTimeOutOfRangeException(parms);
 } }
  
 /*returns true if object is an interval      // Check Month:
 */  
 Boolean CIMDateTime::isInterval() const      if (month == WILDCARD)
 { {
     const Uint32 SIGN_OFFSET = 21;          month = 1;
  
     Boolean isInterval = strcmp(&_rep->data[SIGN_OFFSET], ":000") == 0 ;          if (!numWildcards)
     return isInterval;              numWildcards = 16;
 } }
       else if (month < 1 || month > 12)
   
 /*compares caller to passed in paramiter for eqaulity  
 */  
 Boolean CIMDateTime::equal (const CIMDateTime & x) const  
 { {
     if ((x.isInterval() && !this->isInterval()) || (!x.isInterval() && this->isInterval())) {          MessageLoaderParms parms(
         throw TypeMismatchException();              "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal month number");
           throw DateTimeOutOfRangeException(parms);
     }     }
  
     CIMDateTime current = CIMDateTime((String)_rep->data);      // Check day:
     CIMDateTime compare = CIMDateTime((String)x._rep->data);  // not sure why all this is needed but const has somthing to do with it  
   
     Uint32 spl_pos = current.getHighestWildCardPosition(compare);  
  
     current.insert_WildCard(spl_pos);      if (day == WILDCARD)
     compare.insert_WildCard(spl_pos);      {
           day = 1;
  
     if (current.toMicroSeconds() == compare.toMicroSeconds()) {          if (!numWildcards)
         return true;              numWildcards = 14;
     }     }
     else      else if (day < 1 || day > _getDaysPerMonth(year, month))
         return false;      {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal day number");
           throw DateTimeOutOfRangeException(parms);
 } }
  
       // Check hours:
  
       if (hours == WILDCARD)
 /*subtacts two CIMDateTime objects of like types  
 */  
 Sint64 CIMDateTime::getDifference(CIMDateTime startTime, CIMDateTime finishTime)  
 { {
           hours = 0;
  
     CIMDateTime sta = startTime;          if (!numWildcards)
     CIMDateTime fin = finishTime;              numWildcards = 12;
     CIMDateTime sta_norm;      }
     CIMDateTime fin_norm;      else if (hours > 23)
     Uint64 startT_num;      {
     Uint64 finishT_num;          MessageLoaderParms parms(
     Sint64 diff_num;              "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal hours number ");
     /* the throwing of this expceptoin is only needed becasue of back wards compatability issues          throw DateTimeOutOfRangeException(parms);
     (i.e. this is the way getDifferance worked before). The operator- does not behave this way.  
     */  
     if ((sta.isInterval() && (!( fin.isInterval()))) || ((!( sta.isInterval())) &&  fin.isInterval())) {  
         throw InvalidDateTimeFormatException();  
     }     }
  
     Uint32 splat_pos;      // Check minutes:
     splat_pos = sta.getHighestWildCardPosition(fin);  
   
     sta.insert_WildCard(splat_pos);  
     fin.insert_WildCard(splat_pos);  
   
     startT_num = sta.toMicroSeconds();  
     finishT_num = fin.toMicroSeconds();  
  
     diff_num = finishT_num - startT_num;      if (minutes == WILDCARD)
       {
           minutes = 0;
  
     return diff_num;          if (!numWildcards)
               numWildcards = 10;
       }
       else if (minutes > 59)
       {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal minutes number ");
           throw DateTimeOutOfRangeException(parms);
  }  }
  
       // Check seconds:
  
       if (seconds == WILDCARD)
   
 /*  checks to make sure the format of a particular field in the DateTime string is correct.  
     Returns  
         ONLY_WILD_CARDS - field contains all wild cards  
         SOME_WILD_CARDS - field contains some wild cards (error)  
         ONLY_DIGITS - field contains only digits  
 */  
 CIMDateTime::Field CIMDateTime::fieldcheck(const String & in_p, String & rep_field)  
 { {
     Uint32 post;          seconds = 0;
     rep_field = in_p;  
   
     post = in_p.find("*");  
     if (post == PEG_NOT_FOUND) {  
         return ONLY_DIGITS;  
     }  
  
     const String ast = "**********";          if (!numWildcards)
     String comp = String(ast, in_p.size());   //creates a string of asteriks with the same length as in_p              numWildcards = 8;
     if (!String::compare(in_p, comp)) {  
         return ONLY_WILD_CARDS;                            //fields is all astriks  
     }     }
     else{      else if (seconds > 59)
         return SOME_WILD_CARDS;                //error - mix of asterisk and numbers  in field      {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal seconds number ");
           throw DateTimeOutOfRangeException(parms);
     }     }
  
       // Check microseconds:
   
       if (numSignificantMicrosecondDigits > 6)
       {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "bad numSignificantMicrosecondDigits (must fall between 0 and 6)");
           throw DateTimeOutOfRangeException(parms);
 } }
  
       if (microseconds > 999999)
       {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "microseconds number must be less than 999999");
           throw DateTimeOutOfRangeException(parms);
       }
  
       if (!numWildcards)
           numWildcards = 6 - numSignificantMicrosecondDigits;
  
       // Check UTC offset:
  
 /* This method does not change the value of object, it only converts the      if (utcOffset < -999 || utcOffset > 999)
     representation to a specified time zone.  
     @param utc utc-offset in minutes that represents the time zone to be  
     converted to.  
 */  
 void CIMDateTime::setUtcOffSet(Sint32 utc)  
 { {
     PEGASUS_ASSERT(!isInterval());          MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal utcOffset");
           throw DateTimeOutOfRangeException(parms);
       }
  
     MessageLoaderParms parmsOv("Common.CIMDateTime.UTC_OVERFLOW",      // Set the representation.
         "overflow has occurred during conversion to UTC");  
     MessageLoaderParms parmsUn("Common.CIMDateTime.UTC_UNDERFLOW",  
         "underflow has occurred during conversion to UTC");  
  
     // convert CIMDateTime to microseconds.      Uint32 days = _toJulianDay(year, month, day) - JULIAN_ONE_BCE;
     Uint64 origMicroseconds = toMicroSeconds();  
     Sint64 newUtcMicroseconds = utc * _ONE_MINUTE;  
     Uint64 newMicroseconds = origMicroseconds - newUtcMicroseconds;  
  
     // Check for underflow or overflow      // Multiply in 64-bit to prevent overflow.
     if (utc >= 0)      _rep->usec =
     {          Uint64(microseconds) +
         if (origMicroseconds < (Uint64)newUtcMicroseconds)          Uint64((seconds * SECOND)) +
           Uint64((minutes * MINUTE)) +
           Uint64((hours * HOUR)) +
           Uint64((days * DAY));
       _rep->sign = utcOffset < 0 ? '-' : '+';
       _rep->utcOffset = utcOffset < 0 ? -utcOffset : utcOffset;
       _rep->numWildcards = numWildcards;
   }
   
   void CIMDateTime::setInterval(
       Uint32 days,
       Uint32 hours,
       Uint32 minutes,
       Uint32 seconds,
       Uint32 microseconds,
       Uint32 numSignificantMicrosecondDigits)
         {         {
             throw DateTimeOutOfRangeException(parmsUn);      clear();
         }  
     }  
     else  
     {  
         if (_TEN_THOUSAND_YEARS < (origMicroseconds - newUtcMicroseconds))  
         {  
             throw DateTimeOutOfRangeException(parmsOv);  
         }  
     }  
  
     // Create a new CIMDateTime with the recalculated microseconds value      Uint32 numWildcards = 0;
     // and use the specified UTC value.  
     CIMDateTime newDateTime = CIMDateTime(newMicroseconds, false);  
  
     char newUtcBuffer[5];      // Check days:
     sprintf(newUtcBuffer, "%+04d", utc);  
     Boolean res = newDateTime._rep->set_utcOffSet(newUtcBuffer);  
  
     if (!res)      if (days == WILDCARD)
     {     {
         Tracer::trace(__FILE__,__LINE__,TRC_CIM_DATA,Tracer::LEVEL2,          days = 1;
                       "CIMDateTime::setUTCOffSet() failed");  
         throw InvalidDateTimeFormatException();  
     }  
  
     this->_rep->copy(newDateTime._rep);          if (!numWildcards)
               numWildcards = 20;
       }
       else if (days > 99999999)
       {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal days number (must be less than 100000000");
           throw DateTimeOutOfRangeException(parms);
 } }
  
       // Check hours:
  
       if (hours == WILDCARD)
       {
           hours = 0;
  
 /* finds the Wild Card in the most significant position and returns          if (!numWildcards)
     that position              numWildcards = 12;
     @param cDT_s gets searched along with calling object to find the      }
     wild card in the most significant      else if (hours > 23)
     position  
 */  
 Uint32 CIMDateTime::getHighestWildCardPosition(const CIMDateTime & cDT_s)  
 { {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal hours number ");
           throw DateTimeOutOfRangeException(parms);
       }
  
     Uint32 spot_s = cDT_s.toString().find('*'); //since this return a Uint32 and PEG_NOT_FOUND=-1 can't do a      // Check minutes:
     Uint32 spot_f = this->toString().find('*');  // straight compare  
  
       if (minutes == WILDCARD)
       {
           minutes = 0;
  
     if (spot_s == PEG_NOT_FOUND && spot_f == PEG_NOT_FOUND) {   //start time have more wild cards then finish time          if (!numWildcards)
        return PEG_NOT_FOUND;              numWildcards = 10;
     }  
     else if (spot_f == PEG_NOT_FOUND) {  
          return spot_s;  
     }  
     else if (spot_s == PEG_NOT_FOUND) {  
          return spot_f;  
     }  
     else{  
         if (spot_f < spot_s) {  
             return spot_f;  
         }  
         else{  
             return spot_s;  
         }  
     }     }
       else if (minutes > 59)
       {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "illegal minutes number ");
           throw DateTimeOutOfRangeException(parms);
  }  }
  
       // Check seconds:
  
       if (seconds == WILDCARD)
   
 /*inserts wild cards into CIMDateTime object.  
     @param index - position to start placing wild card characters  
     @param cdt - object to be modified  
     Returns a copy of calling object with wild cards starting at  
     position index  
     @exception InvalidDateTimeFormatException because of invalid index  
     (see rules for wild cards)  
 */  
 void CIMDateTime::insert_WildCard(Uint32 ind)  
 { {
           seconds = 0;
  
     Uint32 index = ind;          if (!numWildcards)
     if (ind > 20) {              numWildcards = 8;
        index = 21;  
     }     }
       else if (seconds > 59)
     Uint32 spot = this->toString().find('*');      {
     if (spot == index) {          MessageLoaderParms parms(
         CIMDateTime cur = CIMDateTime(this->toString());              "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
         return;              "illegal seconds number ");
           throw DateTimeOutOfRangeException(parms);
     }     }
  
     String splat = String("**************.******");      // Check microseconds:
     String cdtStr = this->toString();  
     String final;  
     if (index != PEG_NOT_FOUND) {  
         String str_cdtStr = cdtStr.subString(0, index);  
         String sub_splat = splat.subString(index, (21-index));  
  
         //build result      if (numSignificantMicrosecondDigits > 6)
         String cdt_Splat = str_cdtStr.append(sub_splat);      {
         final = cdt_Splat.append(this->_rep->utcOffSet);          MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "bad numSignificantMicrosecondDigits (must fall between 0 and 6)");
           throw DateTimeOutOfRangeException(parms);
    }    }
  
    else{      if (microseconds > 999999)
         final = splat.append(this->_rep->utcOffSet);      {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "microseconds number must be less than 999999");
           throw DateTimeOutOfRangeException(parms);
    }    }
  
    CIMDateTime ans = CIMDateTime(final);      if (!numWildcards)
    this->_rep->copy(ans._rep);          numWildcards = 6 - numSignificantMicrosecondDigits;
    return;  
   
 }  
  
       // Set the representation.
  
       _rep->usec =
           microseconds +
           (seconds * SECOND) +
           (minutes * MINUTE) +
           (hours * HOUR) +
           (days * DAY);
       _rep->sign = ':';
       _rep->utcOffset = 0;
       _rep->numWildcards = numWildcards;
   }
  
 CIMDateTime CIMDateTime::operator+(const CIMDateTime & cDT) const  String CIMDateTime::toString() const
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      Char16 str[26];
     CIMDateTime opt_cDT = cDT;      _toChar16Str(_rep, str);
     Sint32 utc;      return String(str, 25);
     Boolean isInt = this->isInterval();  
   
     // only interval+interval and timeStamp+interval are allowed. Therefor second operand must be interval  
     if (!opt_cDT.isInterval()) {  
         throw TypeMismatchException();  
     }     }
  
     Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(opt_cDT);  Sint64 CIMDateTime::getDifference(CIMDateTime x, CIMDateTime y)
   {
     Uint64 opt_num = opt_cDT.toMicroSeconds();      if (x.isInterval() != y.isInterval())
     Uint64 cur_num = cur_cDT.toMicroSeconds();          throw InvalidDateTimeFormatException();
  
     Uint64 ans = opt_num + cur_num;      return y.toMicroSeconds() - x.toMicroSeconds();
     CIMDateTime ans_cdt = CIMDateTime(ans, isInt);  }
  
     if (!isInt) {  Boolean CIMDateTime::isInterval() const
         utc = atol((_rep->utcOffSet).getCString());  {
         ans_cdt.setUtcOffSet(utc);      return _rep->sign == ':';
     }     }
  
     ans_cdt.insert_WildCard(splat_pos);  Boolean CIMDateTime::isInterval()
   {
       return _rep->sign == ':';
   }
  
     return ans_cdt;  Boolean CIMDateTime::isTimeStamp() const
   {
       return _rep->sign != ':';
 } }
  
   Uint64 CIMDateTime::toMicroSeconds() const
   {
       return _toMicroSeconds(_rep);
   }
  
   Boolean CIMDateTime::equal(const CIMDateTime& x) const
   {
       return _compare(_rep, x._rep) == 0;
   }
  
   CIMDateTime CIMDateTime::operator+(const CIMDateTime& x) const
   {
       CIMDateTime result(*this);
       return result+=(x);
   }
  
 CIMDateTime & CIMDateTime::operator+=(const CIMDateTime & cDT)  CIMDateTime& CIMDateTime::operator+=(const CIMDateTime& x)
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      // ATTN: check for overflow?
     CIMDateTime opt_cDT = cDT;  
  
     CIMDateTime sum_cdt = cur_cDT + opt_cDT;      if (!x.isInterval())
           throw TypeMismatchException();
  
     _rep->copy(sum_cdt._rep);      if (isInterval())
           _rep->usec += x._rep->usec;
       else
           _rep->usec += x.toMicroSeconds();
  
      return *this;      return *this;
 } }
  
   CIMDateTime CIMDateTime::operator-(const CIMDateTime& dt) const
 CIMDateTime CIMDateTime::operator-(const CIMDateTime & cDT) const  
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      // ATTN: check for overflow?
     CIMDateTime opt_cDT = cDT;      // ATTN: use operator-=()?
   
     CIMDateTime ans_cdt;  
     Sint32 utc;  
  
     Boolean cur_isIn = this->isInterval();      if (isInterval() && !dt.isInterval())
     Boolean opt_isIn = opt_cDT.isInterval();  
   
     // only I-I, T-I and T-T are allowed  
     if (cur_isIn && !opt_isIn) {  
         throw TypeMismatchException();         throw TypeMismatchException();
     }  
  
     Uint64 opt_num = opt_cDT.toMicroSeconds();      Uint64 x = toMicroSeconds();
     Uint64 cur_num = cur_cDT.toMicroSeconds();      Uint64 y = dt.toMicroSeconds();
  
     if (cur_num < opt_num) {      if (x < y)
         MessageLoaderParms parmsSub("Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",      {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
                "Result of subtracting two CIMDateTimes would be negative.");                "Result of subtracting two CIMDateTimes would be negative.");
         throw DateTimeOutOfRangeException(parmsSub);          throw DateTimeOutOfRangeException(parms);
     }     }
  
     Uint64 diff = cur_num - opt_num;      if (isInterval() == dt.isInterval())
       {
     if ((cur_isIn && opt_isIn) || (!cur_isIn && !opt_isIn)) { //don't konw how to do logical xor          // TIMESTAMP - TIMESTAMP
         ans_cdt = CIMDateTime(diff, true);          // OR
           // INTERVAL - INTERVAL
           return CIMDateTime(x - y, true);
     }     }
     else{      else
         ans_cdt = CIMDateTime(diff, false);      {
         utc = atol((_rep->utcOffSet).getCString());          // TIMESTAMP - INTERVAL (INTERVAL - TIMESTAMP eliminated above).
         ans_cdt.setUtcOffSet(utc);          CIMDateTime tmp(x - y, false);
           tmp._rep->sign = _rep->sign;
           tmp._rep->utcOffset = _rep->utcOffset;
           tmp._rep->numWildcards = _rep->numWildcards;
           return tmp;
     }     }
   
     Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(opt_cDT);  
     ans_cdt.insert_WildCard(splat_pos);  
   
      return ans_cdt;  
 } }
  
   CIMDateTime& CIMDateTime::operator-=(const CIMDateTime& x)
   {
       // ATTN: check for overflow?
  
       if (!x.isInterval())
           throw TypeMismatchException();
  
       if (_rep->usec < x._rep->usec)
 CIMDateTime & CIMDateTime::operator-=(const CIMDateTime & cDT)  
 { {
           MessageLoaderParms parms(
               "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
               "Result of subtracting two CIMDateTimes would be negative.");
           throw DateTimeOutOfRangeException(parms);
       }
  
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      if (isInterval())
     CIMDateTime opt_cDT = cDT;          _rep->usec -= x._rep->usec;
       else
     CIMDateTime dif_cdt = cur_cDT - opt_cDT;          _rep->usec -= x.toMicroSeconds();
       _rep->copy(dif_cdt._rep);  
  
      return *this;      return *this;
 } }
  
   CIMDateTime CIMDateTime::operator*(Uint64 x) const
   
   
 CIMDateTime CIMDateTime::operator*(Uint64 num) const  
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      CIMDateTime result(*this);
       return result*=(x);
     if (!this->isInterval()){  
         throw TypeMismatchException();  
     }     }
  
     Uint64 cur_num = cur_cDT.toMicroSeconds();  CIMDateTime& CIMDateTime::operator*=(const Uint64 x)
     Uint64 prod = cur_num * num;  {
       if (!isInterval())
     CIMDateTime prod_cdt = CIMDateTime(prod, true);          throw TypeMismatchException();
   
     CIMDateTime dummy;  
     Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(dummy);  
   
     prod_cdt.insert_WildCard(splat_pos);  
  
     return prod_cdt;      _rep->usec *= x;
       return *this;
 } }
  
   CIMDateTime CIMDateTime::operator/(Uint64 x) const
   
   
 CIMDateTime & CIMDateTime::operator*=(Uint64 num)  
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      CIMDateTime result(*this);
       return result/=(x);
   }
  
     CIMDateTime prod_cdt = cur_cDT * num;  CIMDateTime& CIMDateTime::operator/=(const Uint64 x)
   {
       if (!isInterval())
       {
           MessageLoaderParms parms(
               "Common.CIMDateTime.INVALID_OPERATION_DIV_INT",
               "Can not divide a TimeStamp by an integer");
           throw TypeMismatchException(parms);
       }
  
     _rep->copy(prod_cdt._rep);      if (x == 0)
       {
           MessageLoaderParms parms(
               "Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO",
               "Can not divide CIMDateTime by zero");
           throw Exception(parms);
       }
  
       _rep->usec /= x;
      return *this;      return *this;
 } }
  
   Uint64 CIMDateTime::operator/(const CIMDateTime& x) const
   
   
 CIMDateTime CIMDateTime::operator/(Uint64 num) const  
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      if (!isInterval() || !x.isInterval())
       {
     if (!(this->isInterval())){          MessageLoaderParms parms(
         MessageLoaderParms parmsD("Common.CIMDateTime.INVALID_OPERATION_DIV_INT",              "Common.CIMDateTime.INVALID_OPERATION_DIV_TS",
                                  "Can not divide a TimeStamp by an integer");              "Can not divide two CIMDateTime objects if one of them is "
         throw TypeMismatchException(parmsD);              "a TimeStamp");
           throw TypeMismatchException(parms);
     }     }
  
     if (num == 0) {      if (x._rep->usec == 0)
         MessageLoaderParms parmsZ("Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO",      {
           MessageLoaderParms parms(
               "Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO",
                                  "Can not divide CIMDateTime by zero");                                  "Can not divide CIMDateTime by zero");
         throw Exception(parmsZ);          throw Exception(parms);
     }     }
  
     Uint64 cur_num = cur_cDT.toMicroSeconds();      return _rep->usec / x._rep->usec;
     Uint64 prod = cur_num/num;  }
   
     CIMDateTime prod_cdt = CIMDateTime(prod, true);  
     CIMDateTime dummy;  
   
     Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(CIMDateTime(dummy));  
     prod_cdt.insert_WildCard(splat_pos);  
  
     return prod_cdt;  Boolean CIMDateTime::operator<(const CIMDateTime& x) const
   {
       return _compare(_rep, x._rep) < 0;
 } }
  
   Boolean CIMDateTime::operator<=(const CIMDateTime& x) const
   {
       return _compare(_rep, x._rep) <= 0;
   }
  
   Boolean CIMDateTime::operator>(const CIMDateTime& x) const
   {
       return _compare(_rep, x._rep) > 0;
   }
  
 CIMDateTime & CIMDateTime::operator/=(Uint64 num)  Boolean CIMDateTime::operator>=(const CIMDateTime& x) const
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      return _compare(_rep, x._rep) >= 0;
   }
  
     CIMDateTime ans = cur_cDT/num;  Boolean CIMDateTime::operator!=(const CIMDateTime& x) const
     _rep->copy(ans._rep);  {
       return _compare(_rep, x._rep) != 0;
   }
  
      return *this;  Boolean operator==(const CIMDateTime& x, const CIMDateTime& y)
   {
       return x.equal(y);
 } }
  
   //==============================================================================
   //
   // PEGASUS_OS_TYPE_UNIX
   //
   //==============================================================================
  
   #if defined(PEGASUS_OS_TYPE_UNIX)
  
   CIMDateTime CIMDateTime::getCurrentDateTime()
   {
       // Get sec and usec:
  
 Uint64 CIMDateTime::operator/(const CIMDateTime & cDT) const      time_t sec;
       Uint64 usec;
 { {
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));          // ATTN: if this fails on your platform, use time() to obtain the
     CIMDateTime opt_cDT = cDT;          // sec element and set usec to zero.
           struct timeval tv;
           gettimeofday(&tv, NULL);
           sec = tv.tv_sec;
           usec = Uint64(tv.tv_usec);
       }
  
       // Get the localtime
  
     if (!cur_cDT.isInterval() || !opt_cDT.isInterval()) {      struct tm* tmval;
         MessageLoaderParms parmsMM("Common.CIMDateTime.INVALID_OPERATION_DIV_TS",      struct tm tmvalBuffer;
                              "Can not divide two CIMDateTime objects if one of them is a TimeStamp");      tmval = localtime_r(&sec, &tmvalBuffer);
         throw TypeMismatchException(parmsMM);      PEGASUS_ASSERT(tmval != 0);
     }  
  
     Uint64 opt_num = opt_cDT.toMicroSeconds();      // Calculate minutes East of GMT.
     Uint64 cur_num = cur_cDT.toMicroSeconds();  
  
     if (opt_num == 0) {      int tzMinutesEast;
         MessageLoaderParms parmsDZ("Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO_CDT",      {
                              "Trying to divide a CIMDateTime object by a zero value CIMDateTime object");  # if defined(PEGASUS_OS_SOLARIS)
         throw Exception(parmsDZ);          tzMinutesEast =
               -(int)((tmval->tm_isdst > 0 && daylight) ? altzone : timezone) / 60;
   # elif defined(PEGASUS_OS_HPUX)
           tzMinutesEast = - (int) timezone / 60;
           if ((tmval->tm_isdst > 0) && daylight)
           {
               // ATTN: It is unclear how to determine the DST offset.
               // Assume 1 hour.
               tzMinutesEast += 60;
           }
   # elif defined(PEGASUS_OS_LINUX)
           tzMinutesEast = (int) tmval->tm_gmtoff/60;
   # else
           struct timeval tv;
           struct timezone tz;
           gettimeofday(&tv, &tz);
           tzMinutesEast = -tz.tz_minuteswest;
   # endif
     }     }
  
     Uint64 ans = cur_num/opt_num;      // Create the representation object.
   
       CIMDateTimeRep* rep = new CIMDateTimeRep;
       rep->usec =
           POSIX_1970_EPOCH_OFFSET + Uint64(sec) * Uint64(1000000) + Uint64(usec);
       rep->sign = tzMinutesEast < 0 ? '-' : '+';
       rep->utcOffset = tzMinutesEast < 0 ? -tzMinutesEast : tzMinutesEast;
       rep->numWildcards = 0;
  
     return ans;      return CIMDateTime(rep);
 } }
  
   #endif /* PEGASUS_OS_TYPE_UNIX */
  
   //==============================================================================
   //
   // PEGASUS_OS_VMS
   //
   //==============================================================================
  
   #if defined(PEGASUS_OS_VMS)
  
 Boolean CIMDateTime::operator<(const CIMDateTime & cDT) const  CIMDateTime CIMDateTime::getCurrentDateTime()
 { {
       time_t mSysTime;
       struct tm* tmval;
  
     CIMDateTime cur_cDT = CIMDateTime((String)(this->_rep->data));      // Get time.
     CIMDateTime opt_cDT = cDT;  
  
     if ((!cur_cDT.isInterval() && opt_cDT.isInterval()) || (cur_cDT.isInterval() && !opt_cDT.isInterval())) {      mSysTime = time(NULL);
         MessageLoaderParms parms("Common.CIMDateTime.INVALID_OPERATION_COMP_DIF",  
                              "Trying to compare CIMDateTime objects of differing types");  
         throw TypeMismatchException(parms);  
     }  
  
     Uint32 splat_pos = cur_cDT.getHighestWildCardPosition(opt_cDT);      // Get the localtime
     opt_cDT.insert_WildCard(splat_pos);  
     cur_cDT.insert_WildCard(splat_pos);  
  
     Uint64 opt_num = opt_cDT.toMicroSeconds();      tmval = localtime(&mSysTime);
     Uint64 cur_num = cur_cDT.toMicroSeconds();  
  
     if (cur_num < opt_num) {      // Initialize components.
         return true;  
     }      Uint32 year = 1900 + tmval->tm_year;
     else{      Uint32 month = tmval->tm_mon + 1;
         return false;      Uint32 day = tmval->tm_mday;
     }      Uint32 hours = tmval->tm_hour;
       Uint32 minutes = tmval->tm_min;
       Uint32 seconds = tmval->tm_sec;
   
       // ATTN: missing UTC offset here.
   
       return CIMDateTime(year, month, day, hours, minutes, seconds, 0, 6, 0);
 } }
  
   #endif /* PEGASUS_OS_VMS */
  
   //==============================================================================
   //
   // PEGASUS_OS_TYPE_WINDOWS
   //
   //==============================================================================
  
   #if defined(PEGASUS_OS_TYPE_WINDOWS)
  
 Boolean CIMDateTime::operator<=(const CIMDateTime & cDT) const  Boolean getCurrentTimeZone(Sint16& currentTimeZone)
 { {
     CIMDateTime cur = CIMDateTime((String)(this->_rep->data));      currentTimeZone = 0;
       TIME_ZONE_INFORMATION timezone;
       ::memset(&timezone, 0, sizeof(timezone));
  
    if ((cur < cDT) || (cur == cDT)) {      switch(::GetTimeZoneInformation(&timezone))
       return true;      {
    }          case TIME_ZONE_ID_UNKNOWN:
    else{          {
        return false;              currentTimeZone = static_cast<Sint16>(timezone.Bias);
               break;
    }    }
   
           case TIME_ZONE_ID_STANDARD:
           {
               currentTimeZone =
                   static_cast<Sint16>(timezone.Bias + timezone.StandardBias);
               break;
 } }
  
           case TIME_ZONE_ID_DAYLIGHT:
           {
               currentTimeZone =
                   static_cast<Sint16>(timezone.Bias + timezone.DaylightBias);
               break;
           }
  
           default:
               break;
       }
  
       // the bias used to calculate the time zone is a factor that is used to
       // determine the UTC time from the local time. to get the UTC offset from
       // the local time, use the inverse.
  
 Boolean CIMDateTime::operator>(const CIMDateTime & cDT) const      if(currentTimeZone != 0)
 { {
     CIMDateTime cur = CIMDateTime((String)(this->_rep->data));          currentTimeZone *= -1;
       }
  
     if ((!(cur < cDT)) && (!(cur == cDT))) {  
        return true;        return true;
     }     }
     else{  
        return false;  
     }  
 }  
  
   CIMDateTime CIMDateTime::getCurrentDateTime()
   {
       // Get system time.
  
       SYSTEMTIME time;
       memset(&time, 0, sizeof(time));
       GetLocalTime(&time);
  
       // Get UTC offset.
  
 Boolean CIMDateTime::operator>=(const CIMDateTime & cDT) const      Sint32 utcOffset = 0;
 {      Sint16 currentTimeZone;
     CIMDateTime cur = CIMDateTime((String)(this->_rep->data));  
  
    if (!(cur < cDT)) {      if (getCurrentTimeZone(currentTimeZone))
       return true;          utcOffset = currentTimeZone;
    }  
    else{      // Create the CIMDateTime object.
       return false;  
    }      return CIMDateTime(
           time.wYear,
           time.wMonth,
           time.wDay,
           time.wHour,
           time.wMinute,
           time.wSecond,
           time.wMilliseconds * 1000,
           6,
           utcOffset);
 } }
  
   #endif /* PEGASUS_OS_TYPE_WINDOWS */
  
   /*
   ================================================================================
  
 Boolean CIMDateTime::operator!=(const CIMDateTime & cDT) const  Notes:
 {  
     CIMDateTime cur = CIMDateTime((String)(this->_rep->data));  
  
     if (!(cur  == cDT)) {      (1) The legacy implementation added the UTC offset when it was negative and
         return true;          substracted it when it was positive. I preserved this behavior but
     }          suspect it may be wrong.
     else{  
         return false;      (2) Evenetually change getCurrentDateTime() to use constructor that takes
     }          a single microseconds component.
 }  
  
       (4) Add overflow checking for adds and multiplies.
  
   ================================================================================
   */
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.70  
changed lines
  Added in v.1.71

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2