我在这里想到了很多不同的看法。
我读 man mktime
:
(A positive or zero value for tm_isdst causes mktime() to presume initially
that summer time (for example, Daylight Saving Time) is or is not in
effect for the specified time, respectively. A negative value for
tm_isdst causes the mktime() function to attempt to divine whether summer
time is in effect for the specified time.
我的问题是,不应该 tm_isdst
保持为 -1
让系统决定它的dst是否与代码成为dst不可知?
我错过了什么吗?
我认为最初的原因是某些时区没有夏令时。由于mktime不是异步安全的,也不是可重入的,因此允许实现将夏令时的当前值存储在POSIX extern char tzname [2]中,由daylight [0或1]索引。这意味着tzname [0] =“[std TZ name]”和tzname =“[daylight TZ name,例如EDT]”
有关此内容的更多信息,请参见tzset()手册页。符合mktime()的标准要求表现得好像无论如何都要调用tzset()。这种情况避免了使用tm_isdst,IMO。
底线:您的特定实现和时区将决定是否对tm_isdst使用-1,0或1。对于所有实现,没有一种默认的正确方法。
如果可能,您应该避免将tm_isdst设置为-1。系统无法始终仅从日期和时间确定DST状态。在夏令时结束之前和之后的一小时,这是模棱两可的。例如,如果你通过 mktime()
2012年11月4日凌晨1:30,这还不足以让您获得正确的信息 time_t
来自的价值 mktime()
。通常我见过 mktime()
假设标准时间不明确,但我没有看到任何保证所有平台上的行为的文档。 2012年11月4日凌晨1:30 tm_isdst == 1
将是1小时前,因为小时1:00:00至1:59:59重复。
#include <stdio.h>
#include <time.h>
int main()
{
time_t daylight, standard;
struct tm timestr;
double diff;
timestr.tm_year = 2012 - 1900;
timestr.tm_mon = 11 - 1;
timestr.tm_mday = 4;
timestr.tm_hour = 1;
timestr.tm_min = 30;
timestr.tm_sec = 0;
/* first with standard time */
timestr.tm_isdst = 0;
standard = mktime(×tr);
/* now with daylight time */
timestr.tm_isdst = 1;
daylight = mktime(×tr);
diff = difftime(standard, daylight);
printf("Difference is %f hour(s)", diff/60.0/60.0);
return 0;
}
这会产生:
Difference is 1.000000 hour(s)
两者都是2012年11月4日凌晨1:30,但两者都是两个不同的time_t值,相隔1小时。
mktime()
基本上有2个输出:
时间结构既是输入又是输出。它被修改 mktime()
将所有struct成员返回到名义范围。例如,如果增加tm_hour成员 += 500
,这意味着将时间增加500小时。该 tm_hour
会员将更改为值00到59,并且 tm_day
, tm_mday
等都将相应调整。 tm_isdst
也是输入和输出。其价值如下:
- 1(DST有效,即白天时间)
- 0(DST无效,即标准时间)
- -1(未知的DST状态)
所以mktime()将为tm_isdst输出1或0,从不输出-1。
-1是可能的 输入,但我认为它意味着“未知”。不要将其视为“自动确定”的含义,因为一般来说, mktime()
不能总是自动确定它。
显式DST状态(0或1)应来自软件外部的某些内容,例如将其存储在文件或数据库中,或提示用户。
我认为最初的原因是某些时区没有夏令时。由于mktime不是异步安全的,也不是可重入的,因此允许实现将夏令时的当前值存储在POSIX extern char tzname [2]中,由daylight [0或1]索引。这意味着tzname [0] =“[std TZ name]”和tzname =“[daylight TZ name,例如EDT]”
有关此内容的更多信息,请参见tzset()手册页。符合mktime()的标准要求表现得好像无论如何都要调用tzset()。这种情况避免了使用tm_isdst,IMO。
底线:您的特定实现和时区将决定是否对tm_isdst使用-1,0或1。对于所有实现,没有一种默认的正确方法。
如果可能,您应该避免将tm_isdst设置为-1。系统无法始终仅从日期和时间确定DST状态。在夏令时结束之前和之后的一小时,这是模棱两可的。例如,如果你通过 mktime()
2012年11月4日凌晨1:30,这还不足以让您获得正确的信息 time_t
来自的价值 mktime()
。通常我见过 mktime()
假设标准时间不明确,但我没有看到任何保证所有平台上的行为的文档。 2012年11月4日凌晨1:30 tm_isdst == 1
将是1小时前,因为小时1:00:00至1:59:59重复。
#include <stdio.h>
#include <time.h>
int main()
{
time_t daylight, standard;
struct tm timestr;
double diff;
timestr.tm_year = 2012 - 1900;
timestr.tm_mon = 11 - 1;
timestr.tm_mday = 4;
timestr.tm_hour = 1;
timestr.tm_min = 30;
timestr.tm_sec = 0;
/* first with standard time */
timestr.tm_isdst = 0;
standard = mktime(×tr);
/* now with daylight time */
timestr.tm_isdst = 1;
daylight = mktime(×tr);
diff = difftime(standard, daylight);
printf("Difference is %f hour(s)", diff/60.0/60.0);
return 0;
}
这会产生:
Difference is 1.000000 hour(s)
两者都是2012年11月4日凌晨1:30,但两者都是两个不同的time_t值,相隔1小时。
mktime()
基本上有2个输出:
时间结构既是输入又是输出。它被修改 mktime()
将所有struct成员返回到名义范围。例如,如果增加tm_hour成员 += 500
,这意味着将时间增加500小时。该 tm_hour
会员将更改为值00到59,并且 tm_day
, tm_mday
等都将相应调整。 tm_isdst
也是输入和输出。其价值如下:
- 1(DST有效,即白天时间)
- 0(DST无效,即标准时间)
- -1(未知的DST状态)
所以mktime()将为tm_isdst输出1或0,从不输出-1。
-1是可能的 输入,但我认为它意味着“未知”。不要将其视为“自动确定”的含义,因为一般来说, mktime()
不能总是自动确定它。
显式DST状态(0或1)应来自软件外部的某些内容,例如将其存储在文件或数据库中,或提示用户。