2016-09-01 279 views
2

我正在編程一個在BusyBox嵌入式linux上運行的C++代碼。我的代碼和它的庫有幾個調用std::chrono::system_clock::now()來獲取當前時間。std :: chrono :: system_clock :: now()考慮操作系統配置的時區

由於現在我的盒子被配置爲默認時區(UTC),一切正常,進程運行和結果ok。

現在我不得不設置我的linux留在不同的時區。然後,我做到了通過配置在框中/etc/profile

export TZ=UTC+3 

當我發出命令date,我得到了正確的控制檯的時候,但我對std::chrono::system_clock::now() I'm電話仍然得到UTC時間,而不是時間顯示在date命令中(正確的時間)。

我不想改變我所有的now()調用 - 其上有幾百個調用...這導致我的進程在不同的時間工作,而不是在控制檯上設置的正確時間。

有沒有辦法解決這個問題,而不改變我的代碼?我在這裏錯過的任何東西?

感謝您的幫助。

+0

這將是在內部使用任何東西,但UTC是錯誤的。將其顯示給人類用戶時,將其轉換爲當地時間。節目與UTC完全一致,他們不關心我們的晝夜節律。 –

+0

n.m. - 從now()收集的數據然後使用int64格式存儲在本地和雲數據庫中,並將它們上載到Web服務器。然後顯示給最終用戶....在存儲到數據庫之前,我需要在我的C++代碼上獲得正確的時間,因爲我將不會跟蹤上述圖層中的時區... – Mendes

+0

@mendes哦上帝不,不要將本地時間存儲在雲數據庫中。 *可能*存儲用戶設置某個事件時使用的時區*旁邊的通用時間戳(對於日曆應用程序,他們選擇了8月12日和7日),但本地時間幾乎適用於每個用戶輸入和輸出。這種情況(選擇時區)是用戶*在某種意義上(而不是某個時間,某個實際事件發生或「從現在起6小時」)選擇絕對時間點*的時間。 – Yakk

回答

6

儘管標準沒有指定,但std::chrono::system_clock::now()的每個實現都跟蹤Unix Time,這與UTC非常接近。

如果你想std::chrono::system_clock::now()轉換爲本地時間,您可以通過system_clock::to_time_t翻譯system_clock::time_pointtime_t,然後你的工作方式通過C API(如localtime),或者你可以嘗試這是建立在這個現代化的時區庫的<chrono>頂部:

https://howardhinnant.github.io/date/tz.html

你可以使用它來獲取當前的本地時間是這樣的:

#include "tz.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono; 
    auto t = make_zoned(current_zone(), system_clock::now()); 
    std::cout << t << '\n'; 
} 

make_zoned是一種工廠功能,它返回zoned_time類型的任何精度,您的system_clock支持(例如,納秒)。它是time_zonesystem_clock::time_point的配對。

你可以得到一個local_time<Duration>這是一個std::chrono::time_point這樣的:

auto t = make_zoned(current_zone(), system_clock::now()); 
    auto lt = t.get_local_time(); 
    std::cout << lt.time_since_epoch().count() << '\n'; 

雖然庫具有遠程API自動下載IANA timezone database,該API可以通過與-DHAS_REMOTE_API=0編制被禁用。詳情請見installation instructions。在禁用遠程API的情況下,您需要手動從IANA timezone database下載數據庫(這只是一個tar.gz)。

如果需要當前UTC偏移,可以這樣獲得:

auto t = make_zoned(current_zone(), system_clock::now()); 
    auto offset = t.get_info().offset; 
    std::cout << offset << '\n'; 

在上面的代碼片段,我趁着同時GitHub的存儲庫中找到"chrono_io.h"打印offsetoffset有型號std::chrono::seconds。這只是我的輸出:

-14400s 

(-0400)

最後,如果你要發現你的當前時區的IANA名字,那簡直是:

std::cout << current_zone()->name() << '\n'; 

這對我來說只是輸出:

America/New_York 

類型從name()返回的std::string。如果需要,可以記錄該字符串,再後來用time_zone使用該名稱,即使這不是計算機的當前時區:

auto tz_name = current_zone()->name(); 
// ... 
auto t = make_zoned(tz_name, system_clock::now()); // current local time in tz_name 
+0

嗯,我不需要一個字符串,但與原來的現在(),但與時鐘代表正確的時區相同的格式。在圖書館需要外部訪問的情況下,嵌入式系統上沒有互聯網連接... – Mendes

+0

@Mendes:更新瞭解決您的問題的答案。 –

相關問題