首页 文章

如何获得另一个时区的夏令时状态

提问于
浏览
2

假设我的Windows服务器应用程序在东部时区(NY)运行 .

我以UTC格式转换并存储每个日期时间事件(它们发生的那一刻),以便连接到服务器的任何客户端应用程序读取事件的UTC时间并转换并在客户端自己的TZ中显示它 .

但这里是棘手的部分,有些事件在另一个州的时间报告他们的时间戳,并没有明确指定夏令时信息(例如xx:xx:xx AM PT,意思是太平洋时间,但我不知道它目前是否在夏令时) .

服务器可以检查它是否在夏令时期间,但这将是服务器自己的TZ(这是东部时间) . 我能想到的最好的方法是阅读服务器的本地夏令时信息并将其用于PT,但我知道这不是100%准确 . 当ET刚刚开始(或停止)使用夏令时,特别是通过短窗口,PT还有几个小时的时间 .

现在我的问题是,有没有办法(在Windows API中)准确地找出另一个时区的夏令时状态,无论服务器应用程序驻留在哪个时区?

Edit: 好的,如何从东部时间运行的Windows机器将其转换为UTC "Sun, Mar 13, 2016 1:15 AM PT"? (请注意,当正在运行的机器(在ET中)当前处于夏令时的时间和转换的日期/时间时,特别选择的日期/时间不仅仅是在夏令时 . 我已经涵盖了UTC转换但是无法弄清楚给定的日期/时间是否为夏令时 .

2 回答

  • 1

    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;
    

    两个相关的结构成员是 StandardDateDaylightDate .

    有关更多详细信息,请参阅MSDN:TIME_ZONE_INFORMATION

  • 2

    我不确定Windows API,但一般来说,你要做的是调用 mktime ,你的远程时间的TZ值有效 . 在Unix下,您可以直接调用 setenv("TZ", whatever) 来执行此操作 . 不确定Windows,但我认为你也可以在那里做同样的事情 .

    如果除了 mktimetimegm 之外,还有一个变体允许您指定要明确使用的区域(而不是将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 = %.24s\n", t, ctime(&t));
    }
    

    这告诉你洛杉矶时间12:30:15对应于Unix(UTC)时间1113334215和纽约时间15:30:15 .


    附录:每次需要处理不同时区的时间时,这就像在程序内设置环境变量一样,看看是否可以使用BSD函数 tzalloclocaltime_rzmktime_z .

相关问题