2012-09-06 45 views
0

我編寫了以下代碼片段以將輸入日期提前到下一個日曆日期。當在用g ++編譯的虛擬源代碼文件中測試時,此方法運行良好。4.1.2使用ctime提前指定日期到下一個日曆日期的問題

但是,當從我公司的模擬器(其中錯綜複雜的細節在此處不可用)中運行以下代碼時,它會在20021027 ;即20021027以外的日期,它按預期工作,但是對於20021027,它本身返回20021027。

請告知可能會出現什麼問題?

int nextday(const int &date, int n=1) 
{ 
    struct tm curr_time; 

    int yyyy = curr_time.tm_year = date/10000-1900; 
    int mm = curr_time.tm_mon=(date/100)%100-1; 
    int dd = curr_time.tm_mday=date%100; 
    curr_time.tm_min=0; 
    curr_time.tm_sec=0; 
    curr_time.tm_hour=0; 

    time_t next = mktime(&curr_time) + 24*60*60*n; 
    struct tm new_time; 
    localtime_r(&next,&new_time); 
    yyyy = 1900 + new_time.tm_year; 
    mm = 1 + new_time.tm_mon; 
    dd = new_time.tm_mday; 
    return (10000*yyyy+100*mm+dd); 
} 

回答

1

我不明白爲什麼這一個日期會導致問題,但我不知道爲什麼你要做的事情困難的方式。在調用mktime之前,只需在 tm_mday字段中添加一個,然後從struct tm中提取已更正的 值,您將其傳入mktime。 (還有一個原因 爲什麼指針變成mktime指向非const。)喜歡的東西:

int 
nextday(int date, int n = 1) 
{ 
    tm broken_down; 
    broken_down.tm_year = date/10000 - 1900; 
    broken_down.tm_mon = (date/100) % 100 - 1; 
    broken_down.tm_mday = date % 100 + n; 
    broken_down.tm_hour = 12; // avoid issues with summer time, etc. 
    broken_down.tm_min = 0; 
    broken_down.tm_sec = 0; 
    mktime(&broken_down); 
    return (broken_down.tm_year + 1900) * 10000 
     + (broken_down.tm_mon + 1) * 100 
     + broken_down.tm_mday; 
} 

(您可能要增加一些理智的檢查,即驗證,在真正通過int 並代表日期預期的格式,並且 n是在一些合理的範圍內。或者,如果你能影響決策, 使用一些標準的日期格式,所以你不必。)

不管怎麼說,我懷疑一些問題在模擬器中,特別是如果它在本地使用相同的值。

+0

謝謝你的這段代碼。這確實有效,結果是夏令時導致了這個問題。 原來DST在美國結束20021027!因此,這會將時間推回一小時,導致代碼指向相同的日期(因爲我使用的是00:00:00引用) 通過設置tm_isdst = 0(標準時間)或使用tm_hour = 12,這個問題得到解決 – Mindstorm

+0

對我沒有意識到這一點我感到羞恥,我經常這樣做,我只是自動使用中午,即使沒有考慮原因。 –

0

你只是達到2147483647的整數限制,然後向下舍入。

如果任何數字超過該值^^,請務必檢查您的代碼。切換到無符號應該修復(或只是將問題還原到4294967295)

編輯:你是正確的。我的回答是錯誤的。

+1

在哪個表達式中溢出?我發現在一臺32位的機器上,他應該是214748年的好時機。(time_t的值可能有問題,但是他也會遇到重大的系統問題)(一個帶符號的32位'time_t ',從1970年開始,直到2038年纔有效。) –

相關問題