【问题标题】:Why does glibc "timezone" global not agree with system time on DST?为什么 glibc "timezone" global 与 DST 上的系统时间不一致?
【发布时间】:2010-10-12 18:08:06
【问题描述】:

我遇到了一个奇怪的问题,我的系统时钟知道这是夏令时,但 glibc 似乎不知道。这是一个最新的 Ubuntu 安装,我检查了 /etc/localtime,它有正确的转换时间,适合上周切换到 DST。

我当前正确的时区是太平洋夏令时间 (UTC-7)。当我询问我的系统我在哪个时区时,它会正确地告诉我:

$ date +%z
-0700

但是当我运行以下程序时:

#include <time.h>
#include <stdio.h>

int main() {
  tzset();
  printf("%lu\n", timezone);
  return 0;
}

输出错误:

28800

对应于 UTC-8 或太平洋标准时间。 (不,我的环境中没有设置 TZ)

我认为 glibc 和 date 程序会从同一个来源获取他们的时区信息,但显然要么他们没有,要么我误解了 glibc 全局时区的工作原理。

那么基本问题是:

  1. 为什么这两个输出不同
  2. 如何可靠地检测来自 C 程序的系统 UTC 偏移量?

【问题讨论】:

    标签: c timezone glibc


    【解决方案1】:

    我不认为“时区”会随着日光时间而变化。尝试“日光”变量。在我的系统上:

    外部变量 timezone 包含差异,以秒为单位, 在 UTC 和当地标准时间之间(例如,在美国东部 时区(EST),时区为 5*60*60)。外部变量日光 仅当在 TZ 环境变量。

    【讨论】:

    • 我对 tzset 手册页的阅读表明,dayllight 变量仅表明本地区域是否在某个时候使用夏令时,并不一定表明它当前是否有效。
    • 我想我同意你的看法。我建议 { time_t t = time(NULL); printf("%d\n",(int)difftime(mktime(gmtime(&t)),t)); } 但这给了我与“时区”相同的结果。
    【解决方案2】:

    执行此操作后查看 tm.tm_isdst 字段:

      time_t current_time;
      struct tm tm;
    
      current_time = time(NULL);
      localtime_r(&current_time, &tm);
    

    根据 localtime_r(3) 联机帮助页,这确实表明 DST 在指定时间是否有效。我认为您需要假设 DST 为您已经使用的 timezone(3) 变量增加了一小时,或者针对 GMT 执行差异技巧。

    在澳大利亚 AEST 对我有用,希望对你有用。

    【讨论】:

      【解决方案3】:

      您可以使用 struct tm 的tm_gmtoff 成员,它与 ::timezone 相同,但它考虑 DST 并且符号相反。

      http://www.gnu.org/s/libc/manual/html_node/Time-Zone-Functions.html#Time-Zone-Functions

      【讨论】:

      • 标准struct tm中没有tm_gmtoff
      【解决方案4】:

      如果定义了 linux,这是我使用 tm_gmtoff 的代码,否则使用 gettimofday 中的 timezone.tz_minuteswest(这里的 'ltm' 是本地时间的输出):

      {
          int tz_offset;
      
      #if defined(__linux__)
          tz_offset= ltm.tm_gmtoff;
      #else
          tz_offset= -tz.tz_minuteswest*60 + ltm.tm_isdst*3600;
      #endif
      
           printf ("LT = UTC +d sec\n", tz_offset);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        • 2020-10-02
        • 2017-01-31
        • 2011-06-11
        • 2020-03-09
        • 1970-01-01
        相关资源
        最近更新 更多