//*************************************************************************** // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // // wbemtime.cpp // // Purpose: Defines the WBEMTime and WBEMTimeSpan objects which are // similar to the MFC CTime and CTimeSpan objects. The WBEM versions // are capable of storing down to the nsec and also have functions for // Creating from and getting BSTRs. // // Note; The current implementation of WBEMTime does not support dates // before 1/1/1601; // // WBEMTime::m_uTime is stored in GMT as 100 nsecs since 1/1/1601 // //*************************************************************************** #include "precomp.h" #include #pragma warning( disable : 4290 ) #ifdef UTILLIB #include #else #define ASSERT_BREAK(a) #endif //UTILLIB #include #include // These are here rather than wbemtime.h so we don't have to doc/support #define DECPOS 14 #define SGNPOS 21 #define DMTFLEN 25 #define DEPRECATED 0 #define INVALID_TIME_FORMAT 0 #define INVALID_TIME_ARITHMETIC 0 #define BAD_TIMEZONE 0 // **************************************************************** // Static functions and variables. These can't be called/referenced // outside of wbemtime.cpp static WBEMTime g_Jan1970((time_t)0); //*************************************************************************** // // StructtmToSystemTime // // Description: General utility for converting between the two common // data structures. // // Return values: TRUE if OK; // //*************************************************************************** static BOOL StructtmToSystemTime(const struct tm *ptm, SYSTEMTIME * pst) { if (pst && ptm) { pst->wYear = ptm->tm_year + 1900; pst->wMonth = ptm->tm_mon + 1; pst->wDay = (WORD)ptm->tm_mday; pst->wHour = (WORD)ptm->tm_hour; pst->wMinute = (WORD)ptm->tm_min; pst->wSecond = (WORD)ptm->tm_sec; pst->wDayOfWeek = (WORD)ptm->tm_wday; pst->wMilliseconds = 0; return TRUE; } return FALSE; } static BOOL SystemTimeToStructtm(const SYSTEMTIME *pst, struct tm *ptm) { if (pst && ptm && pst->wYear >= 1900) { ptm->tm_year = pst->wYear - 1900; ptm->tm_mon = pst->wMonth - 1; ptm->tm_mday = pst->wDay; ptm->tm_hour = pst->wHour; ptm->tm_min = pst->wMinute; ptm->tm_sec = pst->wSecond; ptm->tm_wday = pst->wDayOfWeek; ptm->tm_isdst = 0; // Since we are working in gmt... return TRUE; } return FALSE; } //*************************************************************************** // // FileTimeToui64 // ui64ToFileTime // // Description: Conversion routines for going between FILETIME structures // and __int64. // //*************************************************************************** static void FileTimeToui64(const FILETIME *pft, ULONGLONG *p64) { *p64 = pft->dwHighDateTime; *p64 = *p64 << 32; *p64 |= pft->dwLowDateTime; } static void ui64ToFileTime(const ULONGLONG *p64,FILETIME *pft) { unsigned __int64 uTemp = *p64; pft->dwLowDateTime = (DWORD)uTemp; uTemp = uTemp >> 32; pft->dwHighDateTime = (DWORD)uTemp; } static int CompareSYSTEMTIME(const SYSTEMTIME *pst1, const SYSTEMTIME *pst2) { FILETIME ft1, ft2; SystemTimeToFileTime(pst1, &ft1); SystemTimeToFileTime(pst2, &ft2); return CompareFileTime(&ft1, &ft2); } // This function is used to convert the relative values that come // back from GetTimeZoneInformation into an actual date for the year // in question. The system time structure that is passed in is updated // to contain the absolute values. static void DayInMonthToAbsolute(SYSTEMTIME *pst, const WORD wYear) { const static int _lpdays[] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; const static int _days[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; SHORT shYearDay; // If this is not 0, this is not a relative date if (pst->wYear == 0) { // Was that year a leap year? BOOL bLeap = ( (( wYear % 400) == 0) || ((( wYear % 4) == 0) && (( wYear % 100) != 0))); // Figure out the day of the year for the first day of the month in question if (bLeap) shYearDay = 1 + _lpdays[pst->wMonth - 1]; else shYearDay = 1 + _days[pst->wMonth - 1]; // Now, figure out how many leap days there have been since 1/1/1601 WORD yc = wYear - 1601; WORD y4 = (yc) / 4; WORD y100 = (yc) / 100; WORD y400 = (yc) / 400; // This will tell us the day of the week for the first day of the month in question. // The '1 +' reflects the fact that 1/1/1601 was a monday (figures). You might ask, // 'why do we care what day of the week this is?' Well, I'll tell you. The way // daylight savings time is defined is with things like 'the last sunday of the month // of october.' Kinda helps to know what day that is. SHORT monthdow = (1 + (yc * 365 + y4 + y400 - y100) + shYearDay) % 7; if ( monthdow < pst->wDayOfWeek ) shYearDay += (pst->wDayOfWeek - monthdow) + (pst->wDay - 1) * 7; else shYearDay += (pst->wDayOfWeek - monthdow) + pst->wDay * 7; /* * May have to adjust the calculation above if week == 5 (meaning * the last instance of the day in the month). Check if yearday falls * beyond month and adjust accordingly. */ if ( (pst->wDay == 5) && (shYearDay > (bLeap ? _lpdays[pst->wMonth] : _days[pst->wMonth])) ) { shYearDay -= 7; } // Now update the structure. pst->wYear = wYear; pst->wDay = shYearDay - (bLeap ? _lpdays[pst->wMonth - 1] : _days[pst->wMonth - 1]); } } // ************************************************************************** // These are static to WBEMTIME, which means they CAN be called from outside // wbemtime LONG WBEMTime::GetLocalOffsetForDate(const time_t &t) { FILETIME ft; ULONGLONG ull = Int32x32To64(t, 10000000) + 116444736000000000; ui64ToFileTime(&ull, &ft); return GetLocalOffsetForDate(&ft); } LONG WBEMTime::GetLocalOffsetForDate(const struct tm *ptmin) { SYSTEMTIME st; StructtmToSystemTime(ptmin, &st); return GetLocalOffsetForDate(&st); } LONG WBEMTime::GetLocalOffsetForDate(const FILETIME *pft) { SYSTEMTIME st; FileTimeToSystemTime(pft, &st); return GetLocalOffsetForDate(&st); } LONG WBEMTime::GetLocalOffsetForDate(const SYSTEMTIME *pst) { TIME_ZONE_INFORMATION tzTime; DWORD dwRes = GetTimeZoneInformation(&tzTime); LONG lRes = 0xffffffff; switch (dwRes) { case TIME_ZONE_ID_UNKNOWN: { // Read tz, but no dst defined in this zone lRes = tzTime.Bias * -1; break; } case TIME_ZONE_ID_STANDARD: case TIME_ZONE_ID_DAYLIGHT: { // Convert the relative dates to absolute dates DayInMonthToAbsolute(&tzTime.DaylightDate, pst->wYear); DayInMonthToAbsolute(&tzTime.StandardDate, pst->wYear); if ( CompareSYSTEMTIME(&tzTime.DaylightDate, &tzTime.StandardDate) < 0 ) { /* * Northern hemisphere ordering */ if ( CompareSYSTEMTIME(pst, &tzTime.DaylightDate) < 0 || CompareSYSTEMTIME(pst, &tzTime.StandardDate) > 0) { lRes = tzTime.Bias * -1; } else { lRes = (tzTime.Bias + tzTime.DaylightBias) * -1; } } else { /* * Southern hemisphere ordering */ if ( CompareSYSTEMTIME(pst, &tzTime.StandardDate) < 0 || CompareSYSTEMTIME(pst, &tzTime.DaylightDate) > 0) { lRes = (tzTime.Bias + tzTime.DaylightBias) * -1; } else { lRes = tzTime.Bias * -1; } } break; } case TIME_ZONE_ID_INVALID: default: { // Can't read the timezone info ASSERT_BREAK(BAD_TIMEZONE); break; } } return lRes; } /////////////////////////////////////////////////////////////////////////// // WBEMTime - This class holds time values. //*************************************************************************** // // WBEMTime::operator=(BSTR bstrWbemFormat) // // Description: Assignment operator which is also used by the constructor. // The string must have the format: // YYYYMMDDHHSS.123456789 So 3:04 am, 1/1/96 would be 199601010304.0 // // or the format yyyymmddhhmmss.mmmmmmsuuu. // // Note that the fractional part can be between 1 and nine digits. // // Return: WBEMTime object. // //*************************************************************************** const WBEMTime & WBEMTime::operator=(const BSTR bstrWbemFormat) { Clear(); // set when properly assigned if((NULL == bstrWbemFormat) || bstrWbemFormat[DECPOS] != L'.' ) { ASSERT_BREAK(INVALID_TIME_FORMAT); return *this; } if ( (wcslen(bstrWbemFormat) == DMTFLEN) && (bstrWbemFormat[SGNPOS] == L'+' || bstrWbemFormat[SGNPOS] == L'-') ) { SetDMTF(bstrWbemFormat); } else { ASSERT_BREAK(INVALID_TIME_FORMAT); } return *this; } //*************************************************************************** // // WBEMTime::operator=(const SYSTEMTIME) // // Description: Assignment operator which is also used by the constructor. // This takes a standard WIN32 SYSTEMTIME stucture. // // Return: WBEMTime object. // //*************************************************************************** const WBEMTime & WBEMTime::operator=(const SYSTEMTIME & st) { Clear(); // set when properly assigned FILETIME t_ft; if ( SystemTimeToFileTime(&st, &t_ft) ) { // now assign using a FILETIME. *this = t_ft; } else { ASSERT_BREAK(INVALID_TIME_FORMAT); } return *this; } //*************************************************************************** // // WBEMTime::operator=(const FILETIME) // // Description: Assignment operator which is also used by the constructor. // This takes a standard WIN32 FILETIME stucture. // // Return: WBEMTime object. // //*************************************************************************** const WBEMTime & WBEMTime::operator=(const FILETIME & ft) { FileTimeToui64(&ft, &m_uTime); return *this; } //*************************************************************************** // // WBEMTime::operator=(struct tm tmin) // // Description: Assignment operator which is also used by the constructor. // This takes a standard c runtine struct tm stucture. // // Return: WBEMTime object. // //*************************************************************************** const WBEMTime & WBEMTime::operator=(const struct tm &a_tmin) { Clear(); // set when properly assigned SYSTEMTIME systemTime; if (StructtmToSystemTime(&a_tmin, &systemTime)) { *this = systemTime; } return *this; } //*************************************************************************** // // WBEMTime::operator=(struct time_t t) // // Description: Assignment operator which is also used by the constructor. // This takes a standard c runtine time_t stucture. // // Return: WBEMTime object. // //*************************************************************************** const WBEMTime & WBEMTime::operator=(const time_t & t) { if (t >= 0) { m_uTime = Int32x32To64(t, 10000000) + 116444736000000000; } else { Clear(); } return *this; } //*************************************************************************** // // WBEMTime::operator+(const WBEMTime &uAdd) // // Description: dummy function for adding two WBEMTime. It doesnt really // make sense to add two date, but this is here for Tomas's template. // // Return: WBEMTime object. // //*************************************************************************** WBEMTime WBEMTime::operator+(const WBEMTimeSpan &uAdd) const { WBEMTime ret; if (IsOk() && uAdd.IsOk()) { ret.m_uTime = m_uTime + uAdd.m_Time; } else { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return ret; } const WBEMTime &WBEMTime::operator+=( const WBEMTimeSpan &ts ) { if (IsOk() && ts.IsOk()) { m_uTime += ts.m_Time ; } else { Clear(); ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return *this ; } //*************************************************************************** // // WBEMTime::operator-(const WBEMTime & sub) // // Description: returns a WBEMTimeSpan object as the difference between // two WBEMTime objects. // // Return: WBEMTimeSpan object. // //*************************************************************************** WBEMTimeSpan WBEMTime::operator-(const WBEMTime & sub) { WBEMTimeSpan ret; if (IsOk() && sub.IsOk() && (m_uTime >= sub.m_uTime)) { ret.m_Time = m_uTime-sub.m_uTime; } else { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return ret; } WBEMTime WBEMTime::operator-(const WBEMTimeSpan & sub) const { WBEMTime ret; if (IsOk() && sub.IsOk() && (m_uTime >= sub.m_Time)) { ret.m_uTime = m_uTime - sub.m_Time; } else { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return ret; } const WBEMTime &WBEMTime::operator-=(const WBEMTimeSpan & sub) { if (IsOk() && sub.IsOk() && (m_uTime >= sub.m_Time)) { m_uTime -= sub.m_Time; } else { Clear(); ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return *this; } //*************************************************************************** // // WBEMTime::GetBSTR(void) // // This function used to CLAIM to do this: // // WRONG Description: Converts the time which is stored as the number of // nano seconds since 1970 into a bstr with this format. // YYYYMMDDHHSS.123456789 So 3:04 am, 1/1/96 would be 199601010304.000000000 // // What it really did was return some bastardized form of a dmtf string. Now // it returns a dmtf string in gmt form (which is what the docs claim). // // Return: BSTR representation of time, or NULL if error. Note that the // caller should free up this string! // //*************************************************************************** BSTR WBEMTime::GetBSTR(void) const { return GetDMTF(false) ; } //*************************************************************************** // // WBEMTime::GetDMTFNonNtfs(void) // //*************************************************************************** BSTR WBEMTime::GetDMTFNonNtfs(void) const { FILETIME t_ft1, t_ft2; BSTR t_Date = NULL; if (GetFILETIME(&t_ft1) && FileTimeToLocalFileTime(&t_ft1, &t_ft2)) { t_Date = WBEMTime(t_ft2).GetDMTF(); if (t_Date != NULL) { t_Date[21] = L'+'; t_Date[22] = L'*'; t_Date[23] = L'*'; t_Date[24] = L'*'; } } return t_Date; } //*************************************************************************** // // WBEMTime::time_t(time_t * ptm) // // Return: TRUE if OK. // //*************************************************************************** BOOL WBEMTime::Gettime_t(time_t * ptm) const { if( (!IsOk()) || (ptm == NULL) || (*this < g_Jan1970)) { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); return FALSE; } if (g_Jan1970 != *this) { LONGLONG t_tmp = ( (m_uTime - g_Jan1970.m_uTime) / 10000000); if (t_tmp <= (LONGLONG)0xffffffff) { *ptm = (time_t)t_tmp; } else { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); return FALSE; } } else { *ptm = 0; } return TRUE; } //*************************************************************************** // // WBEMTime::GetStructtm(struct tm * ptm) // // Return: TRUE if OK. // //*************************************************************************** BOOL WBEMTime::GetStructtm(struct tm * ptm) const { SYSTEMTIME systemTime; return (GetSYSTEMTIME(&systemTime) && SystemTimeToStructtm(&systemTime, ptm)); } //*************************************************************************** // // WBEMTime::GetSYSTEMTIME(SYSTEMTIME * pst) // // Return: TRUE if OK. // //*************************************************************************** BOOL WBEMTime::GetSYSTEMTIME(SYSTEMTIME * pst) const { if ((pst == NULL) || (!IsOk())) { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); return FALSE; } FILETIME t_ft; if (GetFILETIME(&t_ft)) { if (!FileTimeToSystemTime(&t_ft, pst)) { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); return FALSE; } } else { return FALSE; } return TRUE; } //*************************************************************************** // // WBEMTime::GetFILETIME(FILETIME * pst) // // Return: TRUE if OK. // //*************************************************************************** BOOL WBEMTime::GetFILETIME(FILETIME * pft) const { if ((pft == NULL) || (!IsOk())) { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); return FALSE; } ui64ToFileTime(&m_uTime, pft); return TRUE; } //*************************************************************************** // // CWbemTime::SetDMTF(BSTR wszText) // // Description: Sets the time value to the DMTF string datetime value // passed as the parameter // // Return: TRUE if OK. // //*************************************************************************** BOOL WBEMTime::SetDMTF( const BSTR a_wszText ) { wchar_t t_DefaultBuffer[] = {L"16010101000000.000000+000"} ; wchar_t t_DateBuffer[ DMTFLEN + 1 ] ; t_DateBuffer[ DMTFLEN ] = NULL ; bstr_t t_bstrDate( a_wszText ) ; // wildcard cleanup and validation // =============================== if( DMTFLEN != t_bstrDate.length() ) { ASSERT_BREAK( INVALID_TIME_FORMAT ) ; return FALSE ; } wchar_t *t_pwBuffer = (wchar_t*)t_bstrDate ; for( int t_i = 0; t_i < DMTFLEN; t_i++ ) { switch( t_pwBuffer[ t_i ] ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { // stepping on separator or sign if( DECPOS == t_i || SGNPOS == t_i ) { ASSERT_BREAK( INVALID_TIME_FORMAT ) ; return FALSE ; } t_DateBuffer[ t_i ] = t_pwBuffer[ t_i ] ; break ; } case '*': { // stepping on separator or sign if( DECPOS == t_i || SGNPOS == t_i ) { ASSERT_BREAK( INVALID_TIME_FORMAT ) ; return FALSE ; } else { // replace with default stamp t_DateBuffer[ t_i ] = t_DefaultBuffer[ t_i ] ; } break ; } case '.': { if( DECPOS != t_i ) { ASSERT_BREAK( INVALID_TIME_FORMAT ) ; return FALSE ; } t_DateBuffer[ t_i ] = t_pwBuffer[ t_i ] ; break ; } case '+': case '-': { if( SGNPOS != t_i ) { ASSERT_BREAK( INVALID_TIME_FORMAT ) ; return FALSE ; } t_DateBuffer[ t_i ] = t_pwBuffer[ t_i ] ; break ; } default: { ASSERT_BREAK( INVALID_TIME_FORMAT ) ; return FALSE ; } } } // Parse it // ======== int nYear, nMonth, nDay, nHour, nMinute, nSecond, nMicro, nOffset; WCHAR wchSep; int nRes = swscanf ( (LPCWSTR)&t_DateBuffer, L"%4d%2d%2d%2d%2d%2d.%6d%c%3d", &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond, &nMicro, &wchSep, &nOffset ); if ( ( 9 != nRes ) || ( 1601 > nYear) ) { ASSERT_BREAK(INVALID_TIME_FORMAT); return FALSE; } // Convert it to SYSTEMTIME // ======================== SYSTEMTIME st; st.wYear = (WORD)nYear; st.wMonth = (WORD)nMonth; st.wDay = (WORD)nDay; st.wHour = (WORD)nHour; st.wMinute = (WORD)nMinute; st.wSecond = (WORD)nSecond; st.wMilliseconds = nMicro / 1000; st.wDayOfWeek = 0; *this = st; // NOW we adjust for the offset // ============================ if ( IsOk() ) { int nSign = (wchSep == L'+') ? 1 : -1 ; m_uTime -= (LONGLONG)nSign * (LONGLONG)nOffset * 60 * 10000000; } else { ASSERT_BREAK( INVALID_TIME_ARITHMETIC ) ; return FALSE ; } return TRUE; } //*************************************************************************** // // BSTR WBEMTime::GetDMTF(void) // // Description: Gets the time in DMTF string datetime format. User must call // SysFreeString with the result. If bLocal is true, then the time is given // in the local timezone, else the time is given in GMT. // // Return: NULL if not OK. // //*************************************************************************** BSTR WBEMTime::GetDMTF(BOOL bLocal) const { if (!IsOk()) { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); return NULL; } SYSTEMTIME t_Systime; wchar_t chsign = L'-'; int offset = 0; // If the date to be converted is within 12 hours of // 1/1/1601, return the greenwich time ULONGLONG t_ConversionZone = 12L * 60L * 60L ; t_ConversionZone = t_ConversionZone * 10000000L ; if ( !bLocal || ( m_uTime < t_ConversionZone ) ) { if(!GetSYSTEMTIME(&t_Systime)) { return NULL; } } else { if (GetSYSTEMTIME(&t_Systime)) { offset = GetLocalOffsetForDate(&t_Systime); WBEMTime wt; if (offset >= 0) { chsign = '+'; wt = *this + WBEMTimeSpan(0, 0, offset, 0); } else { offset *= -1; wt = *this - WBEMTimeSpan(0, 0, offset, 0); } wt.GetSYSTEMTIME(&t_Systime); } else { return NULL; } } LONGLONG tmpMicros = m_uTime%10000000; LONG micros = (LONG)(tmpMicros / 10); BSTR t_String = SysAllocStringLen(NULL, DMTFLEN + 1); if ( ! t_String ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } swprintf( t_String, L"%04.4d%02.2d%02.2d%02.2d%02.2d%02.2d.%06.6d%c%03.3ld", t_Systime.wYear, t_Systime.wMonth, t_Systime.wDay, t_Systime.wHour, t_Systime.wMinute, t_Systime.wSecond, micros, chsign, offset ); return t_String ; } /////////////////////////////////////////////////////////////////////////// // WBEMTimeSpan - This class holds timespan values. The data is stored // in 100 nanosecond units (like FILETIME). //*************************************************************************** // // WBEMTimeSpan::WBEMTimeSpan(int iDays, int iHours, int iMinutes, int iSeconds, // int iMSec, int iUSec, int iNSec) // // Description: Constructor. // //*************************************************************************** WBEMTimeSpan::WBEMTimeSpan(int iDays, int iHours, int iMinutes, int iSeconds, int iMSec, int iUSec, int iNSec) { m_Time = 0; //todo, check values!!! m_Time += iSeconds; m_Time += iMinutes * 60; m_Time += iHours * 60 * 60; m_Time += iDays * 24 * 60 * 60; m_Time *= 10000000; m_Time += iNSec / 100; // Nanoseconds m_Time += iUSec*10; // Microseconds m_Time += iMSec*10000; // Milliseconds } WBEMTimeSpan::WBEMTimeSpan ( const FILETIME &ft ) { ASSERT_BREAK(DEPRECATED); *this = ft ; } WBEMTimeSpan::WBEMTimeSpan ( const time_t & t ) { ASSERT_BREAK(DEPRECATED); *this = t ; } ; //*************************************************************************** // // WBEMTimeSpan::operator=(const BSTR bstrWbemFormat) // // Return: WBEMTimeSpan object. // //*************************************************************************** const WBEMTimeSpan & WBEMTimeSpan::operator=(const BSTR bstrWbemFormat) { Clear(); // all characters should be digits except for one which // must be a period if ((bstrWbemFormat == NULL) || (bstrWbemFormat[DECPOS] != L'.') || (wcslen(bstrWbemFormat) != DMTFLEN) || (bstrWbemFormat[SGNPOS] != L':') ) { ASSERT_BREAK(INVALID_TIME_FORMAT); return *this; } int nDays, nHours, nMinutes, nSeconds, nMicros, nOffset; WCHAR wchSep; int nRes = swscanf ( bstrWbemFormat, L"%8d%2d%2d%2d.%6d%c%3d", &nDays, &nHours, &nMinutes, &nSeconds, &nMicros, &wchSep, &nOffset ); if ( (nRes != 7) || ( nOffset != 0) ) { ASSERT_BREAK(INVALID_TIME_FORMAT); return *this; } *this = WBEMTimeSpan(nDays, nHours, nMinutes, nSeconds, 0, nMicros, 0); return *this; } //*************************************************************************** // // WBEMTimeSpan::operator=(const FILETIME &) // WBEMTimeSpan::operator=(const time_t &) // // Description: Assignment operator which is also used by the constructor. // // Return: WBEMTimeSpan object. // //*************************************************************************** const WBEMTimeSpan & WBEMTimeSpan::operator=(const FILETIME &ft) { ASSERT_BREAK(DEPRECATED); ULONGLONG uTemp; FileTimeToui64(&ft, &uTemp); m_Time = uTemp; return *this; } const WBEMTimeSpan & WBEMTimeSpan::operator=(const time_t & t) { ASSERT_BREAK(DEPRECATED); ULONGLONG uTemp = 0; uTemp = t; if (t >= 0) { m_Time = uTemp * 10000000; } else { Clear(); } return *this; } //*************************************************************************** // // WBEMTimeSpan::operator +(const WBEMTimeSpan &uAdd) // // Description: function for adding two WBEMTimeSpan objects. // // Return: WBEMTimeSpan object. // //*************************************************************************** WBEMTimeSpan WBEMTimeSpan::operator+(const WBEMTimeSpan &uAdd) const { WBEMTimeSpan ret; if (IsOk() && uAdd.IsOk()) { ret.m_Time = m_Time + uAdd.m_Time; } else { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return ret; } const WBEMTimeSpan &WBEMTimeSpan::operator+= ( const WBEMTimeSpan &uAdd ) { if (IsOk() && uAdd.IsOk()) { m_Time += uAdd.m_Time ; } else { Clear(); ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return *this ; } //*************************************************************************** // // WBEMTimeSpan::operator -(const WBEMTimeSpan &uAdd) // // Description: function for adding two WBEMTimeSpan objects. // // Return: WBEMTimeSpan object. // //*************************************************************************** WBEMTimeSpan WBEMTimeSpan::operator-(const WBEMTimeSpan &uSub) const { WBEMTimeSpan ret; if (IsOk() && uSub.IsOk() && (m_Time >= uSub.m_Time)) { ret.m_Time = m_Time - uSub.m_Time; } else { ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return ret; } const WBEMTimeSpan &WBEMTimeSpan::operator-= ( const WBEMTimeSpan &uSub ) { if (IsOk() && uSub.IsOk() && (m_Time >= uSub.m_Time)) { m_Time -= uSub.m_Time; } else { Clear(); ASSERT_BREAK(INVALID_TIME_ARITHMETIC); } return *this; } //*************************************************************************** // // WBEMTimeSpan::GetBSTR(void) // // Description: Converts the time which is stored as the number of // 100 nano second units into a dmtf formatted string // ddddddddhhmmss.mmmmmm:000 // // Return: BSTR representation of time, or NULL if error. Note that the // caller should free up this string! // //*************************************************************************** BSTR WBEMTimeSpan::GetBSTR(void) const { if(!IsOk()) { return NULL; } ULONGLONG Time = m_Time; // The /10 is to convert from 100ns to microseconds long iMicro = (long)((Time % 10000000) / 10); Time /= 10000000; int iSec = (int)(Time % 60); Time /= 60; int iMin = (int)(Time % 60); Time /= 60; int iHour = (int)(Time % 24); Time /= 24; BSTR t_String = SysAllocStringLen(NULL, DMTFLEN + 1); if ( ! t_String ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } swprintf(t_String, L"%08I64i%02d%02d%02d.%06ld:000", Time, iHour, iMin, iSec, iMicro); return t_String ; } //*************************************************************************** // // WBEMTimeSpan::Gettime_t(void) // WBEMTimeSpan::GetFILETIME(void) // // Description: Converts the time span which is stored as the number of // nano seconds into common stuctures. // // Return: TRUE if OK. // //*************************************************************************** BOOL WBEMTimeSpan::Gettime_t(time_t * ptime_t) const { ASSERT_BREAK(DEPRECATED); if(!IsOk()) { return FALSE; } *ptime_t = (DWORD)(m_Time / 10000000); return TRUE; } BOOL WBEMTimeSpan::GetFILETIME(FILETIME * pst) const { ASSERT_BREAK(DEPRECATED); if(!IsOk()) { return FALSE; } ULONGLONG uTemp; uTemp = m_Time; ui64ToFileTime(&uTemp,pst); return TRUE; }