On the various ways of getting the current time and date in Win32

Raymond Chen

Raymond

There are a number of functions in Win32
that obtain the current date and time.
Here’s how they fit together:

The starting point is
Get­System­Time­As­File­Time.
This returns the current time in UTC in the form of a
FILE­TIME structure.
This also happens to be the time format used internally by the system,
so this value can be retrieved with a minimum of fuss.

You can also call
Get­System­Time which returns the current UTC time
in the form of a
SYSTEM­TIME structure.
To do this, the operating system takes the
current FILE­TIME and then calls
the moral equivalent of
File­Time­To­System­Time,
which
does a boatload of gnarly math
to decompose the
FILE­TIME
into year, month, day, hour, minute, second, and millisecond.

Meanwhile, you can also get the current local time by taking
the
FILE­TIME returned by
Get­System­Time­As­File­Time,
then passing it to
File­Time­To­Local­File­Time.

And finally, there’s
Get­Local­Time,
which does the same thing
as
Get­System­Time,
but it starts with the local file time.

In equations:

FormatTime zoneFunctionAlgorithm
FILE­TIMEUTCGet­System­Time­As­File­Time(Native format)
FILE­TIMELocal(None)Get­System­Time­As­File­Time
+ File­Time­To­Local­File­Time
SYSTEM­TIMEUTCGet­System­Time Get­System­Time­As­File­Time+ File­Time­To­System­Time
SYSTEM­TIMELocalGet­Local­Time Get­System­Time­As­File­Time
+ File­Time­To­Local­File­Time
+ File­Time­To­System­Time

I happen to be a fan of commutative diagrams.
(Though since there are no closed loops, there is nothing to commute.)

A 2-by-2 grid of boxes.
The top row is labeled FILE­TIME; the bottom row is labeled
SYSTEM­TIME.
The first column is labeled UTC; the second column is labeled Local.
The upper left box
is labeled Get­System­Time­As­File­Time.
There is an outgoing arrow to the right
labeled
File­Time­To­Local­File­Time leading to the box in the
second column labeled None.
There is an outgoing arrow downward labeled
File­Time­To­System­Time
leading to the box in the second row, first column,
labeled Get­System­Time.
From the box in the upper right corner labeled None,
there is an outgoing arrow
downward labeled
File­Time­To­System­Time
leading to the box in the second row, second column,
labeled Get­Local­Time.
UTC
Local
File­Time
Get­System­Time­As­File­Time
File­Time­To­Local­File­Time
(None)
File­Time­To­System­Time
File­Time­To­System­Time
SYSTEM­TIME
Get­System­Time
Get­Local­Time

To complete the commutative diagram,
there would be an arrow connecting the bottom two boxes called
System­Time­To­Local­Time,
but there is no such function.

Today’s article was inspired by some code I ran across which did this:

SYSTEMTIME stNow;
FILETIME ftNow;
GetSystemTime(&stNow);
SystemTimeToFileTime(&stNow, &ftNow);

That code unwittingly takes an excursion from
Get­System­Time­As­File­Time
through
File­Time­To­System­Time to
Get­System­Time,
then back through
System­Time­To­File­Time&shy to
return to
Get­System­Time­As­File­Time,
just so that it can end up where it started,
but with a lot of extra math (and loss of resolution).

Exercise: How would you implement the
System­Time­To­Local­Time
function?

Raymond Chen
Raymond Chen

Follow Raymond