tags:

views:

141

answers:

2

Continuing on my attempt to create a DateTime class , I am trying to store the "epoch" time in my function:

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.

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:

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.

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.

Why is mktime() only messing up the epoch? And how should I fix / workaround this?

Thanks!

+2  A: 

Since it is off by one hour I would expect daylight savings time. Is the value of time.tm_isdst getting set somewhere? If you aren't setting it, it could be randomly getting set to 1 or 0 which would affect your results.

sdtom
+1. I was thinking along the same lines. According to Python (on Mac OS X), `gmtime(0)` returns: `time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)`. I'm not sure what that proves, though, because Python does some translation of `struct tm` when it builds a `time.struct_time` object.
Daniel Pryden
`tm_isdst` is reporting 0. I have updated the post to reflect the rest of the `time` structure, according to my debugger.
Austin Hyde
specify -1 for it as you are not setting it anywhere and don't know it :)
rama-jka toti
+3  A: 

You're passing 0 as the day parameter and putting that into time.tm_mday. That component (and only that component) of struct tm is 1-based, not 0-based.

Don't ask me why.

To specify 01 Jan 1970, 12:00:00am you'd want to call it like so:

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).

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).

Michael Burr
Thanks! When I explicitly set `time.tm_isdst = -1` everything works.
Austin Hyde