【问题标题】:Interpretation of tm_isdst field in struct tmstruct tm中tm_isdst字段的解释
【发布时间】:2016-07-02 02:26:09
【问题描述】:

时间结构 (struct tm) 包含分解成其组件的日历日期和时间。该结构包含九个 int 类型的成员(按任意顺序),它们是:

Member  Type    Meaning Range
tm_sec  int seconds after the minute    0-61*
tm_min  int minutes after the hour  0-59
tm_hour int hours since midnight    0-23
tm_mday int day of the month    1-31
tm_mon  int months since January    0-11
tm_year int years since 1900    
tm_wday int days since Sunday   0-6
tm_yday int days since January 1    0-365
tm_isdst    int Daylight Saving Time flag

如果夏令时有效,夏令时标志 (tm_isdst) 大于零,如果夏令时无效,则为零,如果信息不可用,则小于零。

我与 tm_isdst 相关的具体问题如下:

  1. 对于日期(YYYY-MM-DD)2016-03-16(当 DST 生效时),应该 tm_isdst 为 1?还是 0?

  2. 对于日期(YYYY-MM-DD)2016-01-16(DST 无效时), tm_isdst 应该为 1 吗?还是 0?

  3. 2016 年夏令时(美国)从 2:00 AM 开始 3 月 13 日,星期日。所以在 3 月 13 日凌晨 1 点 45 分,什么是价值 tm_isdst?谁设置了这个 flag 的值以及如何设置?

  4. 有什么方法可以检查 DST 何时生效 系统调用?

【问题讨论】:

    标签: c date


    【解决方案1】:

    关键问题是struct tm 代表一个时间戳,其字段限制为 24 小时、12 个月 60 分钟等。DST 字段不必匹配什么时钟在该时区用于该日期。当然,对于许多应用程序,设置为不常见的值需要纠正。

    对于本地时间戳,简单设置所有字段(tm_ydaytm_wday 除外)并调用mktime()。它将所有字段调整到通常范围,包括将tm_isdst设置为0或1。


    1. 对于日期(YYYY-MM-DD)2016-03-16(当 DST 生效时),tm_isdst 是否应该为 1?还是 0?

      // set to 1 to indicate DST
      tm.tm_isdst = 1;
      
    2. 对于日期(YYYY-MM-DD)2016-01-16(DST 无效时),tm_isdst 是否应该为 1?还是 0?

      // set to 0 to indicate standard time
      tm.tm_isdst = 0;
      
    3. 2016 年夏令时(美国)于 3 月 13 日星期日凌晨 2:00 开始。所以在 3 月 13 日凌晨 1:45 时,tm_isdst 的值是多少?谁设置了这个标志值以及如何设置?

      如果不确定 DST 设置,请使用 tm.tm_isdst = -1; 致电 mktime()。如果代码知道struct tm 是标准时间,请将tm_isdst 字段设置为0。它没有区别是一年中的什么时间。与 DST 类似,如果代码知道它是 DST 时间戳,则将该字段设置为 1。调用 mktime() 会将字段调整为本地时区的通常设置。

      当然,凌晨 1:45(tm_isdst < 0)可以任意解释,mktime() 通常会选择 0 或 1。

      // set to 1 to indicate DST
      // set to 0 to indicate standard time
      // set to -1 to indicate DST is not known
      tm.tm_isdst = -1;
      mktime(&tm);  // This will adjust all the fields including tm_isdst
      
    4. 有什么方法可以通过某些系统调用检查 DST 何时生效?

      是的。要确定 struct tm 是否应将 tm_isdst 设为 0 或 1,请调用 mktime()

      mktime(&tm);  // This will adjust the fields including tm_isdst
      printf("%d\n", tm.tm_isdst);
      

    顺便说一句:健壮的代码检查mktime()的返回值

    if (mktime(&tm) == -1) puts("Oops");
    

    【讨论】:

      【解决方案2】:
      1. 应该是1(或正值),因为正如您所说,夏令时生效。

      2. 应该是0,因为正如你所说,夏令时没有生效。

      3. 应该是0,因为当时没有夏令时。

      4. 您可以使用localtime() 在给定时间填充struct tm,然后检查该标志的值。这就是它存在的主要原因。

      【讨论】:

        猜你喜欢
        • 2018-02-25
        • 1970-01-01
        • 2011-06-30
        • 2017-09-26
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多