两个独立的tm结构互相镜像

时间:2010-06-15 16:17:23

标签: c++ time linked-list time-t

以下是我目前的情况:

  • 我有两个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 个答案:

答案 0 :(得分:3)

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

  

此结构由gmtime和localtime函数静态分配和共享。每次调用其中一个函数时,都会覆盖此结构的内容。

您需要将值复制出结构。您的函数可以按值返回tm结构,您可以取消引用主程序中的函数等。

答案 1 :(得分:3)

你必须这样做:

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将指向相同的内存地址!

答案 2 :(得分:1)

你实际上根本没有两种不同的tm结构。你所拥有的是两个tm结构指针,它们都指向localtime返回的相同静态结构。因此看起来对一个的改变会影响另一个,但实际上它只是一个结构有两个不同的指针。

解决这个问题最安全的方法是不依赖于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);