Converting from a UTC-based SYSTEMTIME directly to a local-time-based SYSTEMTIME
Last year, I presented this commutative diagram
I claimed that there was no function to complete the commutative diagram by connecting the bottom two boxes.
I was wrong, but I’m going to try to get off on a technicality.
You can connect the two boxes by calling
NULL as the time zone parameter, which means “Use the current time zone.”
This works here because the time being converted always refers to the current time.
Here comes the technicality.
This technique doesn’t work in general because
SystemTimeToTzSpecificLocalTime uses the time zone in effect at the time being converted, whereas the
FileTimeToLocalFileTime function uses the time zone in effect right now. Furthermore, it doesn’t take into account changes in daylight savings rules that may have historically been different from the current set of rules. (Though this is easily repaired by switching to
SystemTimeToTzSpecificLocalTimeEx.) The trick works here because the time we are converting is right now.
In other words, the more general diagram does not commute. Instead, it looks more like this:
This is why the documentation for
FileTimeToLocalFileTime tells you that if you want to get from the upper left corner to the upper right corner while accounting for daylight saving time relative to the time being converted, then you need to take the long way around.
So what we have is not so much a commutative diagram as a something like covering space: If you start at any box and travel around the diagram, you won’t necessarily end up where you started. Let’s start at the upper left corner for the sake of example.
When you return to the upper left box, you might end up somewhere else, probably an hour ahead of or behind where you started. Each time you take a trip around the diagram, you drift another hour further away. Well, until you hit another daylight saving time changeover point.