Linux C的localtime函式問題
剛好前陣子工作時遇到一個讓我找了一整天的BUG,在這裡跟大家分享一下,免得以後還有其他受到這個問題的殘害。在C語言的library中,在 linux 下的時區的設定是利用TZ這個環境變數來指定,如果TZ環境變數沒有設定,則會以/etc/localtime為主。
/etc/localtime檔案可能是個符號連結到一個時區設定檔,或是一個真實檔案。大部份linux系統會將環境變數指向
/etc/localtime,“TZ=/etc/localtime”,再藉由/etc/localtime來指向時區檔案。在C語言中,如果時區發現變化,會使用 tzset() 涵數讓系統重新讀取到新的時間,但這個動作並無法發揮作用,導致/etc/localtime產生變化後,而 localtime() 仍然會使用舊的時區來讀取時間。tzset() 會 reset 三個C的內部變數,分別為 tzname丶timezone丶daylight。在此提供一個方法避開這個問題,因為tzset()無法成功的 reset 這三個變數,使得 localtime() 察覺不到時區的變化。
範例如下:
時間12:00
環境變數:
TZ=”/etc/localtime”
時區檔案:
/etc/localtime -> /mnt/html/zoneinfo/GMT+08:00
透過date指令得到的時間為12:00
透過localtime()涵數讀取到的時間為12:00
現將/etc/localtime指向新的時區檔案:
/etc/localtime -> /mnt/html/zoneinfo/GMT+06:00
透過date指令得到的時間為10:00
透過localtime()涵數讀取到的時間仍然為12:00
因為導致使用 localtime() 涵數的功能發生時間上的錯誤。解決方法如下:
可以透過TZ環境變數的強制改變,來使 tzname丶timezone丶daylight 這三個內部變數更新到新的時區。
在/etc/localtime指到新的時區之後,先將TZ環境變數設為NULL。讓 localtime() 先讀取一次時間,此時會因為TZ設定
NULL而使得 localtime() 以UTC時區讀取時間,接著再一次將TZ環境變數指回 /etc/localtime,再一次使用 localtime() 涵數便可以得到正確的時間。範例如下:
時間12:00
環境變數:
TZ=”/etc/localtime”
時區檔案:
/etc/localtime -> /mnt/html/zoneinfo/GMT+08:00
透過date指令得到的時間為12:00
透過localtime()涵數讀取到的時間為12:00
時間12:00
環境變數將TZ改為NULL:
TZ=”NULL”
時區檔案:
/etc/localtime -> /mnt/html/zoneinfo/GMT+08:00
透過date指令得到的時間為4:00
透過localtime()涵數讀取到的時間為4:00
再一步將環境變數將TZ改回/etc/localtime:
TZ=”/etc/localtime”
透過date指令得到的時間為12:00
透過localtime()涵數讀取到的時間為12:00
備註:
發生環境:Ubuntu丶Fedora
gcc version: 4.1.3
glibc: 2.3.6
訂閱:
張貼留言 (Atom)
dnf upgrade fails with Error: GPG check FAILED
OS: Fedora 36 今天在做 dnf 更新的時候,突然有很多 package 都出現簽章問題無法更新。類似如下的錯誤訊息 .... is not signed. ...... is not signed. ......... is not...
-
這陣子決定將自己的筆記從 Evente 轉換到 Joplin,順便把轉換的過程和心得記錄下來,方便有相同需求或是在評估 Joplin 的捧油可以有個參考。 現在的筆記軟體或平台很多,依每個人需求的不同都會有較適合的方案,最後我會選擇 Jopline 最主要的原因是 程式碼開...
-
VIM的搜尋取代插入進階用法 VIM 中的基本搜尋方式是在普通模式下按 “/” 鍵(指令模式的),再輸入要搜尋的字串或是 正則表示式 ,就可以找到需要的字串。 透過搜尋的結果可以驗證輸入的條件或正則表示式是否可以正確選出要處理的字串。例如以下的檔案內容 冰ic...
-
Gnucash入門使用教學(一) 五大類介紹 Gnucash是一套複式簿記系統的記帳軟體,基本上的概念和會計相同,將所有帳目分為五大類,再由五大類細分出各細項。這五大類分別是“資產(Assets)”丶“負債(Liabilities)”丶“收入(Income)”...
沒有留言:
張貼留言