在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的问题......
答案 0 :(得分:7)
请参阅以下文档:
localtime()函数将日历时间timep转换为 分解时间表示,相对于用户表示 指定的时区。该函数就像调用tzset(3)和 使用有关当前的信息设置外部变量tzname 时区,时区与Coordinated Universal的区别 时间(UTC)和本地标准时间(以秒为单位)和日光到a 如果夏令时规则适用于某些部分,则非零值 那一年。返回值指向静态分配的结构 可能会被后续调用任何日期和 时间功能。 localtime_r()函数执行相同操作,但存储 用户提供的结构中的数据。它不需要设置tzname,timezone, 和日光。
来自:http://linux.die.net/man/3/localtime_r
据我所知,似乎代码正如我所期望的那样工作。
编辑以从同一文档中添加更多内容:
根据POSIX.1-2004,localtime()需要表现得像 调用tzset(3),而localtime_r()没有这个 需求。对于可移植代码,应该先调用tzset(3) 则localtime_r()。