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或者不是。我想设置它是完全错误的,但它会是实际上这样做是出于上述原因…)