简体   繁体   English

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

[英]WinAPI to format FILETIME as a localized string with date and/or time

I'm looking for a low-level WinAPI to format date-time from FILETIME to a localized string with an output of a date, time, or date and time together. 我正在寻找一种低级WinAPI,以将FILETIME日期时间格式化为本地化的字符串,并输出日期,时间或日期和时间。

By reversing the MFC's COleDateTime I was able to find VarBstrFromDate function that "kinda" works. 通过反转MFC的COleDateTime我能够找到“ kinda”起作用的VarBstrFromDate函数。 So I was trying to see if there's another more reliable API that can accomplish that. 因此,我试图查看是否还有另一个更可靠的API可以完成此任务。

There are two issues with VarBstrFromDate that I could see: 我可以看到VarBstrFromDate有两个问题:

1) It doesn't reliably report the date or time parts. 1)它不能可靠地报告日期或时间部分。 For instance, if I call it as such for midnight Dec. 31, 1899 : 例如,如果我这样称呼它是在midnight Dec. 31, 1899

BSTR bstr = NULL;
HRESULT hr = ::VarBstrFromDate(1.0, LANG_USER_DEFAULT, VAR_FOURDIGITYEARS, &bstr);
::SysFreeString(bstr);

it returns "12/31/1899" without the time part. 它返回不带时间部分的"12/31/1899"

Or, if I call it for, say, noon Dec. 30, 1899 : 或者,如果我打电话说noon Dec. 30, 1899

BSTR bstr = NULL;
HRESULT hr = ::VarBstrFromDate(0.5, LANG_USER_DEFAULT, VAR_FOURDIGITYEARS, &bstr);
::SysFreeString(bstr);

it returns "12:00:00 PM" without the date part. 它返回不带日期部分的"12:00:00 PM"

2) Additionally, conversion from FILETIME to DATE is somewhat tricky, especially for dates prior to Dec. 30, 1899. Again, by reversing MFC I was able to find that SystemTimeToVariantTime can do it via the SYSTEMTIME struct. 2)此外,从FILETIMEDATE转换有些棘手,尤其是对于1899年12月30日之前的日期。再次,通过反转MFC,我发现SystemTimeToVariantTime可以通过SYSTEMTIME结构来完成。 Kinda backwards, but OK. 金达倒退了,但是还可以。 But then I saw this monstrosity in the atlcore.h : 但是后来我在atlcore.h看到了这种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;
}

Do you know why they're checking the result returned by SystemTimeToVariantTime by then passing it through VariantTimeToSystemTime in such an awkward way? 您知道他们为什么要检查SystemTimeToVariantTime返回的结果,然后以尴尬的方式将其传递给VariantTimeToSystemTime吗? Does it mean that SystemTimeToVariantTime may return an incorrect result, or what? 这是否意味着SystemTimeToVariantTime可能返回错误的结果,还是什么?

Anyway, I was thinking to find another API that wouldn't rely on conversion to a floating-point DATE . 无论如何,我一直在想找到另一个不依赖于转换为浮点数DATE API。

You can use the classic time functions in kernel32: First call FileTimeToSystemTime and then call GetTimeFormat and GetDateFormat . 您可以在kernel32中使用经典的时间函数:首先调用FileTimeToSystemTime ,然后调用GetTimeFormatGetDateFormat SHFormatDateTime is a wrapper around those functions. SHFormatDateTime是这些函数的包装。

The shell also has StrFromTimeInterval if you need friendly text of time duration. 如果需要持续时间的友好文本,则外壳程序还将具有StrFromTimeInterval

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM