2013-04-05 197 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了解完整的说明,教程和实施。