5

这很尴尬,但我很难对日期时间进行简单的操作。

这是我基本上尝试使用 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 day=14 的日期的示例。

PS:chrono 是否足以在 c++11 中处理日期/时间/时区?需要time.h吗?

4

2 回答 2

7

旧问题的新答案。

除了弄乱古老的std::tm,C++11 没有处理日期或日期时间的好方法,除了boost Date Time。还有一个我最近一直在研究的库,它高度倾向于性能、编译时类型安全和chrono兼容性。如前所述,它仅适用于 C++14,但如果您退出某些constexprs,它将适用于 C++11。它是仅标头,仅包含一个标头,并在此处记录。 它的 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}, "");

这意味着“日期常量”既可读又高效,可以编译为“立即加载”。

有关完整描述、教程和实现,请参阅文档。

于 2015-03-27T01:55:07.430 回答
5

您需要从 初始化所有字段tm,从

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

如果没有这个,其他字段(您之后没有明确设置的字段)将包含任意值。转换还将标准化值,这意味着如果该字段tm_hour包含 123456789,它将在您指定的日期增加这么多小时。这就是e1可以解释这些无意义值的方式。如果您显式初始化所有字段,它将允许您的示例返回有意义的值,尽管您可能需要设置更多字段,例如isdst使其适用于所有情况。

我不得不承认,chrono到目前为止我还没有使用过,因为我发现所需的语法过于冗长,并且我继续使用我自己的类来包装 C 风格的时间函数。当然,这不是关于 质量和力量的陈述<chrono>,也许我应该开始使用它 :)

于 2013-04-05T18:31:50.853 回答