2013-04-05 191 views
3

這很尷尬,但我很難對日期時間進行簡單的操作。如何在C++ 11中操作日期/日期時間?

這是我基本上嘗試使用C++ 11的c#版本;

DateTime date1=new DateTime(4,5,2012); 
DateTime date2=new DateTIme(7,8,2013); 
int day1=date1.Days; 
TimeSpan ts=d2-d1; 
int diffDays=ts.Days; 

我試過了什麼?

std::tm tm; 
    tm.tm_year=113; 
    tm.tm_mon=0; 
    tm.tm_wday=0; 

    std::time_t tt=mktime(&tm); 
    std::chrono::system_clock::time_point then = std::chrono::system_clock::from_time_t(tt); 
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); 
    auto e1 = std::chrono::duration_cast<std::chrono::hours>(now - then).count(); 

E1(379218)的價值是沒有意義都沒有。

我看了一下chrono,它是用於datetime的C++ 11標準庫,但我找不到如何創建int year = 2012,int month = 2,int天= 14。

PS:在C++ 11中是否足夠處理日期/時間/時區?是否需要time.h?

+1

''處理時間,但它不處理日曆,這是你正在尋找(不是從'time_t'轉換)。我還不知道任何建立在''之上的日曆庫。 – 2013-04-05 18:27:53

+3

對於處理日期,有一個優秀的'boost gregorian'庫:http://www.boost.org/doc/libs/1_39_0/doc/html/date_time/gregorian.html。另外QT也有它自己的日期類。 – decden 2013-04-05 18:29:34

+3

除了使用boost庫的好建議之外,歡迎您嘗試使用此答案中描述的日期庫:http://stackoverflow.com/a/15146434/576911。這是直接鏈接到它:http://home.roadrunner.com/~hinnant/bloomington/date.html – 2013-04-05 18:47:35

回答

2

你需要從tm初始化所有領域,開始

std::tm tm = {0,0,0,0,0,0,0,0,0,0,0}; 

如果沒有這個,其他字段(你不明確設置之後的那些)將包含任意值。轉換也會使值正常化,這意味着如果字段tm_hour包含123456789,它會在指定的那一天增加很多小時。這就是e1這些無意義值的解釋方式。如果您明確初始化所有字段,它將允許您的示例返回有意義的值,但您可能需要設置更多字段,如isdst以使其正確適用於所有情況。

我不得不承認,我沒有使用chrono,只要我發現所需的語法過於冗長,並且我繼續使用自己的類來包裝C風格的時間函數。當然,這不是關於<chrono>的質量和功率的說明,也許我應該開始使用它:)

+0

你不能只是'std :: tm tm = {0}'? – 0x499602D2 2013-04-05 20:33:06

+0

@ 0x499602D2是的,但GCC和鏘會警告你缺少字段初始值(一個或多個),參見[LWS](http://liveworkspace.org/code/2CAxKb$0)。 – 2013-04-05 20:38:22

+0

@Daniel:但我懷疑'std :: tm tm = {};'不會。 – ildjarn 2013-04-06 04:46:50

5

對於舊問題的新答案。

除了搞亂陳舊的std::tm,C++ 11沒有處理日期或日期時間的好方法,boost Date Time除外。另外還有一個我最近一直在研究的庫,它非常傾向於性能,編譯時類型安全性和兼容性。由於提出只與C++ 14的工作,但如果你背過一些constexpr S的,它會與C++ 11的工作。它只是標題,並且只包含一個標題,並記錄在here中。它的I/O能力很弱。(現在擁有豐富的I/O能力)

但這裏是它看起來像你的例子:

哦,現在,我仔細一看,不知道C#,我不知道是否DateTime(4,5,2012)指2012年4月5日或2012年5月4日.m/d/y和d/m/y格式均廣泛使用。這是我的圖書館解決的問題之一。它明確接受這兩種格式。在這個演示中,我假設你使用m/d/y格式編寫。但我會用兩種格式複製你的例子:

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

int 
main() 
{ 
//  DateTime date1=new DateTime(4,5,2012); 
//  DateTime date2=new DateTIme(7,8,2013); 
//  int day1=date1.Days; 
//  TimeSpan ts=d2-d1; 
//  int diffDays=ts.Days; 

    using namespace date; 
    auto date1 = sys_days(apr/5/2012);  // m/d/y is ok 
    auto date2 = sys_days(8_d/jul/2013); // d/m/y is ok 
              // y/m/d is also ok 
    auto diffDays = date2 - date1;   // diffDays is a chrono::duration 
    std::cout << diffDays.count() << '\n'; 
} 

這將輸出:

459 

而且在C++ 14,這種計算實際上可以在編譯時完成:

constexpr auto date1 = sys_days(apr/5/2012); 
constexpr auto date2 = sys_days(8_d/jul/2013); 
constexpr auto diffDays = date2 - date1; 
static_assert(diffDays == days{459}, ""); 

而這意味着「日期常量」可以非常易讀且非常高效,編譯爲「立即加載」。

查看the documentation瞭解完整的說明,教程和實施。