GetTimeZoneInformation的返回值是否也适用于动态DST区域? [英] Is return value of GetTimeZoneInformation also valid for dynamic DST zones?
问题描述
以下我在Delphi中编写的函数(但是,我的问题并不特定于Delphi)确实会输出当前的UTC Unix时间戳:
function CurrentUnixTimeUTC:int64;
var
tzi:TTimeZoneInformation;
begin
//获取本地时间的当前unix时间戳。
结果:= DateTimeToUnix(Now);
//首先,添加DST特定偏差
情况下
的GetTimeZoneInformation(tzi)TIME_ZONE_ID_INVALID:
RaiseLastOSError;
TIME_ZONE_ID_UNKNOWN:
; //不知道该怎么办。我们只是不施加任何偏见。
TIME_ZONE_ID_STANDARD:
结果:=结果+ tzi.StandardBias * 60;
TIME_ZONE_ID_DAYLIGHT:
结果:=结果+ tzi.DaylightBias * 60;
结尾;
//现在应用区域特定偏差
结果:=结果+ tzi.Bias * 60;
结尾;
该函数有效,并且在德国的输出与在加利福尼亚的输出相同。
在研究MSDN时,我还发现了 GetDynamicTimeZoneInformation
。
通过阅读MSDN(其中对成员 Bias btw的定义不完整),对我来说,是否简单地调用 GetTimeZoneInformation
足以让我的函数 CurrentUnixTimeUTC
也可以在具有动态DST设置(即DST日期每年更改)的区域中工作。换句话说, GetTimeZoneInformation
是否可以成功判断系统当前是否处于DST模式,或者我是否需要调用 GetDynamicTimeZoneInformation
相反,如果我想与应用了动态DST规则的时区的计算机兼容?
如果您只是想从Win32 API获取当前UTC时间,则不应该涉及时区。操作系统将自动处理。直接使用 GetSystemTime
或 GetSystemTimeAsFileTime
。
例如,在.NET中, DateTime.UtcNow
只是调用 GetSystemTimeAsFileTime
。但是 DateTime.Now
首先调用 DateTime.UtcNow
,然后获取本地时区并将其应用于该时间。 / p>
关于您最初询问的动态DST信息,我相信只要调用 GetTimeZoneInformation
就足够了Windows应该将适用于当前日期和时间的动态DST规则复制到注册表中的非动态值中。但是,就像我说的那样,最好直接获取UTC时间。
我很惊讶没有直接使用UTC时间的Delphi功能。它必须是时代的产物,因为许多事情都是在广泛使用Delphi的时候在本地完成的。
一些Delphi函数:
函数NowUTC:TDateTime;
var
st:TSystemTime;
开始
GetSystemTime(st);
结果:= EncodeDateTime(st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
结尾;
函数CurrentUnixUTCTimestamp:int64;
开始
结果:= DateTimeToUnix(NowUTC);
结尾;
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;
这篇关于GetTimeZoneInformation的返回值是否也适用于动态DST区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!