如何解析tzdata数据库(由 IANA 或操作系统供应商发布)以获取历史时区信息?
例如,我想知道Asia/Tokyo
在特定时间点与 GMT 的时间偏移量是多少1435100000
,实际上是2015-04-25T22:13:20+00:00 (UTC)
您通常不需要自己解析数据文件来回答这类问题。
在大多数 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代码。(但您仍然不需要手动解析任何数据文件。)