Две отдельные тм структуры, отражающие друг друга - PullRequest
2 голосов
/ 15 июня 2010

Вот моя текущая ситуация:

  • У меня есть две структуры tm, обе установлены на текущее время
  • Я изменяю час в одной из структур
  • Магическое изменение происходит в другой структуре ....
  • Как мне предотвратить это? Мне нужно уметь сравнивать и знать количество секунд между двумя разными временами - текущим временем и временем в будущем. Я использовал difftime и mktime, чтобы определить это. Я признаю, что технически мне не нужны две структуры tm (другая структура может быть просто time_t, загруженным необработанным временем), но мне все еще интересно понять, почему это происходит.

void Tracker :: monitor (char * buffer) {

// time handling
time_t systemtime, scheduletime, currenttime;
struct tm * dispatchtime;
struct tm * uiuctime;
double remainingtime;


// let's get two structs operating with current time
dispatchtime = dispatchtime_tm();
uiuctime = uiuctime_tm();

// set the scheduled parameters
dispatchtime->tm_hour = 5;
dispatchtime->tm_min = 05;
dispatchtime->tm_sec = 14;

uiuctime->tm_hour = 0;

    // both of these will now print the same time! (0:05:14)
    // what's linking them??

// print the scheduled time
printf ("Current Time :  %2d:%02d:%02d\n", uiuctime->tm_hour, uiuctime->tm_min, uiuctime->tm_sec);
printf ("Scheduled Time :  %2d:%02d:%02d\n", dispatchtime->tm_hour, dispatchtime->tm_min, dispatchtime->tm_sec);

}

struct tm* Tracker::uiuctime_tm(){
    time_t uiucTime;
    struct tm *ts_uiuc;

    // give currentTime the current time
    time(&uiucTime);

    // change the time zone to UIUC
    putenv("TZ=CST6CDT");
    tzset();

    // get the localtime for the tz selected
    ts_uiuc = localtime(&uiucTime);

    // set back the current timezone
    unsetenv("TZ");
    tzset();

    // set back our results
    return ts_uiuc;
}

struct tm* Tracker::dispatchtime_tm(){
    time_t currentTime;
    struct tm *ts_dispatch;

    // give currentTime the current time
    time(&currentTime);

    // get the localtime for the tz selected
    ts_dispatch = localtime(&currentTime);

    // set back our results
    return ts_dispatch;
}

Ответы [ 3 ]

3 голосов
/ 15 июня 2010

Вы должны сделать это:

struct tm* temp_tm;
struct tm dispatchtime; // No longer a pointer
struct tm uiuctime;     // No longer a pointer

temp_tm = dispatchtime_tm();
dispatchtime = *temp_tm; // Member to member copy

temp_tm = uiuctime_tm();
uiuctime = *temp_tm; // Member to member copy

Таким образом, вы будете хранить локальную копию структуры tm.Эта структура размещается внутри стандартной библиотеки, каждый вызов localtime будет указывать на один и тот же адрес памяти!

3 голосов
/ 15 июня 2010

http://www.cplusplus.com/reference/clibrary/ctime/localtime/

Эта структура статически выделяется и совместно используется функциями gmtime и localtime.Каждый раз, когда одна из этих функций называется, содержимое этой структуры перезаписывается.

Вам необходимо скопировать значение из структуры.Ваши функции могут возвращать структуру tm по значению, вы можете разыменовать функции в основной программе и т. Д.

1 голос
/ 15 июня 2010

У вас вообще нет двух разных структур тм вообще. У вас есть два указателя на структуру tm, оба указывают на одну и ту же статическую структуру, возвращаемую локальным временем. Таким образом, кажется, что изменения одного влияют на другое, но в действительности это просто одна структура, имеющая два разных указателя.

Самый безопасный способ решить эту проблему - не полагаться на статическую структуру localtime, а использовать localtime_r, который требует, чтобы вы передали собственный указатель структуры tm, который затем будет заполнен. Например:

void Tracker::uiuctime_tm(struct tm* out){
    time_t uiucTime;

    // give currentTime the current time
    time(&uiucTime);

    // change the time zone to UIUC
    putenv("TZ=CST6CDT");
    tzset();

    // get the localtime for the tz selected, and set back the result into the output parameter.
    localtime_r(&uiucTime, out);

    // set back the current timezone
    unsetenv("TZ");
    tzset();
}

struct tm uiuctime;
uiuctime_tm(&uiuctime);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...