[英]localtime() crashes when pass value >0x7FFFFFFF
根據我的理解time_t rawtime = 0xffFFffFF
是GMT: Sunday, February 7, 2106 6:28:15 AM
但是下面的程序在某些編譯器中帶來了Thu 1970-01-01 02:59:59 MSK
,而在其他編譯器中則崩潰了。
int main()
{
time_t rawtime = 0xffFFffFF;
struct tm ts;
char buf[80];
ts = *localtime(&rawtime);
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
printf("%s\n", buf);
return 0;
}
rawtime >0x7fFFffFF
時出現錯誤行為。 為什么? 如何解決這個問題?
UPD:我需要有一系列警報並在時機成熟時采取行動。 這是嵌入式系統,我無法忍受 memory 和復雜數據類型的資源。
在大多數平台上,類型time_t
是簽名的 integer。 同樣在大多數平台上, time_t
從 1970 年 1 月 1 日開始計算時間。結合這兩個事實,我們有對應於 1970 年 1 月 1 日之前的日期的負time_t
值。
如果你機器上的time_t
是一個有符號的 32 位 integer, 0xffffffff
是 -1。 因此,理論上,該值對應於 1969 年 12 月 31 日的 23:59:59 UTC,即 UTC 午夜前一秒。 但在某些情況下,-1 表示錯誤。 因此,盡管我從未遇到過它,但如果有一個localtime()
實現將輸入的值 -1 視為錯誤,我並不完全感到驚訝。
你說它“崩潰了”,但這部分是你的錯。 localtime
通過返回 null 指針來指示失敗。 所以寫起來更安全
struct tm *ts;
ts = localtime(&rawtime);
if(ts == NULL) {
fprintf(stderr, "localtime failed\n");
exit(1);
}
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
如果time_t
是帶符號的 32 位值,則其最大值為 2147483647(仍假設 Unix 時期為 1970 年)對應於 2038 年 1 月 19 日 03:14:07 UTC。 最小值 2147483648 對應於 1901 年 12 月 13 日 20:45:52 UTC。
沒錯,如果time_t
被視為無符號,則最大 32 位值將是 4294967295 並且對應於您提到的 2106 中的日期和時間。
如果time_t
是 64 位類型,並且越來越流行(為了防止y2.038k 問題或多或少有必要),則最大值是如此之大以至於它實際上毫無意義。 (它太大了,年份甚至不能用 32 位表示。)
最后,值得記住的是time_t
的解釋是特定於平台的。 從理論上講,它不一定要計算秒數,不一定要從 1970 年 1 月 1 日開始計算,甚至不一定是 integer。 即使這些事實確實成立,也沒有規定必須對time_t
進行簽名,因此在為廣泛可移植性而設計的程序中,我不會指望有對應於 1901-1970 的值,因為在某些平台上它們可能對應於畢竟是 2038-2106 年。
time_t
的類型和范圍是實現定義的,沒有最低要求。 它可以是有符號、無符號、32 位、64 位、浮點等。
如果您使用的編譯器沒有time_t
其范圍符合您的要求,您可以:
time_t
,或time_t
限制內工作。 正如評論中提到的,“崩潰”可能是由於本地時間由於輸入超出范圍而返回localtime
指針,並且您在沒有首先檢查 null 的情況下取消引用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.