version 1.70, 2006/08/16 19:31:25
|
version 1.71, 2006/09/14 20:11:13
|
|
|
// 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; |
|
|
# 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 |