为啥 glibc "timezone" global 与 DST 上的系统时间不一致?
Posted
技术标签:
【中文标题】为啥 glibc "timezone" global 与 DST 上的系统时间不一致?【英文标题】: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 全局时区的工作原理。
那么基本问题是:
-
为什么这两个输出不同
如何可靠地检测来自 C 程序的系统 UTC 偏移量?
【问题讨论】:
【参考方案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(¤t_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);
【讨论】:
以上是关于为啥 glibc "timezone" global 与 DST 上的系统时间不一致?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 "map! <C-q> :q <CR> " 在 vim 中不起作用?
为啥我在php中用date()函数获取的时间老师与我电脑上显示的差8小时?
为啥 python datetime replace timezone 返回不同的时区?
为啥使用Hibernate开发web项目的时候在servlet头上使用@webServlet(name="index",urlPatterns="/index&q