Here's how I'm going about it:
- Pretending against better knowledge the
tm
structure holds local time (non-DST if anyone asks; it doesn't matter, but must be consistent with step 3), convert it to time_t
.
- Convert the date back into a
tm
structure, but this time in UTC representation.
- Pretending against better knowledge that
tm
structure to also hold local (non-DST if anyone asks, but more importantly consistent with step 1), and convert it to time_t
once more.
- From the two
time_t
results I can now compute the difference between local time (non-DST if anyone asks) and UTC in time_t
units.
- Adding that difference to the first
time_t
result gives me the proper time in UTC.
Convoluted, but I'm confident it should work. Unless the computer uses a TAI-based clock, in which case on rare occasions the result might be off by a second. The consistent DST setting (as opposed to having mktime auto-detect it) is necessary so that I don't get thrown off by an entire hour when trying to compute a date/time close to the start or end of the DST period.
tm tt;
// populate tt here
tt.tm_isdst = 0;
time_t tLoc = mktime(&tt);
tt = *gmtime(&tLoc);
tt.tm_isdst = 0;
time_t tRev = mktime(&tt);
time_t tDiff = tLoc - tRev;
time_t tUTC = tLoc + tDiff;
However, this approach comes with the caveat that gmtime()
is not thread-safe. So if anyone has any better solution, I'd love to hear it.