Я ищу WinAPI низкого уровня для форматирования даты и времени из FILETIME
в локализованную строку с выводом даты, времени или даты и времени вместе.
Путем изменения МФЦ COleDateTime
Я смог найти VarBstrFromDate
функция, которая «своего рода» работает. Поэтому я пытался выяснить, есть ли еще один более надежный API, способный это сделать.
Есть две проблемы с VarBstrFromDate
что я мог видеть:
1) Он не достоверно сообщает дату или время. Например, если я назову это так midnight Dec. 31, 1899
:
BSTR bstr = NULL;
HRESULT hr = ::VarBstrFromDate(1.0, LANG_USER_DEFAULT, VAR_FOURDIGITYEARS, &bstr);
::SysFreeString(bstr);
это возвращается "12/31/1899"
без временной части.
Или, если я призываю это, скажем, noon Dec. 30, 1899
:
BSTR bstr = NULL;
HRESULT hr = ::VarBstrFromDate(0.5, LANG_USER_DEFAULT, VAR_FOURDIGITYEARS, &bstr);
::SysFreeString(bstr);
это возвращается "12:00:00 PM"
без даты часть.
2) Кроме того, конвертация из FILETIME
в DATE
несколько сложно, особенно для дат до 30 декабря 1899 года. Опять же, изменив MFC, я смог найти, что SystemTimeToVariantTime
может сделать это через SYSTEMTIME
структура. Вроде назад, но хорошо. Но потом я увидел это чудовище в atlcore.h
:
inline BOOL AtlConvertSystemTimeToVariantTime(
_In_ const SYSTEMTIME& systimeSrc,
_Out_ double* pVarDtTm)
{
ATLENSURE(pVarDtTm!=NULL);
//Convert using ::SystemTimeToVariantTime and store the result in pVarDtTm then
//convert variant time back to system time and compare to original system time.
BOOL ok = ::SystemTimeToVariantTime(const_cast<SYSTEMTIME*>(&systimeSrc), pVarDtTm);
SYSTEMTIME sysTime;
::ZeroMemory(&sysTime, sizeof(SYSTEMTIME));
ok = ok && ::VariantTimeToSystemTime(*pVarDtTm, &sysTime);
ok = ok && (systimeSrc.wYear == sysTime.wYear &&
systimeSrc.wMonth == sysTime.wMonth &&
systimeSrc.wDay == sysTime.wDay &&
systimeSrc.wHour == sysTime.wHour &&
systimeSrc.wMinute == sysTime.wMinute &&
systimeSrc.wSecond == sysTime.wSecond);
return ok;
}
Знаете ли вы, почему они проверяют результат, возвращенный SystemTimeToVariantTime
к тому времени передавая его через VariantTimeToSystemTime
таким неловким образом? Означает ли это, что SystemTimeToVariantTime
может вернуть неверный результат или как?
Во всяком случае, я думал найти другой API, который не будет полагаться на преобразование в плавающую точку DATE
,
Вы можете использовать классические функции времени в kernel32: первый вызов FileTimeToSystemTime
а затем позвоните GetTimeFormat
а также GetDateFormat
. SHFormatDateTime
является оберткой вокруг этих функций.
Оболочка также имеет StrFromTimeInterval
если вам нужен дружелюбный текст продолжительности времени.
Других решений пока нет …