سؤال

ها هو وضعي الحالي:

  • لديّان TM ، كلاهما تم تعيينهما على الوقت الحالي
  • أقوم بتغيير في الساعة في أحد الهياكل
  • التغيير يحدث في الهياكل الأخرى سحرية ....
  • كيف يمكنني منع هذا من الحدوث؟ يجب أن أكون قادرًا على مقارنة ومعرفة عدد الثواني بين مرتين مختلفتين - الوقت الحالي والوقت في المستقبل. لقد كنت أستخدم difftime و mktime لتحديد ذلك. أدرك أنني لا أحتاج تقنيًا إلى بنيتين TM (يمكن أن يكون الهيكل الآخر مجرد وقت محمّل بوقت خام) لكنني ما زلت مهتمًا بفهم سبب حدوث ذلك.

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;
}
هل كانت مفيدة؟

المحلول

انت مجبر على عمل هذا:

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 سوف تشير إلى نفس عنوان الذاكرة!

نصائح أخرى

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

يتم تخصيص هذا الهيكل بشكل ثابت ومشاركته من خلال وظائف GMTIME و LocalTime. في كل مرة تسمى إحدى هذه الوظائف محتوى هذا الهيكل.

ستحتاج إلى نسخ القيمة من البنية. يمكن أن تُرجع وظائفك بنية TM حسب القيمة ، ويمكن أن تضعف الوظائف في البرنامج الرئيسي ، إلخ.

ليس لديك في الواقع اثنين من هياكل TM مختلفة على الإطلاق. ما لديك هو اثنين من مؤشرات TM Struct ، وكلاهما يشير إلى نفس الهيكل الثابت الذي تم إرجاعه بواسطة 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top