2016-07-31 87 views
3

我有一個time_t,它代表自epoch以來的秒數。那些秒指的是當地時間。將time_t從本地時區轉換爲UTC

我想將它們轉換爲UTC。

有沒有辦法在C++中做到這一點?

+0

不確定爲什麼減少?這個問題非常具體和明確。 – MATH000

+0

應該關閉與問題相同的原因:無:-)你是對的,這個問題是從來沒有廣泛的,這裏沒有什麼錯......只是忘記了SO中的選票。 – Klaus

+1

有效的'time_t'值(在類Unix系統上)總是相對於1970-01-01 00:00:00 ** UTC **。你是如何得到當地時間的價值的? –

回答

3

我要表明這樣做的方法有兩種:

  1. 使用C API。
  2. 使用基於<chrono>頂部的現代C++ 11/14庫。

對於本演示的目的,我假設當前時區的秒數爲1,470,003,841。我當地的時區是America/New_York,所以我得到的結果反映我們目前在-0400 UTC。

首先是C API:

這個API是不是類型安全的,而且非常容易出錯。我在編寫答案時犯了幾個錯誤,但是我能夠快速檢測到這些錯誤,因爲我正在檢查第二種技術的答案。

#include <ctime> 
#include <iostream> 

int 
main() 
{ 
    std::time_t lt = 1470003841; 
    auto local_field = *std::gmtime(&lt); 
    local_field.tm_isdst = -1; 
    auto utc = std::mktime(&local_field); 
    std::cout << utc << '\n'; // 1470018241 
    char buf[30]; 
    std::strftime(buf, sizeof(buf), "%F %T %Z\n", &local_field); 
    std::cout << buf; 
    auto utc_field = *std::gmtime(&utc); 
    std::strftime(buf, sizeof(buf), "%F %T UTC\n", &utc_field); 
    std::cout << buf; 
} 

首先我初始化time_t。現在沒有C API從本地time_t轉到UTC time_t。但是,您可以使用gmtime從UTC time_t轉到UTC tm(從串行到字段類型,全部採用UTC)。所以第一步是謊言gmtime,告訴它你有UTC time_t。然後當你得到結果時,你只需假裝你有一個本地tm而不是UTC tm。目前清除?這就是:

auto local_field = *std::gmtime(&lt); 

現在你走之前(我個人搞砸這部分了第一次通過),你必須以擴大此字段類型說,你不知道這是否是當前夏令與否。這會導致隨後的步驟去弄清楚你:

local_field.tm_isdst = -1; 

接下來,您可以使用make_time到本地tm轉換爲UTC time_t

auto utc = std::mktime(&local_field); 

您可以打印出來,對我來說是:

1470018241 

這是4h更大。其餘的功能是以可讀的格式打印出這些時間,以便您可以調試這些東西。對於我來說,輸出:

2016-07-31 22:24:01 EDT 
2016-08-01 02:24:01 UTC 

現代C++ API:

存在着在的std :: lib中沒有任何設施,以做到這一點。但是,您可以使用此free, open source (MIT license) library

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

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono_literals; 
    auto zt = make_zoned(current_zone(), local_seconds{1470003841s}); 
    std::cout << zt.get_sys_time().time_since_epoch() << '\n'; // 1470018241s 
    std::cout << zt << '\n'; 
    std::cout << zt.get_sys_time() << " UTC\n"; 
} 

的第一步是從紀元創造秒爲單位的本地時間:

local_seconds{1470003841s} 

接下來要做的是創建一個zoned_time這是本當地時間配對和當前時區:

auto zt = make_zoned(current_zone(), local_seconds(1470003841s)); 

然後,你可以簡單地打印出的這個配對秒UTC號:

std::cout << zt.get_sys_time().time_since_epoch() << '\n'; 

此輸出對我來說:

1470018241s 

(4H比輸入更高版本)。要打印出這個結果,我的C API中那樣:

std::cout << zt << '\n'; 
std::cout << zt.get_sys_time() << " UTC\n"; 

,輸出:

2016-07-31 22:24:01 EDT 
2016-08-01 02:24:01 UTC 

在這個現代化的C++的辦法,在本地時間和UTC時間是不同的類型,使其更更有可能是我在編譯時意外混合了這兩個概念(與創建運行時錯誤相反)。

1

您可以使用gmtime的:

轉換的time_t以TM作爲UTC時間使用由計時器指出 值填充代表相應 時間值的TM結構,表示爲UTC時間(即GMT時區的時間)。

(三)http://www.cplusplus.com/reference/ctime/gmtime/

+0

'gmtime'假設一個基於UTC的'time_t'值。 OP說他有一個本地時間基於'time_t'值 - 我懷疑這是一個誤解。 –