I need to be able to convert local time to UTC on a Windows machine. I found the SystemTimeToTzSpecificLocalTime API that claims to do this, but then I read its description and found this:
The SystemTimeToTzSpecificLocalTime function may calculate the local time incorrectly under the following conditions:
<li>The time zone uses a different UTC offset for the old and new years.</li>
<li>The UTC time to be converted and the calculated local time are in different years.</li>
My first rhetorical question to MS, "How difficult is it to write a reliable API?"
And then, the actual question — how do you do it to work in 100% of the times? (And not like that API suggests.)
The answer to both your questions is that it is essentially impossible. This is one of the reasons computer science folks tend to hate dealing with local time.
Here are some examples of the confounding issues: When we jump back an hour from 2:00 to 1:00, there are two 1:30's. We also have no way to know today what the daylight savings time rules, if any, will be in ten years. Time zone boundaries are sometimes moved, so just knowing that you're in Pacific time today may not be enough to tell us what your time zone offset was 85 years ago. There is no way to know today what leap seconds may or may not be inserted in the future.
If you find yourself in a situation when it is possible, you will have to code in the specific circumstances that make those operations possible in your particular case. The operations provided are generalized and provide "usually correct" results without constraining the cases in which they can be used.
Moral: Don't use local time except for display. And even then, converting times in the past or future into local times is problematic.
Since the DST periods sometimes change in certain areas, it's hard to write something that is correct in all cases, past and future.
Nevertheless, I you need this functionality, I would suggest using the C functions (localtime, mktime, ...). I recently had a problem where the Windows function SystemTimeToTzSpecificLocalTime did not work correctly on a Citrix server (Citrix does quite some strange (but advanced) things regarding timezones), but the C functions worked correctly.