如何从ULONGLONG毫秒创建SYSTEMTIME结构?

时间:2012-06-20 15:15:02

标签: c++ windows visual-c++ datetime

我想使用::GetSystemTime()::GetTickCount64来计算它,而不是使用WMI来获取上次启动时间。但是一旦达到毫秒,我就不知道如何回到FILETIME对象。

我试过了:

static ULONGLONG FileTimeToMillis(const FILETIME &ft)
{
    ULARGE_INTEGER uli;
    uli.LowPart = ft.dwLowDateTime; // could use memcpy here!
    uli.HighPart = ft.dwHighDateTime;

    return uli.QuadPart/10000;
}

static void MillisToSystemTime(ULONGLONG millis, SYSTEMTIME *st)
{
   UINT64 t = static_cast<UINT64>(-10000) * static_cast<UINT64>(millis);

   FILETIME ft;
   ft.dwLowDateTime = static_cast<DWORD(t & 0xFFFFFFFF);
   ft.dwHighDateTime = static_cast<DWORD>(t >> 32);

   ::FileTimeToSystemTime(&ft, st);
}

void main()
{
    SYSTEMTIME st, lt, st2, lt2;

    ::GetSystemTime(&st);
    ::GetLocalTime(&lt);

    cout << "The system time is: " << st.wHour << ":" << st.wMinute << ":" << st.wSecond << endl;
    cout << "The local time is: "  << lt.wHour << ":" << lt.wMinute << ":" << lt.wSecond << endl;

    FILETIME sft, lft;
    ::SystemTimeToFileTime(&st, &sft);
    ::SystemTimeToFileTime(&lt, &lft);  

    cout << "The system time in millis is: " << FileTimeToMillis(sft) << endl;
    cout << "The local time in millis is: "  << FileTimeToMillis(lft) << endl;

    MillisToSystemTime(FileTimeToMillis(sft), &st2);
    MillisToSystemTime(FileTimeToMillis(sft), &lt2);

    cout << "The system time (post conversion) is: " << st2.wHour << ":" << st2.wMinute << ":" << st2.wSecond << endl;
    cout << "The local time (post conversion) is: "  << lt2.wHour << ":" << lt2.wMinute << ":" << lt2.wSecond << endl;
}

但我当然不会得到预期的结果。相反,我得到:

The system time is: 15:5:2
The local time is: 10:5:2
The system time in millis is: 12984678302935
The local time in millis is: 12984660302935
The system time (post conversion) is: 52428:52428:52428
The local time (post conversion) is: 52428:52428:52428

有什么想法吗?请不要告诉我使用Boost或因为我无法使用它。

2 个答案:

答案 0 :(得分:4)

  

系统时间(转换后)为:52428:52428:52428

当您获得怪码值时,请始终先转换为十六进制。 52428 == 0xcccc。这是调试版本生成的代码用于初始化变量的值。所以你正在看未初始化的记忆。

下一步的防御策略是永远忽略Windows api函数的返回值。使用VERIFY()宏,就像MFC中可用的宏。然后,您将很容易看到FileTimeToSystemTime()失败。

错误是-10000。

答案 1 :(得分:3)

原来我做的算术运算不正确。在我阅读ULARGE_INTEGERFILETIME之后,我发现我可以直接使用QuadPart的{​​{1}},然后正确地拉出高低部分,同时避免位移和混乱。

ULARGE_INTEGER

Key正在阅读MSDN中的以下内容:

  

不建议您添加和减去值   FILETIME结构获取相对时间。相反,你应该复制   文件时间的低位和高位部分为ULARGE_INTEGER   结构,在QuadPart成员上执行64位运算,然后复制   LowPart和HighPart成员进入FILETIME结构。