Following function which I have written in Delphi (however, my question is not specific to Delphi) does output the current UTC unix timestamp:
function CurrentUnixTimeUTC: int64;
var
tzi: TTimeZoneInformation;
begin
// Get the current unix timestamp in local time.
Result := DateTimeToUnix(Now);
// First, add the DST specific bias
case GetTimeZoneInformation(tzi) of
TIME_ZONE_ID_INVALID:
RaiseLastOSError;
TIME_ZONE_ID_UNKNOWN:
; // Unknown what to do. We simply don't apply any bias.
TIME_ZONE_ID_STANDARD:
Result := Result + tzi.StandardBias * 60;
TIME_ZONE_ID_DAYLIGHT:
Result := Result + tzi.DaylightBias * 60;
end;
// Now apply the region specific bias
Result := Result + tzi.Bias * 60;
end;
The function works and has the same output in Germany as in California.
While researching MSDN, I have additionally found the function GetDynamicTimeZoneInformation
.
From reading the MSDN (which has an incomplete definition of the member "Bias" btw), it is not clear to me if simply calling GetTimeZoneInformation
is sufficient to have my function CurrentUnixTimeUTC
also work in regions which have dynamic DST settings (i.e. the DST dates change from year to year). In other words, can GetTimeZoneInformation
sucessfully tell if the system is currently in DST mode or not, or do I need to call GetDynamicTimeZoneInformation
instead, if I want to be compatible with computers which are in a time zone where dynamic DST rules are applied?
If you're just looking to get the current UTC time from the Win32 API, you shouldn't involve time zones. The OS will handle that automatically. It's faster to simply get the UTC time directly using GetSystemTime
, or GetSystemTimeAsFileTime
.
For example, in .NET, DateTime.UtcNow
just makes a call to GetSystemTimeAsFileTime
. But DateTime.Now
first calls DateTime.UtcNow
and then gets the local time zone and applies it to that time.
Regarding the dynamic DST info that you originally asked about, I believe that it would be sufficient to call GetTimeZoneInformation
, because Windows should be copying the dynamic DST rule that applies to the current date and time into the non-dynamic values in the registry. But like I said, it's better to just get the UTC time directly.
I'm surprised there is no Delphi function for getting the UTC time directly. It must be an artifact of the ages, since many things were done locally in the time when Delphi was widely used.
A few Delphi functions:
function NowUTC: TDateTime;
var
st: TSystemTime;
begin
GetSystemTime(st);
result := EncodeDateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
end;
function CurrentUnixUTCTimestamp: int64;
begin
result := DateTimeToUnix(NowUTC);
end;