在C中解析tzdata数据库的工具

时间:2018-08-24 10:29:34

标签: c timezone tzdata

如何解析tzdata数据库(由IANA或操作系统供应商发布)以获取历史时区信息?

例如,我想知道在1435100000之类的特定时间点,2015-04-25T22:13:20+00:00 (UTC)中与格林尼治标准时间的偏移量是多少,而实际上是{{1}}

1 个答案:

答案 0 :(得分:2)

您通常不需要自己解析数据文件即可回答此类问题。

在大多数Unix和Linux版本中,该程序将为您提供所需的时间偏移:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    time_t t = 1435100000;
    struct tm *tmp;
    setenv("TZ", "Asia/Tokyo", 1);
    tzset();
    tmp = localtime(&t);
    printf("offset = %ld\n", tmp->tm_gmtoff);
}

不幸的是,此程序所依赖的tm_gmtoff字段尽管非常有用,但却是非标准的。 (在Unix的某些版本中,其名称可能为_tm_gmtoff。在某些版本中,它可能根本不存在。)如果没有tm_gmtoff可用,或者您需要代码具有可移植性尽可能,您可以改用以下技巧:

time_t t2;
tmp = gmtime(&t);
t2 = mktime(tmp);
printf("offset = %ld\n", t - t2);

对于Unix,Linux,MacOS以及使用IANA代码和数据的任何平台,此类程序应在1970年1月1日以来的任何时区和任何时间给出正确的结果。

对于1970年1月1日之前的时间,普通的IANA数据并不全面,因此,如果您需要处理较旧的日期和时间,则可能需要做一些不同的事情。 (IANA数据确实涵盖了1970年之前的时区规则,但并不全面,也没有权威性。)

据我了解,Windows下的日期和时间代码不保留历史时区信息,并且对于任何历史日期始终使用当前年份的规则,因此在Windows下,您可能需要编写自己的代码,或者获取和编译IANA代码。 (但是您仍然不需要手动解析任何数据文件。)