[英]Odd behavior of mktime()
Continuing on my attempt to create a DateTime class , I am trying to store the "epoch" time in my function: 继续尝试创建DateTime类 ,我正在尝试在函数中存储“纪元”时间:
void DateTime::processComponents(int month, int day, int year,
int hour, int minute, int second) {
struct tm time;
time.tm_hour = hour;
time.tm_min = minute;
time.tm_sec = second;
time.tm_mday = day;
time.tm_mon = month;
time.tm_year = year - 1900;
ticks_ = mktime(&time);
processTm(time);
}
void DateTime::processTm(struct tm time) {
second_ = time.tm_sec;
minute_ = time.tm_min;
hour_ = time.tm_hour;
weekday_ = time.tm_wday;
monthday_ = time.tm_mday;
yearday_ = time.tm_yday;
month_ = time.tm_mon;
year_ = time.tm_year + 1900;
}
For an arbitrary date, processComponents(5,5,1990,1,23,45)
(June 6, 1990 1:23:45 am), it sets all values correctly and as expected. 对于任意日期,
processComponents(5,5,1990,1,23,45)
(1990年6月6日凌晨processComponents(5,5,1990,1,23,45)
),它将正确并按预期设置所有值。
However, upon further testing, I find that for processComponents(0,0,1970,0,0,0)
(January 1, 1970, 12:00:00 am), mktime(&time)
causes time
to be screwed up: 但是,在进一步测试中,我发现对于
processComponents(0,0,1970,0,0,0)
(1970年1月1日,上午12:00:00), mktime(&time)
导致time
:
time.tm_mon = 11;
time.tm_mday = 30;
time.tm_year = 69;
time.tm_hour = 23;
time.tm_min = 0;
time.tm_sec = 0;
time.tm_isdst = 0;
time.tm_gmtoff = -18000;
time.tm_zone = "EST";
time.tm_wday = 2;
time.tm_yday = 363;
Translating to a date of December 31, 1969 11:00:00 pm. 转换为1969年12月31日晚上11:00:00的日期。
I can verify that mktime()
is responsible, because by commenting out that line, it reports the date and time correctly as January 1, 1970 12:00:00 am. 我可以验证
mktime()
是负责任的,因为通过注释掉该行,它可以正确地将日期和时间报告为1970年1月1日上午12:00:00。
Why is mktime()
only messing up the epoch? 为什么
mktime()
只会搞乱纪元? And how should I fix / workaround this? 我应该如何解决/解决这个问题?
Thanks! 谢谢!
You're passing 0 as the day
parameter and putting that into time.tm_mday
. 您将传递0作为
day
参数,并将其放入time.tm_mday
。 That component (and only that component) of struct tm
is 1-based, not 0-based. struct tm
该组件(并且仅该组件)基于1,而不是基于0。
Don't ask me why. 不要问我为什么。
To specify 01 Jan 1970, 12:00:00am you'd want to call it like so: 要指定1970年1月1日上午12:00:00,您可以这样称呼它:
processComponents(0,1,1970,0,0,0);
And as sdtom mentioned , you'll want to make sure that tm_isdst
is set appropriately - 0 for not in effect, positive for in effect, and negative for you don't know (in which case mktime()
should try to guess). 正如sdtom所述 ,您将要确保
tm_isdst
设置了tm_isdst
-0表示无效,正数表示有效,而负数表示您不知道(在这种情况下, mktime()
应该尝试猜测)。
Just to let you know, when I pass the date you have (0 Jan 1970, 00:00:00) to mktime()
in MSVC 9 it returns an error (the passed in struct tm
is untouched and the returned time_t
value is -1). 只是让您知道,当我在MSVC 9中将日期(1970年1月0日,00:00:00)传递给
mktime()
,它会返回错误(未传递传入的struct tm
,并且返回的time_t
值为- 1)。
Since it is off by one hour I would expect daylight savings time. 由于关闭一小时,我希望可以节省夏令时。 Is the value of time.tm_isdst getting set somewhere?
time.tm_isdst的值是否设置在某处? If you aren't setting it, it could be randomly getting set to 1 or 0 which would affect your results.
如果未设置,则可能会随机将其设置为1或0,这会影响您的结果。
Passing all zeros to mktime()
is interpreted as "Sun Jan 0 00:00:00 1900". 将所有零传递给
mktime()
解释为“ Sun Jan 0 00:00:00 1900”。 Based on this, there needs to be some adjustments... 基于此,需要进行一些调整...
// the input is local time
// the output is seconds since the epoch
// The epoch is Jan 1, 1970 @ 0:00 GMT
time_t mktime_wrapper( int month, int day, int year,
int hour=0, int min=0, int sec=0, bool isDST=-1
)
{
tm t;
t.tm_sec=sec, t.tm_min=min, t.tm_hour=hour, t.tm_isdst=isDST;
t.tm_mday=day, t.tm_mon=month-1, t.tm_year=year-1900;
return mktime( &t );
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.