📄 cimdatetime.cpp
字号:
"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: if (utcOffset < -999 || utcOffset > 999) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "illegal utcOffset"); throw DateTimeOutOfRangeException(parms); } // Set the representation. Uint32 days = _toJulianDay(year, month, day) - JULIAN_ONE_BCE; // Multiply in 64-bit to prevent overflow. _rep->usec = Uint64(microseconds) + 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){ clear(); Uint32 numWildcards = 0; // Check days: if (days == WILDCARD) { days = 1; 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; if (!numWildcards) numWildcards = 12; } else if (hours > 23) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "illegal hours number "); throw DateTimeOutOfRangeException(parms); } // Check minutes: if (minutes == WILDCARD) { minutes = 0; 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) { seconds = 0; if (!numWildcards) numWildcards = 8; } else if (seconds > 59) { 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; // Set the representation. _rep->usec = microseconds + (seconds * SECOND) + (minutes * MINUTE) + (hours * HOUR) + (days * DAY); _rep->sign = ':'; _rep->utcOffset = 0; _rep->numWildcards = numWildcards;}String CIMDateTime::toString() const{ Char16 str[26]; _toChar16Str(_rep, str); return String(str, 25);}Sint64 CIMDateTime::getDifference(CIMDateTime x, CIMDateTime y){ if (x.isInterval() != y.isInterval()) throw InvalidDateTimeFormatException(); return y.toMicroSeconds() - x.toMicroSeconds();}Boolean CIMDateTime::isInterval() const{ return _rep->sign == ':';}Boolean CIMDateTime::isInterval(){ return _rep->sign == ':';}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& x){ // ATTN: check for overflow? if (!x.isInterval()) throw TypeMismatchException(); if (isInterval()) _rep->usec += x._rep->usec; else _rep->usec += x.toMicroSeconds(); return *this;}CIMDateTime CIMDateTime::operator-(const CIMDateTime& dt) const{ // ATTN: check for overflow? // ATTN: use operator-=()? if (isInterval() && !dt.isInterval()) throw TypeMismatchException(); Uint64 x = toMicroSeconds(); Uint64 y = dt.toMicroSeconds(); if (x < y) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Result of subtracting two CIMDateTimes would be negative."); throw DateTimeOutOfRangeException(parms); } if (isInterval() == dt.isInterval()) { // TIMESTAMP - TIMESTAMP // OR // INTERVAL - INTERVAL return CIMDateTime(x - y, true); } else { // TIMESTAMP - INTERVAL (INTERVAL - TIMESTAMP eliminated above). CIMDateTime tmp(x - y, false); tmp._rep->sign = _rep->sign; tmp._rep->utcOffset = _rep->utcOffset; tmp._rep->numWildcards = _rep->numWildcards; return tmp; }}CIMDateTime& CIMDateTime::operator-=(const CIMDateTime& x){ // ATTN: check for overflow? if (!x.isInterval()) throw TypeMismatchException(); if (_rep->usec < x._rep->usec) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Result of subtracting two CIMDateTimes would be negative."); throw DateTimeOutOfRangeException(parms); } if (isInterval()) _rep->usec -= x._rep->usec; else _rep->usec -= x.toMicroSeconds(); return *this;}CIMDateTime CIMDateTime::operator*(Uint64 x) const{ CIMDateTime result(*this); return result*=(x);}CIMDateTime& CIMDateTime::operator*=(Uint64 x){ if (!isInterval()) throw TypeMismatchException(); _rep->usec *= x; return *this;}CIMDateTime CIMDateTime::operator/(Uint64 x) const{ CIMDateTime result(*this); return result/=(x);}CIMDateTime& CIMDateTime::operator/=(Uint64 x){ if (!isInterval()) { MessageLoaderParms parms( "Common.CIMDateTime.INVALID_OPERATION_DIV_INT", "Can not divide a TimeStamp by an integer"); throw TypeMismatchException(parms); } 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;}Uint64 CIMDateTime::operator/(const CIMDateTime& x) const{ if (!isInterval() || !x.isInterval()) { MessageLoaderParms parms( "Common.CIMDateTime.INVALID_OPERATION_DIV_TS", "Can not divide two CIMDateTime objects if one of them is " "a TimeStamp"); throw TypeMismatchException(parms); } if (x._rep->usec == 0) { MessageLoaderParms parms( "Common.CIMDateTime.INVALID_OPERATION_DIV_ZERO", "Can not divide CIMDateTime by zero"); throw Exception(parms); } return _rep->usec / x._rep->usec;}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;}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 operator==(const CIMDateTime& x, const CIMDateTime& y){ return x.equal(y);}//==============================================================================//// PEGASUS_OS_TYPE_UNIX////==============================================================================#if defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)CIMDateTime CIMDateTime::getCurrentDateTime(){ // Get sec and usec: time_t sec; Uint64 usec; // ATTN: if this fails on your platform, use time() to obtain the // sec element and set usec to zero. struct timeval tv;#if defined(PEGASUS_OS_VMS) void *tz = NULL;#else struct timezone tz;#endif gettimeofday(&tv, &tz); sec = tv.tv_sec; usec = Uint64(tv.tv_usec); // Get the localtime struct tm* tmval; struct tm tmvalBuffer; tmval = localtime_r(&sec, &tmvalBuffer); PEGASUS_ASSERT(tmval != 0); // Calculate minutes East of GMT. int tzMinutesEast; {# if defined(PEGASUS_OS_SOLARIS) 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) || defined(PEGASUS_OS_VMS) tzMinutesEast = (int) tmval->tm_gmtoff/60;# else tzMinutesEast = -tz.tz_minuteswest; if (tz.tz_dsttime > 0) { // ATTN: It is unclear how to determine the DST offset. // Assume 1 hour. tzMinutesEast += 60; }# endif } // Create the representation object. CIMDateTimeRep* rep = new CIMDateTimeRep; rep->usec = POSIX_1970_EPOCH_OFFSET + Uint64(sec + tzMinutesEast * 60) * Uint64(1000000) + Uint64(usec); rep->sign = tzMinutesEast < 0 ? '-' : '+'; rep->utcOffset = tzMinutesEast < 0 ? -tzMinutesEast : tzMinutesEast; rep->numWildcards = 0; return CIMDateTime(rep);}#endif /* PEGASUS_OS_TYPE_UNIX *///==============================================================================//// PEGASUS_OS_TYPE_WINDOWS////==============================================================================#if defined(PEGASUS_OS_TYPE_WINDOWS)Boolean getCurrentTimeZone(Sint16& currentTimeZone){ currentTimeZone = 0; TIME_ZONE_INFORMATION timezone; ::memset(&timezone, 0, sizeof(timezone)); switch(::GetTimeZoneInformation(&timezone)) { case TIME_ZONE_ID_UNKNOWN: { 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. if (currentTimeZone != 0) { currentTimeZone *= -1; } return true;}CIMDateTime CIMDateTime::getCurrentDateTime(){ // Get system time. SYSTEMTIME time; memset(&time, 0, sizeof(time)); GetLocalTime(&time); // Get UTC offset. Sint32 utcOffset = 0; Sint16 currentTimeZone; if (getCurrentTimeZone(currentTimeZone)) utcOffset = currentTimeZone; // Create the CIMDateTime object. return CIMDateTime( time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds * 1000, 6, utcOffset);}#endif /* PEGASUS_OS_TYPE_WINDOWS *//*================================================================================Notes: (1) The legacy implementation added the UTC offset when it was negative and substracted it when it was positive. I preserved this behavior but suspect it may be wrong. (2) Evenetually change getCurrentDateTime() to use constructor that takes a single microseconds component. (4) Add overflow checking for adds and multiplies.================================================================================*/PEGASUS_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -