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:

Format Time zone Function Algorithm
FILE­TIME UTC Get­System­Time­As­File­Time (Native format)
FILE­TIME Local (None) Get­System­Time­As­File­Time + File­Time­To­Local­File­Time
SYSTEM­TIME UTC Get­System­Time  Get­System­Time­As­File­Time + File­Time­To­System­Time
SYSTEM­TIME Local Get­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­ 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?