从C++中的std :: chrono :: time_point中提取年/月/日等

byt*_*e77 43 c++ time c++11 c++-chrono

如何从对象中提取年,月,日,小时,分钟,秒和毫秒std::chrono::time_point

我只看到了如何从a中提取例如秒的总量的示例duration.

How*_*ant 67

您只能从中提取此信息system_clock::time_point.这是唯一一个与民用日历有关系的系统提供的时钟.以下是如何使用此时钟获取当前time_point:

 system_clock::time_point now = system_clock::now();
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其转换为time_t:

time_t tt = system_clock::to_time_t(now);
Run Code Online (Sandbox Code Playgroud)

使用C库,您可以将a转换time_t为a tm,但您必须选择是要在UTC时区或本地时区中进行转换:

tm utc_tm = *gmtime(&tt);
tm local_tm = *localtime(&tt);
Run Code Online (Sandbox Code Playgroud)

然后你可以打印出tm的组件,例如:

std::cout << local_tm.tm_year + 1900 << '\n';
std::cout << local_tm.tm_mon + 1 << '\n';
std::cout << local_tm.tm_mday << '\n';
Run Code Online (Sandbox Code Playgroud)

另外

如果您愿意,您可以利用这些无保证的信息:

system_clock我所知道的每个实现都基于unix时间.即自1970年UTC新世纪以来的秒数,忽略了闰秒.而且这个计数的精度通常比秒更精细.这是一个完整的程序,它提取所有这些信息:

#include <chrono>
#include <ctime>
#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    typedef duration<int, ratio_multiply<hours::period, ratio<24> >::type> days;
    system_clock::time_point now = system_clock::now();
    system_clock::duration tp = now.time_since_epoch();
    days d = duration_cast<days>(tp);
    tp -= d;
    hours h = duration_cast<hours>(tp);
    tp -= h;
    minutes m = duration_cast<minutes>(tp);
    tp -= m;
    seconds s = duration_cast<seconds>(tp);
    tp -= s;
    std::cout << d.count() << "d " << h.count() << ':'
              << m.count() << ':' << s.count();
    std::cout << " " << tp.count() << "["
              << system_clock::duration::period::num << '/'
              << system_clock::duration::period::den << "]\n";

    time_t tt = system_clock::to_time_t(now);
    tm utc_tm = *gmtime(&tt);
    tm local_tm = *localtime(&tt);
    std::cout << utc_tm.tm_year + 1900 << '-';
    std::cout << utc_tm.tm_mon + 1 << '-';
    std::cout << utc_tm.tm_mday << ' ';
    std::cout << utc_tm.tm_hour << ':';
    std::cout << utc_tm.tm_min << ':';
    std::cout << utc_tm.tm_sec << '\n';
}
Run Code Online (Sandbox Code Playgroud)

duration为模型日创建自定义非常方便:

typedef duration<int, ratio_multiply<hours::period, ratio<24> >::type> days;
Run Code Online (Sandbox Code Playgroud)

现在,您可以获得自纪元以来的时间,以及能够管理的精确度:

system_clock::duration tp = now.time_since_epoch();
Run Code Online (Sandbox Code Playgroud)

然后将其截断为几天,然后将其减去.

然后将其截断为几小时,然后将其减去.

继续,直到你减去秒数.

你剩下的就是以秒为单位的秒数system_clock::duration.因此,打印出该运行时值和该值的编译时单位,如图所示.

对我来说这个程序打印出来:

15806d 20:31:14 598155[1/1000000]
2013-4-11 20:31:14
Run Code Online (Sandbox Code Playgroud)

我的输出表明system_clock::duration精度是微秒.如果需要,可以使用以下命令将其截断为毫秒:

milliseconds ms = duration_cast<milliseconds>(tp);
Run Code Online (Sandbox Code Playgroud)

更新

这个仅限标头的C++ 11/14库封装了上面的工作,将客户端工作减少到:

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

int
main()
{
    // Reduce verbosity but let you know what is in what namespace
    namespace C = std::chrono;
    namespace D = date;
    namespace S = std;

    auto tp = C::system_clock::now(); // tp is a C::system_clock::time_point
    {
        // Need to reach into namespace date for this streaming operator
        using namespace date;
        S::cout << tp << '\n';
    }
    auto dp = D::floor<D::days>(tp);  // dp is a sys_days, which is a
                                      // type alias for a C::time_point
    auto ymd = D::year_month_day{dp};
    auto time = D::make_time(C::duration_cast<C::milliseconds>(tp-dp));
    S::cout << "year        = " << ymd.year() << '\n';
    S::cout << "month       = " << ymd.month() << '\n';
    S::cout << "day         = " << ymd.day() << '\n';
    S::cout << "hour        = " << time.hours().count() << "h\n";
    S::cout << "minute      = " << time.minutes().count() << "min\n";
    S::cout << "second      = " << time.seconds().count() << "s\n";
    S::cout << "millisecond = " << time.subseconds().count() << "ms\n";
}
Run Code Online (Sandbox Code Playgroud)

这只是输出给我:

2015-07-10 20:10:36.023017
year        = 2015
month       = Jul
day         = 10
hour        = 20h
minute      = 10min
second      = 36s
millisecond = 23ms
Run Code Online (Sandbox Code Playgroud)

  • @BitTickler:`decltype(std :: chrono :: system_clock :: now())`是`std :: chrono :: system_clock :: time_point`,而不是`system_clock :: duration`.如果您想了解`<chrono>`库,我可以提供帮助.如果你只是想咆哮,请教育自己足够咆哮事实. (4认同)
  • Fwiw,周末我在上面的评论中提到了这个:http://home.roadrunner.com/~hinnant/date_algorithms.html这不是一个约会提案.但它可能有助于其他人创建日期提案. (3认同)
  • 日期库在此处作为 GitHub 存储库发布:https://github.com/HowardHinnant/date (2认同)
  • tm local_tm = * localtime(&tt);通常不是线程安全的(尽管在Windows中) (2认同)
  • @BitTickler:很高兴我能帮助你摆脱困境。现在感觉好些了吗? (2认同)
  • 通常人们会通过 Stack Overflow Question 来提出详细的问题。评论部分没有留下足够的空间或格式灵活性来提高问题/答案的效率。不过,我可以推荐基本的 C++11 chrono 教程:https://www.youtube.com/watch?v=P32hvk8b13M 以及新的 C++20 chrono 设施的视图:https://www.youtube.com /watch?v=adSAN282YIw (2认同)