I'm having trouble with dates management in C++ (VS 2008).
According to MSDN specifications, time_t
represents:
The number of seconds since January 1, 1970, 0:00 UTC
therefore, I've written this piece of code:
#include <stdio.h>
#include <time.h>
time_t GetDate(int year, int month, int day, int hour, int min, int sec)
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = gmtime ( &rawtime );
timeinfo->tm_year = year - 1900;
timeinfo->tm_mon = month - 1;
timeinfo->tm_mday = day;
timeinfo->tm_hour = hour;
timeinfo->tm_min = min;
timeinfo->tm_sec = sec;
timeinfo->tm_isdst = 0; // disable daylight saving time
time_t ret = mktime ( timeinfo );
return ret;
}
int main ()
{
time_t time_0 = GetDate(1970,1,1,0,0,0);
// time_0 == -1 !!!
time_t time_1 = GetDate(1970,1,1,1,0,0);
// time_1 == 0 !!!
return 0;
}
It seems to be shifted by 1 hour (i.e. zero time is January 1, 1970, 1:00 UTC).
Initially, I thought the problem could come from the DayLightSaving flag, but it doesn't change by changing it.
Am I doing something wrong ?
Thanks in advance
P.S. In theory, I might not mind the zero time value, because it's only a reference time.
But I need to be sure about the value, because I'm porting the code to another language and I need to get exactly the same results.
here's the solution, thanks to Josh Kelley Answer
time_t mktimeUTC(struct tm* timeinfo)
{
// *** enter in UTC mode
char* oldTZ = getenv("TZ");
putenv("TZ=UTC");
_tzset();
// ***
time_t ret = mktime ( timeinfo );
// *** Restore previous TZ
if(oldTZ == NULL)
{
putenv("TZ=");
}
else
{
char buff[255];
sprintf(buff,"TZ=%s",oldTZ);
putenv(buff);
}
_tzset();
// ***
return ret;
}
mktime
takes a struct tm
giving a local time and returns the number of seconds since January 1, 1970, 0:00 UTC. Therefore, your GetDate(1970,1,1,0,0,0);
call will return 0 if your local time zone is UTC but may return other values for other time zones.
Edit: For a UTC version of mktime
or your GetDate
, try the following (untested):
getenv
to save the current value of the TZ environment variable (if any).putenv
to change the TZ environment variable to "UTC"._tzset
to make your changes active.mktime
._tzset
again.Just a WAG but try the following:
timeinfo->tm_year = year - (unsigned long)1900;
timeinfo->tm_mon = month - (unsigned long)1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With