为什么glibc“timezone”全球不同意DST的系统时间?

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

对我来说,目前正确的时区是太平洋夏令时(UTC-7)。 当我问我的系统我在哪个时区时,它正确告诉我:

$ date +%z -0700 

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

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

输出是错误的:

 28800 

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

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

那么基本问题是:

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

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

      外部变量时区包含差异,以秒为单位,
      在UTC和当地标准时间之间(例如,在美国东部
      时区(EST),时区为5 * 60 * 60)。 外部变量日光
      只有在指定夏令时区调整时才为非零
       TZ环境变量。

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

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

根据localtime_r(3)联机帮助页,这实际上表明DST是否在指定的时间生效。 我想你需要假设DST为你已经使用的时区(3)变量增加了一个小时,或者对GMT进行差异化处理。

在澳大利亚AEST为我工作,希望它适合你。

这是我的代码,如果定义了linux,则使用tm_gmtoff,并使用来自gettimofday的timezone.tz_minuteswest(这里’ltm’是localtime的输出):

 { 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); } 

您可以使用与时区相同的结构tm的tm_gmtoff内存,但它会考虑DST并且符号反转。

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