如何在c++11中操作日期/日期时间?

问题描述 投票:0回答:2

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

这是我基本上尝试使用 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,它作为日期时间的 c++11 标准库提供,但我只是找不到如何创建具有 intyear=2012、intmonth=2、intday=14 的日期的示例.

PS:chrono 足以处理 c++11 中的日期/时间/时区吗?需要时间吗?

c++ c++11
2个回答
7
投票

C++20 更新

时间不断前行。 ;-)

在 C++20 中,这现在很容易完全在

std::chrono
内完成:

#include <chrono>
#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 std::chrono;
    sys_days date1 = April/5/2012;   // m/d/y is ok
    sys_days date2 = 8d/July/2013;   // d/m/y is ok
                                     // y/m/d is also ok
    auto diffDays = date2 - date1;   // diffDays is a chrono::duration
    std::cout << diffDays << '\n';
}

演示。

原答案:

老问题的新答案。

除了搞乱古老的

std::tm
之外,C++11没有处理日期或日期时间的好方法,除了boost Date Time。 我最近一直在研究另一个库,它非常注重性能、编译时类型安全性和
chrono
兼容性。 正如所介绍的,它仅适用于 C++14,但如果您取消一些
constexpr
,它将适用于 C++11。 它仅包含标头,并且仅包含一个标头,并在here进行了记录。 它的 I/O 能力很轻。(现在具有广泛的 I/O 能力)

但是对于您的示例来说,它是这样的:

哦,现在仔细一看,又不懂C#,我不知道

DateTime(4,5,2012)
指的是Apr 5, 2012还是May 4, 2012。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}, "");

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

请参阅文档以获取完整的描述、教程和实现。


5
投票

您需要初始化

tm
中的所有字段,从

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

如果没有这个,其他字段(您之后没有明确设置的字段)将包含任意值。转换还将标准化值,这意味着如果字段

tm_hour
包含 123456789,它将在您指定的日期中添加这么多小时。这就是如何解释
e1
的那些无意义值。如果您显式初始化所有字段,它将允许您的示例返回有意义的值,尽管您可能需要设置更多字段(如
isdst
)以使其在所有情况下都正确。

我必须承认我还没有使用过

chrono
,因为我发现所需的语法过于冗长,并且我一直使用自己的类来包装 C 风格的时间函数。当然,这并不是关于
<chrono>
的质量和功能的声明,也许我应该开始使用它:)

© www.soinside.com 2019 - 2024. All rights reserved.