【发布时间】:2015-11-10 14:11:00
【问题描述】:
我正在检测夏令时(夏令时)转换。 我遇到了一些我不明白的事情,希望得到一些解释。
我已将我的代码精简到几乎是最低限度以显示问题。
int main(void)
{
struct tm tm1,tm2;
time_t time1, time2;
int order=0;//change this betwee 0 and 1
tm1.tm_hour=2;
if (order)
{
tm1.tm_hour=1;
}
tm1.tm_min=0;
tm1.tm_sec=0;
tm1.tm_mday=1;
tm1.tm_mon=10;
tm1.tm_year=115;
tm1.tm_isdst=-1;
time1=mktime(&tm1);
//insert here
tm2.tm_hour=1;
if (order)
{
tm2.tm_hour=2;
}
tm2.tm_min=0;
tm2.tm_sec=0;
tm2.tm_mday=1;
tm2.tm_mon=10;
tm2.tm_year=115;
tm2.tm_isdst=-1;
time2=mktime(&tm2);
printf("\n\n time stamp 1=%zu time stamp 2=%zu difference=%zi\n\n",time1 ,time2, time2-time1);
exit(0);
}
order = 0 时的输出为:
time stamp 1=1446368400 time stamp 2=1446364800 difference=-3600
order = 1 时的输出为:
time stamp 1=1446361200 time stamp 2=1446368400 difference=7200
(注意这是夏令时结束的时间,2015 年 11 月 1 日 01:59:59 后一秒,将是 01:00:00。)
简单地说,当hour = 2 时结构的转换取决于紧接在它之前发生的转换。一点钟可以(正确地)是 1446364800(标准时间)或 1446361200(DST)。如果发现之前的转换为 DST,则使用第二选择,反之亦然。显而易见的解决方案是 mktime 设置一些变量,以便下次使用。但是我找不到它的任何记录。 mktime 确实设置了三个(四个?)外部变量,tzname[0]、tzname[1]、时区和日光,但这些似乎并没有导致效果。 (我做了一个更复杂的测试程序版本来测试。)
我的时区是美国/埃德蒙顿 (MST(UTC-7)/MDT(UTC-6))
$ gcc --version<br>
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Kubuntu 14.04 LTS
任何见解或指示将不胜感激。
编辑: 回复 cmets: 1) 乔纳森——glibc 2.19 版 2) chux -- 在 mktime() 之后打印 tmX.tm_isdst、tmX.tm_hour 的值并没有给我任何见解。 (那是因为我是盲人吗?) one O'clock 转换显示一小时一小时和 is_dst 为 0 或 1,与时间戳推断完全一致。两点钟的转换当然显示一个小时为 2,is_dst 为 0。
回复 chux 的(?)回答:我想知道我是否还没有完全解释自己。 我意识到发生了什么:存在歧义,它必须“猜测”。我想知道的是为什么(以及如何)它的猜测取决于之前的转换?
第二次编辑:
为了确认 Wumpus Q. Wumbley 的回答在上面代码中指示的位置插入了以下代码:
tm0.tm_hour=0;
tm0.tm_min=0;
tm0.tm_sec=0;
tm0.tm_mday=1;
tm0.tm_mon=10;
tm0.tm_year=115;
tm0.tm_isdst=-1;
time0=mktime(&tm0);
(基本上是一次性转换)我现在有两个小时的差异,无论顺序如何,我都得到了 DST 版本。
谢谢你的解释。
【问题讨论】:
-
观察:C 库 (glibc?) 的版本可能比 GCC 的版本更相关。然而,这是一个挑剔。有趣的问题。
-
建议在
mktime()之后 打印tmX.tm_isdst, tmX.tm_hour的值,以便更深入地了解问题。 -
问题不是跨平台的。在 Mac OS X 10.10.5 上,我得到:
time stamp 1=1446361200 time stamp 2=1446368400 difference=7200和time stamp 1=1446368400 time stamp 2=1446361200 difference=-7200,这是自洽的(并且与您看到的不同)。 -
OTOH,我可以在旧版 Linux 上重现该问题(Linux 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64)。我得到了:
time stamp 1=1446368400 time stamp 2=1446364800 difference=-3600和time stamp 1=1446361200 time stamp 2=1446368400 difference=7200。 -
“我想知道的是为什么(以及如何)它的猜测取决于之前的转换?” @Wumpus Q. Wumbley 很好地回答了这篇关于 gcc/Linux 的帖子——这是被问到的。我的回答集中在 C 规范上,该规范对此问题保持沉默,从而允许编译器之间的各种行为。最好为您感兴趣的编译器定义。然而,其他编译器的可移植解决方案不应该依赖于这种行为。建议在此帖子标签中包含
[gcc]