C++ проблема времени t
у меня проблемы с управлением датами в C++ (VS 2008).
По данным MSDN технические характеристики, time_t
представляет:
количество секунд с 1 января 1970 года, 0: 00 UTC
поэтому я написал этот кусок кода:
#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;
}
похоже, что он сдвинут на 1 час (т. е. нулевое время-1 января 1970 года, 1:00 UTC).
Первоначально я думал, что проблема может исходить из Времени флаг, но это не меняет, изменяя его.
Я делаю что-то неправильно ?
спасибо заранее
С. П. Теоретически, я мог бы не возражать против нулевого значения времени, потому что это только эталонное время.
но мне нужно быть уверенным в значении, потому что я портирую код на другой язык, и мне нужно получить точно такие же результаты.
EDIT:
вот решение, спасибо Джош Келли Ответ
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;
}
2 ответов
mktime
принимает struct tm
дав местные время и возвращает количество секунд с 1 января 1970 года, 0: 00 UTC. Следовательно, ваш GetDate(1970,1,1,0,0,0);
вызов вернет 0, если ваш локальный часовой пояс UTC, но может возвращать другие значения для других часовых поясов.
Edit: для версии UTC mktime
или GetDate
, попробуйте следующее (непроверенных):
просто шутка, но попробуйте следующее:
timeinfo->tm_year = year - (unsigned long)1900;
timeinfo->tm_mon = month - (unsigned long)1;