实时了解localtime()和localtime_r()的时区变化

Ubuntu 12.04.3 LTS框中,我只注意到localtime()和localtime_r()在进程生命周期中系统时区变化时的行为不同:localtime()立即获取时区变化​​,而localtime_r不是,似乎坚持在这个过程启动的时区。 这是预期的行为? 我没有看到这覆盖任何地方。

更确切地说,当我使用下面的代码…

#include <stdio.h> #include <sys/time.h> #include <time.h> #include <unistd.h> int main() { while (1) { time_t t = time(NULL); struct tm *tm = localtime(&t); printf("localtime:%02d/%02d/%02d-%02d:%02d:%02d\n", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); sleep(1); } return 0; } 

…并从UTC更改时区通过…

 # echo 'Europe/Berlin' > /etc/timezone # sudo dpkg-reconfigure --frontend noninteractive tzdata 

然后代码产生以下,…

 localtime:10/04/2013-01:11:33 localtime:10/04/2013-01:11:34 localtime:10/04/2013-01:11:35 localtime:10/03/2013-23:11:36 localtime:10/03/2013-23:11:37 localtime:10/03/2013-23:11:38 

…但是如果我使用:

 #include <stdio.h> #include <sys/time.h> #include <time.h> #include <unistd.h> int main() { while (1) { time_t t = time(NULL); struct tm local_tm; struct tm *tm = localtime_r(&t, &local_tm); printf("localtime_r:%02d/%02d/%02d-%02d:%02d:%02d\n", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); sleep(1); } return 0; } 

…做类似的时区更改时没有改变:

 localtime_r:10/04/2013-01:15:37 localtime_r:10/04/2013-01:15:38 localtime_r:10/04/2013-01:15:39 localtime_r:10/04/2013-01:15:40 localtime_r:10/04/2013-01:15:41 localtime_r:10/04/2013-01:15:42 

更新:调用localtime_r()之前添加一个调用tzset()产生预期的行为。 无论从规范/手册页中是否清楚(见下面的讨论)是mentalhealth.stackexchange.com的一个问题…

请参阅以下文档:

localtime()函数将日历时间timep转换为相对于用户指定的时区表示的细分时间表示。 该函数的作用就像调用tzset(3)一样,并将外部变量tzname设置为关于当前时区,时区的信息,以协调世界时(UTC)和本地标准时间之差(以秒为单位),以及如果日光以白天为非零值储蓄时间规则适用于一年的某个时间段。 返回值指向一个静态分配的结构,可能会被随后调用任何日期和时间函数覆盖。 localtime_r()函数的作用相同,但将数据存储在用户提供的结构中。 它不需要设置tzname,时区和日光。

来自: http : //linux.die.net/man/3/localtime_r

所以据我所知,代码似乎正在按我的预期工作。

从相同的文档编辑添加更多:

根据POSIX.1-2004,localtime()需要像调用tzset(3)那样工作,而localtime_r()则没有这个要求。 对于便携式代码tzset(3)应该在localtime_r()之前调用。