Почему mktime () меняет день года моей структуры tm? - PullRequest
6 голосов
/ 06 марта 2012

Я читаю в двух строках год, юлианский день (годовой день), час, минуту и ​​наблюдение.

Я вытаскиваю соответствующие переменные, используя sscanf:

sscanf(tide_str1.c_str(), "%d %d %d %d %Lf", &y1, &j1, &h1, &m1, &obs1);
sscanf(tide_str2.c_str(), "%d %d %d %d %Lf", &y2, &j2, &h2, &m2, &obs2);

Для этого конкретного набора данных значения: 2011 083 23 22 1,1

Затем я создаю и заполняю структуру tm и запускаю mktime с вызовами cout в промежуточный день, который изменяется с 083 до 364.

int y1=2011, j1=83, h1=23, m1=22;
struct tm time_struct = {0, 0, 0, 0, 0, 0, 0, 0, 0}, *time_ptr = &time_struct;
time_t tv_min;
time_struct.tm_year = y1 - 1900;
time_struct.tm_yday = j1;
cout << time_struct.tm_yday << endl;
time_struct.tm_hour = h1;
time_struct.tm_min = m1;
time_struct.tm_isdst = -1;
cout << time_struct.tm_yday << endl;
tv_min = mktime(time_ptr);
cout << time_struct.tm_yday << endl;

Почему это? Это потому, что tm_mday и tm_mon установлены в 0? Сначала я пытался не инициализировать все это до нуля, но затем mktime вернул -1. Что мне делать по-другому, если я знаю только год, а не месяц и месяц?

1 Ответ

17 голосов
/ 06 марта 2012

mktime() делает то, что должен.

Цитирование стандарта C:

Функция mktime преобразует время разбивки,выражается как местное время в структуре, на которую указывает timeptr , в значение календарного времени с той же кодировкой, что и у значений, возвращаемых функцией time .Исходные значения компонентов tm_wday и tm_yday структуры игнорируются, а исходные значения других компонентов не ограничиваются указанными выше диапазонами.При успешном завершении значения компонентов tm_wday и tm_yday структуры устанавливаются соответствующим образом, а остальные компоненты задаются для представления указанного календарного времени, но их значения принудительно устанавливаются надиапазоны, указанные выше;окончательное значение tm_mday не устанавливается до тех пор, пока не будут определены tm_mon и tm_year .

mktime() может вычислить значения tm_mday и tm_yday от других участников;он не предназначен для вычисления значений других членов из этих полей.

Однако вы можете инициализировать struct tm значениями вне диапазона.Например, если вы хотите, чтобы tm_yday было 200 (200-й день года), вы можете инициализировать struct tm, представляющий 200-й день января.mktime() затем нормализует его до правильной даты, получая значение time_t, которое вы можете затем передать gmtime() или localtime().

Вот простой пример:

#include <iostream>
#include <ctime>

int main()
{
    struct tm t = { 0 };
    t.tm_sec = t.tm_min = t.tm_hour = 0; // midnight
    t.tm_mon = 0;                        // January
    t.tm_year = 2012 - 1900;
    t.tm_isdst = -1;                     // unknown

    t.tm_mday = 200;                     // January 200th?

    time_t when = mktime(&t);
    const struct tm *norm = localtime(&when);   // Normalized time

    std::cout << "month=" << norm->tm_mon << ", day=" << norm->tm_mday << "\n";
    std::cout << "The 200th day of 2012 starts " << asctime(norm);
}

Вывод:

month=6, day=18
The 200th day of 2012 starts Wed Jul 18 00:00:00 2012
...