为什么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时区全局如何工作。
那么基本问题是:
- 为什么这两个输出不同
- 如何可靠地检测C程序的系统UTC偏移?
我认为“时区”不会随着日光时间而变化。 尝试“日光”变量。 在我的系统上:
外部变量时区包含差异,以秒为单位, 在UTC和当地标准时间之间(例如,在美国东部 时区(EST),时区为5 * 60 * 60)。 外部变量日光 只有在指定夏令时区调整时才为非零 TZ环境变量。
执行此操作后,请查看tm.tm_isdst字段:
time_t current_time; struct tm tm; current_time = time(NULL); localtime_r(¤t_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