Вопрос

Продолжая Моя попытка создать класс 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;
}

На произвольную дату, processComponents(5,5,1990,1,23,45) (6 июня 1990 г. 1:23:45), он устанавливает все значения правильно и, как и ожидалось.

Однако при дальнейшем тестировании я нахожу, что для processComponents(0,0,1970,0,0,0) (1 января 1970 г., 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;

Перевод на дату 31 декабря 1969 г. 11:00:00.

Я могу проверить это mktime() несет ответственность, потому что, комментируя эту линию, она правильно сообщает дату и время, как 1 января 1970 года 12:00:00.

Почему mktime() Только все испортило эпоху? И как мне это исправить / обходно это?

Спасибо!

Это было полезно?

Решение

Ты проходишь 0 как day параметр и вмешивание этого в time.tm_mday. Анкет Этот компонент (и только этот компонент) struct tm на основе 1, а не на 0.

Не спрашивайте меня, почему.

Чтобы указать 01 января 1970 года, 12:00:00, вы бы хотели назвать это так:

processComponents(0,1,1970,0,0,0);

И в качестве SDTOM упомянул, вы захотите убедиться, что tm_isdst Установлен соответствующим образом - 0 для не в силе, положительно для вступления в силу, и отрицательно, чтобы вы не знали (в каком случае mktime() должен попытаться угадать).

Просто чтобы вы знали, когда я прохожу дату, которая у вас есть (0 января 1970, 00:00:00) mktime() В MSVC 9 он возвращает ошибку (передача в struct tm нетронут и вернулся time_t значение равно -1).

Другие советы

Поскольку это ушло на один час, я ожидаю, что время сэкономить дневное время. Значение времени. TM_ISDST будет установлено где -нибудь? Если вы не устанавливаете его, это может быть случайным образом установить на 1 или 0, что повлияет на ваши результаты.

Передавая все нули в mktime() интерпретируется как «Солнце 0 января 00:00:00 1900». Исходя из этого, должны быть некоторые корректировки ...

// 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 с атрибуция
Не связан с StackOverflow
scroll top