GetTimeZoneInformation的返回值是否也适用于动态DST区域? [英] Is return value of GetTimeZoneInformation also valid for dynamic DST zones?

查看:108
本文介绍了GetTimeZoneInformation的返回值是否也适用于动态DST区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆