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

And*_*w G 6 c timezone dst

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

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

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

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

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

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

代码是:

#include <stdio.h>
#include <time.h>
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);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

date and time : Mon Nov 30 16:41:01 2015
daylight = 1 tz[0] = [AEST] tz[1] = [AEDT] timezone = [-36000]
tm_isdst = 0
Run Code Online (Sandbox Code Playgroud)

chu*_*ica 6

关于C标准 tm_isdst会员.

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

这与*nix规范略有不同,关于*nix全局变量 daylight.
daylight不属于标准C.


gnu.org报道

变量:int daylight
如果应用夏令时规则,则此变量具有非零值.非零值并不一定意味着夏令时现在生效; 它仅表示夏令时有时生效.


tm_isdststruct tm时间戳.它只表示DST对该时间戳有效.

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

正如澳大利亚/布里斯班曾经观察到DST之前(@Jon Skeet)到1972年,具有daylight == 1合理意义,因为daylightDST在该时区的某些时段有效(可能自1970年以来).

OP的"......即使我的时区根本不使用夏令时"也是不正确的.


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

#include<time.h>
#include<stdlib.h>
#include<sys/time.h>

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;
}
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 3

澳大利亚/布里斯班目前不使用夏令时,但过去曾使用过;查看该australasia文件,您会看到它遵守 DST 的几年。

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

(我并不清楚一个从未遵守 DST 但随着时间的推移改变其标准 UTC 偏移量的时区是否会设置daylight为 1。我想设置它是完全错误的,但它是实用的出于上述原因这样做...)