WinAPI将FILETIME格式化为具有日期和/或时间的本地化字符串

时间:2018-03-14 18:54:38

标签: c++ winapi localization mfc filetime

我正在寻找一个低级WinAPI,将日期时间从FILETIME格式化为一个本地化字符串,并输出日期,时间或日期和时间。

通过颠倒MFC的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有点棘手,特别是对于1899年12月30日之前的日期。再次,通过扭转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可能会返回错误的结果,或者是什么?

无论如何,我正在考虑寻找另一种不依赖于转换为浮点DATE的API。

1 个答案:

答案 0 :(得分:4)

您可以使用kernel32中的经典时间函数:首先调用FileTimeToSystemTime,然后调用GetTimeFormatGetDateFormatSHFormatDateTime是这些函数的包装器。

如果你需要友好的持续时间文本,那么shell也有StrFromTimeInterval