如何获得其他时区的夏令时状态
假设我的Windows服务器应用程序在东部时区(纽约)运行。
我使用UTC转换和存储每个日期时间事件(发生时刻),以便任何连接到服务器的客户端应用程序都可以读取事件的UTC时间并将其转换并显示在客户端自己的TZ中。
但是这里有一个棘手的部分,一些事件在另一个州的时间报告它们的时间戳,并没有明确指定夏令时信息(例如xx:xx:xx AM PT,意思是太平洋时间,但我不知道它目前是否在夏令时)。
服务器可以检查它是否在夏令时期,但这是服务器自己的TZ(东部时间)。 我能想到的最好的办法是读取服务器的本地夏令时信息并将其用于PT,但我知道这并非100%准确。 特别是当ET刚刚开始(或停止)使用夏令时时,短时间窗口仍然有几个小时。
现在我的问题是,是否有一种方法(在Windows API中)能够准确找出另一个时区的夏令时状态,无论服务器应用程序驻留在哪个时区?
编辑:好的,我该如何将它转换为UTC“Sun,Mar 13,2016 1:15 AM PT”,来自东部时间运行的Windows机器? (请注意,这个日期/时间特别选择当运行的机器(ET)在DST的时刻和日期/时间转换不只是在DST。我有UTC转换覆盖,但无法弄清楚是否给定的日期/时间是否在DST中。
Windows的时区数据实际上存储在注册表中:
HKLM
SOFTWARE
Microsoft
Windows NT
CurrentVersion
Time Zones
实际上,“时区”就是两个字。
每个时区都有自己的子项,每个子项都有一个TZI
值,它是一个二进制REG_TZI_FORMAT
结构:
typedef struct _REG_TZI_FORMAT
{
LONG Bias;
LONG StandardBias;
LONG DaylightBias;
SYSTEMTIME StandardDate;
SYSTEMTIME DaylightDate;
} REG_TZI_FORMAT;
这两个相关的结构成员是StandardDate
和DaylightDate
。
有关更多详细信息,请参阅MSDN:TIME_ZONE_INFORMATION
我不确定Windows API,但总的来说,你想要做的就是调用mktime
,使用你的远程时间的TZ值。 在Unix下,你可以从字面上调用setenv("TZ", whatever)
来做到这一点。 不确定Windows,但我认为你也可以在那里做同样的事情。
如果除了mktime
和timegm
之外还有一个变体可以让你明确指定区域(而不是将TZ环境变量作为全局变量),但是这样的变体不是标准的。
在不知道DST是否生效的情况下转换本地时间时,请记住将tm_isdst
设置为-1,以便库将为您解决问题。
这是一个例子:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
struct tm tm = {0};
time_t t;
tm.tm_hour = 12; tm.tm_min = 30, tm.tm_sec = 15; /* 12:30:15 */
tm.tm_year = 2005-1900; tm.tm_mon = 4-1; tm.tm_mday = 12; /* 2005-04-12 */
tm.tm_isdst = -1;
setenv("TZ", "America/Los_Angeles", 1);
t = mktime(&tm);
setenv("TZ", "America/New_York", 1);
printf("%ld = %.24sn", t, ctime(&t));
}
这告诉你洛杉矶时间12:30:15对应于Unix(UTC)时间1113334215和纽约时间15:30:15。
附录:这对Windows也没有帮助,但是如果您不想在程序中设置环境变量,那么每次需要在不同时区使用时间时,请参阅是否可以使用BSD函数tzalloc
, localtime_rz
和mktime_z
。
上一篇: How to get daylight saving status of another time zone
下一篇: WeBid: Timezones with daylight savings time not calculated correctly