September 23rd, 2026
heartmind blown3 reactions

When working with Win32 FILETIME, don’t forget that you have std::chrono now

Some time ago, I was looking at a pull request, and saw that the code was manually calculating the “number of minutes since the last change” by doing annoying math.

static const DWORD c_TicksPerSecond = 10000000;
static const DWORD c_SecondsPerMinute = 60;

uint64_t FileTimeToULongLong(FILETIME time)
{
    ULARGE_INTEGER value;

    value.LowPart = time.dwLowDateTime;
    value.HighPart = time.dwHighDateTime;

    return value.QuadPart;
}
DWORD GetMinutesSinceLastChange()
{
    FILETIME now;
    GetSystemTimeAsFileTime(&now);

    uint64_t now64 = FileTimeToULongLong(now);
    uint64_t last64 = FileTimeToULongLong(m_lastChange);

    if (now64 < last64) {
        return 0;
    }

    uint64_t diff = last64 - now64;
    return static_cast<DWORD>(diff /
        (static_cast<uint64_t>(c_dwSecondsPerMinute) *
         static_cast<uint64_t>(c_TicksPerSecond)));
}

Okay, first of all, we have helpers in the Windows Implementation Library (wil) to save you a lot of typing and calculating weird constants.

DWORD GetMinutesSinceLastChange()
{
    FILETIME now;
    GetSystemTimeAsFileTime(&now);

    int64_t now64 = wil::filetime::to_int64(now);
    int64_t last64 = wil::filetime::to_int64(m_lastChange);

    if (now64 < last64) {
        return 0;
    }

    int64_t diff = last64 - now64;
    return static_cast<DWORD>(diff / wil::filetime_duration::one_minute);
}

But even better: You have std::chrono now. C++/WinRT has already written the weird constants for you, and the C++ standard library has all the convenient helper functions.

DWORD GetMinutesSinceLastChange()
{
    auto last = winrt::clock::from_FILETIME(m_lastChange);
    auto now = (std::max)(winrt::clock::now(), last);
    return (now - last) / 1min;
}

Topics

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

6 comments

Sort by :
  • Sigge Mannen 2 days ago

    Why is

    (std::max)

    in paranteses?

    • LB 1 day ago

      It’s for people who forget to define NOMINMAX before including Windows.h

    • skSdnW 2 days ago

      Parentheses to avoid the Windows max macro?

      • Sigge Mannen 3 hours ago

        Thanks, i learned that this is the way to avoid function macro expansion

  • LB 2 days ago

    I often see comments elsewhere complaining about chrono but I’ve never understood why, it makes stuff like this so much simpler.

    • Yexuan Xiao

      I think the reason is that these people only treat time as a number, and they’ve gotten used to it. A similar problem also happens with Unicode.