248 lines
6.6 KiB
C++
248 lines
6.6 KiB
C++
|
#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;
|
||
|
}
|
||
|
|