c - 实时了解 localtime() 与 localtime_r() 中的时区变化

标签 c linux ubuntu time localtime

在 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 的问题...

最佳答案

请参阅以下文档:

The localtime() function converts the calendar time timep to broken-down time representation, expressed relative to the user's specified timezone. The function acts as if it called tzset(3) and sets the external variables tzname with information about the current timezone, timezone with the difference between Coordinated Universal Time (UTC) and local standard time in seconds, and daylight to a nonzero value if daylight savings time rules apply during some part of the year. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The localtime_r() function does the same, but stores the data in a user-supplied struct. It need not set tzname, timezone, and daylight.

发件人:http://linux.die.net/man/3/localtime_r

据我所知,代码似乎按我预期的方式工作。

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

According to POSIX.1-2004, localtime() is required to behave as though tzset(3) was called, while localtime_r() does not have this requirement. For portable code tzset(3) should be called before localtime_r().

关于c - 实时了解 localtime() 与 localtime_r() 中的时区变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19170721/

相关文章:

c - 如何提高以下循环的性能

linux - 在 Amazon Linux AMI 版本 2014.03 上安装 docker 1.2

linux - 如何在 Linux 中获取 QThread 的 PID?

c - 出于什么原因更改此行的位置会在变量中生成不同的赋值?

c++ - API 为 IP 返回 "incorrect"值,但如果您添加 256 或将负数输入 uchar,它就可以工作。发生了什么?

c - fork() 生成的子进程中的部分代码被跳过

c - Linux 是否允许将进程组 ID 重新分配给进程?

ubuntu - 我必须操作什么系统文件才能创建宏?

MySQL 阻塞(或者如何优化它)

amazon-web-services - 安装 SSl 后 AWS EC2 操作超时