0

我正在寻找一个低级 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) 此外,从FILETIMEtoDATE的转换有些棘手,尤其是对于 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可能会返回不正确的结果,还是什么?

无论如何,我正在考虑找到另一个不依赖于转换为 floating-point 的 API DATE

4

1 回答 1

4

您可以使用 kernel32 中的经典时间函数:先调用FileTimeToSystemTime再调用GetTimeFormatand GetDateFormatSHFormatDateTime是这些函数的包装器。

StrFromTimeInterval如果您需要持续时间的友好文本,shell 也有。

于 2018-03-14T20:26:51.357 回答