簡體   English   中英

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

[英]Extract year/month/day etc. from std::chrono::time_point in C++

如何從std::chrono::time_point對象中提取年,月,日,小時,分鍾,秒和毫秒

我只看到了如何從duration提取例如秒的總量的示例。

您只能從system_clock::time_point提取此信息。 這是唯一一個與民用日歷有關系的系統提供的時鍾。 以下是如何使用此時鍾獲取當前time_point:

 system_clock::time_point now = system_clock::now();

然后,您可以將其轉換為time_t

time_t tt = system_clock::to_time_t(now);

使用C庫,您可以將time_t轉換為tm ,但您必須選擇是要在UTC時區中進行轉換,還是在本地時區:

tm utc_tm = *gmtime(&tt);
tm local_tm = *localtime(&tt);

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

std::cout << local_tm.tm_year + 1900 << '\n';
std::cout << local_tm.tm_mon + 1 << '\n';
std::cout << local_tm.tm_mday << '\n';

另外

如果您願意,您可以利用這些無保證的信息:

我所知道的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';
}

為模型日創建自定義duration非常方便:

typedef duration<int, ratio_multiply<hours::period, ratio<24> >::type> days;

現在,您可以獲得自紀元以來的時間,以及可以管理的精確度:

system_clock::duration tp = now.time_since_epoch();

然后將其截斷為幾天,然后將其減去。

然后將其截斷為幾小時,然后將其減去。

繼續,直到你減去秒數。

你剩下的就是以system_clock::duration為單位的system_clock::duration 因此,打印出該運行時值和該值的編譯時單位,如圖所示。

對我來說這個程序打印出來:

15806d 20:31:14 598155[1/1000000]
2013-4-11 20:31:14

我的輸出表明system_clock::duration精度是微秒。 如果需要,可以使用以下命令將其截斷為毫秒:

milliseconds ms = duration_cast<milliseconds>(tp);

更新

這個僅限標頭的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";
}

這只是輸出給我:

2015-07-10 20:10:36.023017
year        = 2015
month       = Jul
day         = 10
hour        = 20h
minute      = 10min
second      = 36s
millisecond = 23ms

另一個更新

這個庫已經發展成為C ++標准提案,現在已經在C ++ 20工作草案中了。 從C ++ 20中的system_clock::time_point中提取這些字段的語法將是:

#include <chrono>

int
main()
{
    using namespace std::chrono;
    auto tp = system_clock::now();
    auto dp = floor<days>(tp);
    year_month_day ymd{dp};
    hh_mm_ss time{floor<milliseconds>(tp-dp)};
    auto y = ymd.year();
    auto m = ymd.month();
    auto d = ymd.day();
    auto h = time.hours();
    auto M = time.minutes();
    auto s = time.seconds();
    auto ms = time.subseconds();
}

以上假設您希望這些字段為UTC。 如果您在其他時區喜歡它們,那也是可能的。 例如,以下是如何在計算機的當前本地時區執行此操作:

#include <chrono>

int
main()
{
    using namespace std::chrono;
    auto tp = zoned_time{current_zone(), system_clock::now()}.get_local_time();
    auto dp = floor<days>(tp);
    year_month_day ymd{dp};
    hh_mm_ss time{floor<milliseconds>(tp-dp)};
    auto y = ymd.year();
    auto m = ymd.month();
    auto d = ymd.day();
    auto h = time.hours();
    auto M = time.minutes();
    auto s = time.seconds();
    auto ms = time.subseconds();
}

上面唯一的區別是構造tp ,它現在具有類型local_time而不是UTC示例中的sys_time 或者,可以通過這個小變化選擇一個任意時區:

auto tp = zoned_time{"Europe/London", system_clock::now()}.get_local_time();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM