2013-04-11 10 views
32

Jak mogę wyodrębnić rok, miesiąc, dzień, godzinę, minutę, sekundę i milisekundę z obiektu std::chrono::time_point?Wyodrębnij rok/miesiąc/dzień itd. Ze std :: chrono :: time_point w C++

Widziałem tylko przykłady jak wyodrębnić całkowitą ilość np. sekund od duration.

+0

możliwy duplikat [Ho w, aby przekonwertować std :: chrono :: time \ _point na kalendarz datetime string z ułamkowymi sekundami?] (http://stackoverflow.com/questions/12835577/how-to-convert-stdchronotime-point-to-calendar-datetime- string-with-fraction) – Ali

Odpowiedz

48

Możesz wyodrębnić te informacje tylko z system_clock::time_point. Jest to jedyny zegar dostarczany przez system, który ma związek z kalendarzem cywilnym. Oto w jaki sposób uzyskać aktualny time_point za pomocą tego zegara:

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

Następnie można przekonwertować to do time_t z:

time_t tt = system_clock::to_time_t(now); 

Korzystanie z biblioteki C można następnie przekonwertować time_t Do tm, ale trzeba wybrać, czy chcesz, że nawrócenie się wydarzyć w strefie czasowej UTC, albo lokalna strefa czasowa:

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

Wtedy c wydruk składników tm, na przykład:

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

Dodatkowo

Jeśli chcesz, możesz skorzystać z tego niegwarantowanymi informacji:

każdego wdrożenia system_clock I Jestem świadomy, że jest oparty na unix time. To znaczy. liczba sekund od czasu UTC w Nowym Roku 1970, pomijając sekundy przestępne. Dokładność tej liczby jest zwykle większa niż sekund. Oto kompletny program, który wydobywa się z treścią informacji:

#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'; 
} 

Jest przydatny do tworzenia niestandardowych duration modelować dni:

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

Teraz można uzyskać czas od epoki, jako dokładność precyzyjnie, jak to możliwe, z:

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

Następnie przyciąć do dni i odejmij to.

Następnie przyciąć do godzin i odjąć od tego.

Kontynuuj, dopóki nie odejmiesz od sekund.

To, co pozostało, to ułamek sekundy z jednostkami system_clock::duration. Wydrukuj więc tę wartość czasu działania i jednostki czasu kompilacji o tej wartości, jak pokazano.

Dla mnie ten program wypisuje:

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

moje wyjście wskazuje precyzja system_clock::duration jest mikrosekund.W razie potrzeby, które mogą być obcinane do milisekund z:

milliseconds ms = duration_cast<milliseconds>(tp); 

Aktualizacji

This header-only C++11/14 library obudowuje pracę powyżej, redukując pracę klienta w dół do:

#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"; 
} 

który właśnie wyjście dla mnie:

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

Problem z 'tm' polega na tym, że nie ma dokładności milisekund, co jest czymś, czego potrzebuję. – bytecode77

+0

@ Devils Child: W takim przypadku możesz przekonwertować wynikowy time_t z powrotem na system_clock :: time_point, używając 'from_time_t'. A następnie odejmij dwa. Powinieneś uzyskać czas trwania, który zawiera ułamkowe sekundy, którymi możesz dalej manipulować. –

+0

Dzięki. Pójdę z twoim rozwiązaniem :) – bytecode77

Powiązane problemy