time.h中的tzset和daylight全局变量解释

在daylight全局变量的time.h标题中,它说:“如果夏令时规则适用,则此变量具有非零值。非零值并不一定意味着夏令时现在有效;它仅表示夏令时时间有时是有效的。“

现在我注意到,在Solaris 11.2和Linux中,“daylight”变量被设置为1,即使我的时区根本不使用夏令时(澳大利亚/布里斯class)。

示例代码确认了这一点,如果我运行tzset并输出我们得到的全局变量:daylight = 1 tz [0] = [AEST] tz [1] = [AEDT] timezone = [-36000]

但根据我的理解,日光应该设置为0,因为我的区域在一年中的任何时候都没有夏令时。

我还注意到,当设置为当前时间时,struct tm返回tm_isdst = 0,这是正确的。

那么为什么daylight变量设置为1? 它不应该设置为0吗? 还是我误解了这个?

代码是:

#include  #include  void main() { time_t t; struct tm *tms = { 0 }; tzset(); time(&t); tms = localtime(&t); printf("date and time : %s",ctime(&t)); printf("daylight = %d tz[0] = [%s] tz[1] = [%s] timezone = [%ld]\n", daylight, tzname[0], tzname[1], timezone); printf("tm_isdst = %d\n",tms->tm_isdst); } 

输出是:

 date and time : Mon Nov 30 16:41:01 2015 daylight = 1 tz[0] = [AEST] tz[1] = [AEDT] timezone = [-36000] tm_isdst = 0 

关于C标准tm_isdst成员。

如果夏令时生效,则tm_isdst值为正,如果夏令时不生效,则为零;如果信息不可用,则为负。 C11dr§7.27.14

这与* nix规范略有不同,关于* nix全局变量daylight
daylight不是标准C的一部分。


gnu.org报道

变量:int日光
如果应用夏令时规则,则此变量具有非零值。 非零值并不一定意味着夏令时现已生效; 这仅表示夏令时有时会生效。


tm_isdst引用struct tm时间戳。 它只表示DST对该时间戳有效。

daylight != 0表示有时在时区的时间戳中使用DST。

由于澳大利亚/布里斯class曾经观察到DST事先( @Jon Skeet )到1972年, daylight == 1是合理的,因为daylight意味着DST在该时区的某些时段有效(可能是自1970年以来)。

OP的“……即使我的时区根本不使用夏令时”也是不正确的。


以下代码显示自1970年以来“澳大利亚/布里斯class”使用DST(至少时区DB认为如此)。

 #include #include #include int main(void) { setenv("TZ", "Australia/Brisbane", 1); tzset(); time_t now; time(&now); struct tm tm; int isdst = 42; // See Hitchhiker's_Guide_to_the_Galaxy time_t t; for (t = 0; t < now; t += 3600) { tm = *localtime(&t); if (tm.tm_isdst != isdst) { printf("dst:%d %s", tm.tm_isdst, ctime(&t)); isdst = tm.tm_isdst; } } printf("dst:%d %s", tm.tm_isdst, ctime(&t)); return 0; } 

产量

 dst:0 Thu Jan 1 10:00:00 1970 dst:1 Sun Oct 31 03:00:00 1971 dst:0 Sun Feb 27 02:00:00 1972 dst:1 Sun Oct 29 03:00:00 1989 dst:0 Sun Mar 4 02:00:00 1990 dst:1 Sun Oct 28 03:00:00 1990 dst:0 Sun Mar 3 02:00:00 1991 dst:1 Sun Oct 27 03:00:00 1991 dst:0 Sun Mar 1 02:00:00 1992 dst:0 Tue Dec 1 16:00:00 2015 

澳大利亚/布里斯class目前不使用夏令时,但过去一直没有; 看看australasia文件,你会看到它已经观察到DST的几年了。

我对daylight解释是,它表明该时区是否曾经观察过(或者将会遵守现行规则)夏令时。 换句话说,如果这是1,则在执行日期/时间处理时需要小心,而如果它为0,则可以假设一个恒定的UTC偏移。

(我不能立刻清楚一个从未观察过DST但是随着时间的推移已经改变了标准UTC偏移的时区,是否将daylight设置为1或者不是。我想设置它是完全错误的,但它会是实际上这样做是出于上述原因…)