如何解析 tzdata 数据库(由 IANA 或操作系统供应商发布(以获取历史时区信息?
例如,我想知道在特定时间点(如1435100000
(Asia/Tokyo
GMT的时间偏移量是多少,这实际上是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 = %ldn", tmp->tm_gmtoff);
}
不幸的是,该程序所依赖的tm_gmtoff
字段虽然非常有用,但是非标准的。 (在某些版本的Unix下,它可能被命名为_tm_gmtoff
。 在某些版本下,它可能根本不存在。 如果您没有可用的tm_gmtoff
,或者如果您需要代码尽可能可移植,则可以改用此技巧:
time_t t2;
tmp = gmtime(&t);
t2 = mktime(tmp);
printf("offset = %ldn", t - t2);
对于 Unix、Linux、MacOS 以及任何使用 IANA 代码和数据的平台,此类程序应针对自 1970 年 1 月 1 日以来的任何时区和任何时间提供正确的结果。
对于 1970 年 1 月 1 日之前的时间,普通的 IANA 数据并不全面,因此如果您需要使用较旧的日期和时间,则可能需要执行其他操作。 (IANA 数据确实涵盖了 1970 年之前的时区规则,但它并不那么全面,也没有声称是确定的。
据我了解,Windows 下的日期和时间代码不保留历史时区信息,并且始终使用任何历史日期的当年规则,因此在 Windows 下您可能需要编写自己的代码,或者获取并编译 IANA 代码。 (但您仍然不需要手动解析任何数据文件。