|
|
#include <timeutil.h>
////////////////////////////////////////////////////////////////////////////
//
// Helper Function TimeDiff(tm1, tm2)
// helper function to find the difference (in seconds) of 2 system times
//
// Input: 2 SYSTEMTIME structures
// Output: None
// Return: seconds of difference
// > 0 if tm2 is later than tm1
// = 0 if tm2 and tm1 are the same
// < 0 if tm2 is earlier than tm1
//
// On error the function returns 0 even if the two times are not equal
//
// Comment: If the number of seconds goes beyond INT_MAX (that is
// more than 24,855 days, INT_MAX is returned.
// If the number of seconds goes beyond INT_MIN (a negative value,
// means 24,855 days ago), INT_MIN is returned.
//
////////////////////////////////////////////////////////////////////////////
int TimeDiff(SYSTEMTIME tm1, SYSTEMTIME tm2) { LONGLONG i64Sec; int iSec; //
// convert the two times from SYSTEMTIME format into FILETIME format
//
FILETIME ftm1, ftm2;
if ((SystemTimeToFileTime(&tm1, &ftm1) == 0) || (SystemTimeToFileTime(&tm2, &ftm2) == 0)) { return 0; }
if ((ftm1.dwHighDateTime == ftm2.dwHighDateTime) && (ftm1.dwLowDateTime == ftm2.dwLowDateTime)) { return 0; }
//
// convert the two times from FILETIME to LARGE_INTEGER type,
//
LARGE_INTEGER i64Sec1, i64Sec2; i64Sec2.LowPart = ftm2.dwLowDateTime; i64Sec2.HighPart = ftm2.dwHighDateTime; i64Sec1.LowPart = ftm1.dwLowDateTime; i64Sec1.HighPart = ftm1.dwHighDateTime; //
// since Windows support LONGLONG, we directly use the quad portion of LARGE_INTEGER
// to get the difference, which is 100 nanoseconds. Then convert the number to seconds.
//
i64Sec = (i64Sec2.QuadPart - i64Sec1.QuadPart) / NanoSec100PerSec;
//
// convert the LONGLONG seconds value into integer, since it shouldn't exceed
// integer limit
//
if (i64Sec > INT_MAX) { //
// just in case user is playing with the system time.
// Otherwise, this difference should not go beyond 68 years.
//
iSec = INT_MAX; } else { if (i64Sec < INT_MIN) { iSec = INT_MIN; } else { iSec = (int)i64Sec; } } return iSec; }
////////////////////////////////////////////////////////////////////////////
//
// Helper Function TimeAddSeconds(SYSTEMTIME, int, SYSTEMTIME* )
// helper function to calculate time by adding n seconds to
// the given time.
//
// Input: a SYSTEMTIME as base time, an int as seconds to add to the base time
// Output: new time
// Return: HRESULT
//
////////////////////////////////////////////////////////////////////////////
HRESULT TimeAddSeconds(SYSTEMTIME tmBase, int iSeconds, SYSTEMTIME* pTimeNew) { // fixcode use i64 calcs
FILETIME ftm;
if (SystemTimeToFileTime(&tmBase, &ftm) == 0) { return E_FAIL; }
LARGE_INTEGER i64Sec; i64Sec.LowPart = ftm.dwLowDateTime; i64Sec.HighPart = ftm.dwHighDateTime;
__int64 i64Delay = NanoSec100PerSec; i64Delay *= iSeconds; i64Sec.QuadPart += i64Delay; ftm.dwLowDateTime = i64Sec.LowPart; ftm.dwHighDateTime = i64Sec.HighPart; if (FileTimeToSystemTime(&ftm, pTimeNew) == 0) { return E_FAIL; } return S_OK; }
//=======================================================================
// String2SystemTime
//=======================================================================
HRESULT String2SystemTime(LPCTSTR pszDateTime, SYSTEMTIME *ptm) { // we expect the date/time format as 4-digit year ISO:
// 01234567890123456789
// YYYY.MM.DD HH:MM:SS
//
const TCHAR C_DATE_DEL = _T('.'); const TCHAR C_DATE_TIME_DEL = _T(' '); const TCHAR C_TIME_DEL = _T(':'); TCHAR szBuf[20]; LPTSTR pszDestEnd;
if (FAILED(StringCchCopyEx(szBuf, ARRAYSIZE(szBuf), pszDateTime, &pszDestEnd, NULL, MISTSAFE_STRING_FLAGS)) || 19 != pszDestEnd - szBuf) { return E_INVALIDARG; }
for (int i = 0; i < 19; i++) { switch (i) { case 4: case 7: if (szBuf[i] != C_DATE_DEL) { return E_INVALIDARG; } break; case 10: if (szBuf[i] != C_DATE_TIME_DEL) { return E_INVALIDARG; } break; case 13: case 16: if (szBuf[i] != C_TIME_DEL) { return E_INVALIDARG; } break; default: if (szBuf[i] < _T('0') || pszDateTime[i] > _T('9')) { return E_INVALIDARG; } break; } }
//
// get values
//
szBuf[4] = EOS; ptm->wYear = (short)_ttoi(szBuf); szBuf[7] = EOS; ptm->wMonth = (short)_ttoi(szBuf + 5); szBuf[10] = EOS; ptm->wDay = (short)_ttoi(szBuf + 8); szBuf[13] = EOS; ptm->wHour = (short)_ttoi(szBuf + 11); szBuf[16] = EOS; ptm->wMinute = (short)_ttoi(szBuf + 14); ptm->wSecond = (short)_ttoi(szBuf + 17); ptm->wMilliseconds = 0;
//
// validate if this constructed SYSTEMTIME data is good
//
// fixcode should this just be SystemTimeToFileTime() ?
if (GetDateFormat(LOCALE_SYSTEM_DEFAULT,DATE_SHORTDATE, ptm, NULL, NULL, 0) == 0) { return E_INVALIDARG; } if (GetTimeFormat(LOCALE_SYSTEM_DEFAULT,LOCALE_NOUSEROVERRIDE, ptm, NULL, NULL, 0) == 0) { return E_INVALIDARG; }
return S_OK; }
//=======================================================================
// SystemTime2String
//=======================================================================
HRESULT SystemTime2String(SYSTEMTIME & tm, LPTSTR pszDateTime, size_t cchSize) { if ( pszDateTime == NULL ) { return E_INVALIDARG; }
// bug fixed: changed from wsprintf to _snwprintf because an invalid
// date on tm was causing buffer overflow
LPTSTR pszDestEnd; if (FAILED(StringCchPrintfEx( pszDateTime, cchSize, &pszDestEnd, NULL, MISTSAFE_STRING_FLAGS, TEXT("%4i.%02i.%02i %02i:%02i:%02i"), tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond)) || pszDestEnd - pszDateTime != 19) { return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); }
return S_OK; }
|