我在这里想到了很多不同的观点。
我看了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
保留为{{1}}让系统决定它是否为dst,以及代码是否与dst无关?
我错过了什么吗?
答案 0 :(得分:10)
如果可能,您应该避免将tm_isdst设置为-1。系统无法始终仅从日期和时间确定DST状态。在夏令时结束之前和之后的一小时,这是模棱两可的。例如,如果您在2012年11月4日凌晨1:30之前通过了mktime()
,则该信息不足以从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()
修改,以将所有结构成员返回到标称范围。例如,如果增加tm_hour成员+= 500
,则意味着将时间增加500小时。 tm_hour
成员将更改为值00到23,tm_day
,tm_mday
等将全部相应调整。 tm_isdst
也是输入和输出。其价值如下:
因此mktime()将为tm_isdst输出1或0,从不输出-1。
-1是一个可能的输入,但我认为它意味着“未知”。不要将其视为“自动确定”,因为通常mktime()
不能自动确定它。
显式DST状态(0或1)应来自软件外部的某些内容,例如将其存储在文件或数据库中,或提示用户。
答案 1 :(得分:4)
我认为最初的原因是某些时区没有夏令时。由于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。对于所有实现,没有一种默认的正确方法。
答案 2 :(得分:0)
我认为您确实应该在-1
字段中使用tm_isdst
,除非您掌握有关处理时间类型的信息。
例如,在加利福尼亚州,我们仍然有PST和PDT。如果要解析日期,并且存在时区信息,则应相应设置tm_isdst
。正如吉姆·麦克纳马拉(Jim McNamara)所述,在调用tzname[]
之后,这些名称在tzset()
数组中可用。
例如,以下C ++代码编写PST/PDT
:
int main(int argc, char * argv [])
{
tzset();
std::cerr << tzname[0] << "/" << tzname[1] << "\n";
return 0;
}
tzname[]
数组中的偏移量对应于tm_isdst
的值。 (PST-太平洋标准时间tm_isdst = 0
,以及PDT,太平洋夏令时间tm_isdst = 1
。)
如果输入中没有时区信息,则使用-1
是最佳选择。当日期对应于发生更改的日期和时间时,您只会遇到问题。正如Rich Jahn所解释的那样,在2012年11月4日,他在标准时间和夏令时之间进行了更改,并且在该时间前后,gmtime()
必须做出选择,这与您期望的相反。话虽这么说,一年中和半夜总共只发生2个小时。因此,除非您使用的是日期非常重要的关键类型的软件,否则可能不会有太大关系。
所以,作为回顾:
tm_isdst
的值(也就是说,我不太确定如何处理该情况)支持所有时区... tzname[]
数组仅为您提供用户的当前时区。)-1