首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在localtime()与localtime_r()中实时感知时区更改

在localtime()与localtime_r()中实时感知时区更改
EN

Stack Overflow用户
提问于 2013-10-04 07:20:12
回答 1查看 10.3K关注 0票数 10

在Ubuntu12.04.3LTS机器上工作时,我刚刚注意到当系统的时区在进程的生命周期内发生变化时,localtime()和localtime_r()的行为是不同的: localtime()会立即获取时区的变化,而localtime_r()不会,它似乎会坚持进程启动时的时区。这是预期的行为吗?我还没见过这方面的报道。

更准确地说,当我使用以下代码时...

代码语言:javascript
复制
#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的时区...

代码语言:javascript
复制
# echo 'Europe/Berlin' > /etc/timezone 
# sudo dpkg-reconfigure --frontend noninteractive tzdata

..。然后,代码会生成以下代码...

代码语言:javascript
复制
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

..。但是如果我使用:

代码语言:javascript
复制
#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;
}

..。然后,在执行类似的时区更改时不会有任何更改:

代码语言:javascript
复制
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的一个问题……

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-04 07:29:22

请参阅以下文档:

函数的作用是:将日历时间timep转换为分解的时间表示形式,它是相对于用户指定的时区表示的。该函数的作用类似于它调用tzset(3),并使用有关当前时区的信息设置外部变量tzname,使用协调世界时(UTC)和本地标准时间(以秒为单位)之间的时差设置时区,如果夏令时规则在一年中的某个部分应用,则将夏令时设置为非零值。返回值指向一个静态分配的结构,该结构可能会被对任何日期和时间函数的后续调用所覆盖。localtime_r()函数做同样的事情,但将数据存储在用户提供的结构中。它不需要设置tzname、时区和日光。

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

因此,据我所知,代码看起来像我预期的那样工作。

编辑后可从同一文档中添加更多内容:

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

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19170721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档