web-dev-qa-db-ja.com

C ++ 11 time_pointをどのように印刷しますか?

時点を作成しましたが、それを端末に出力するのに苦労しています。

#include <iostream>
#include <chrono>

int main(){

    //set time_point to current time
    std::chrono::time_point<std::chrono::system_clock,std::chrono::nanoseconds> time_point;
    time_point = std::chrono::system_clock::now();

    //print the time
    //...

    return 0;
}

Time_pointを出力するドキュメントは、次の場所にあります。 http://en.cppreference.com/w/cpp/chrono/time_point

ただし、(例のように)time_pointに基づいてtime_tを作成することさえできません。

std::time_t now_c = std::chrono::system_clock::to_time_t(time_point); //does not compile

エラー:

/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono: In instantiation of ‘constexpr std::chrono::time_point<_Clock, _Dur>::time_point(const std::chrono::time_point<_Clock, _Dur2>&) [with _Dur2 = std::chrono::duration<long int, std::ratio<1l, 1000000000l> >; _Clock = std::chrono::system_clock; _Dur = std::chrono::duration<long int, std::ratio<1l, 1000000l> >]’:
time.cpp:13:69:   required from here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:540:32: error: no matching function for call to ‘std::chrono::duration<long int, std::ratio<1l, 1000000l> >::duration(std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >::duration)’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:540:32: note: candidates are:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:247:14: note: template<class _Rep2, class _Period2, class> constexpr std::chrono::duration::duration(const std::chrono::duration<_Rep2, _Period2>&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:247:14: note:   template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:243:46: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:240:23: note: template<class _Rep2, class> constexpr std::chrono::duration::duration(const _Rep2&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:240:23: note:   template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:236:27: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:234:12: note: constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep = long int; _Period = std::ratio<1l, 1000000l>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:234:12: note:   no known conversion for argument 1 from ‘std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >::duration {aka std::chrono::duration<long int, std::ratio<1l, 1000000000l> >}’ to ‘const std::chrono::duration<long int, std::ratio<1l, 1000000l> >&’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:232:12: note: constexpr std::chrono::duration<_Rep, _Period>::duration() [with _Rep = long int; _Period = std::ratio<1l, 1000000l>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:232:12: note:   candidate expects 0 arguments, 1 provided
51
Trevor Hickey

(この投稿では、わかりやすくするためにstd::chrono::資格を省略します。どこに行くか知っていると信じています。)

コード例のコンパイルに失敗する理由は、system_clock::now()の戻り値の型と、これを割り当てようとしている変数の型(time_point<system_clock, nanoseconds>)の間に不一致があるためです。

system_clock::now()の文書化された戻り値はsystem_clock::time_pointであり、これはtime_point<system_clock, system_clock::duration>のtypedefです。 system_clock::durationは実装定義であり、microsecondsnanosecondsが一般的に使用されます。実装ではmicrosecondsを使用しているため、system_clock::now()の戻り値の型はtime_point<system_clock, microseconds>です。

time_pointsの期間が異なると、暗黙的に相互に変換できないため、コンパイラエラーが発生します。

time_point_castを使用して、異なる期間の時刻ポイントを明示的に変換できるため、次のコードがシステムでコンパイルされます。

time_point<system_clock, nanoseconds> time_point;
time_point = time_point_cast<nanoseconds>(system_clock::now());

time_point_castの明示的なテンプレートパラメータは、ターゲットのtime_pointタイプではなく、ターゲットdurationタイプであることに注意してください。クロックタイプはtime_point_castで一致する必要があるため、time_pointタイプ全体(クロックタイプと期間タイプの両方にテンプレート化されています)を指定することは冗長です。

もちろん、あなたの場合、あなたはただタイムポイントを印刷しようとしているので、それが特定の解像度である必要はないので、time_pointをwhat system_clock::now()は最初から戻ります。これを行う簡単な方法は、system_clock::time_point typedefを使用することです。

system_clock::time_point time_point;
time_point = system_clock::now();  // no time_point_cast needed

これはC++ 11なので、autoを使用することもできます。

auto time_point = system_clock::now(); 

このコンパイラエラーを解決すると、time_tへの変換は問題なく動作します。

std::time_t now_c = std::chrono::system_clock::to_time_t(time_point);

time_tstd::ctimeなどのstd::strftime値を表示する標準的な方法を使用できるようになりました。 (Cassio Neriがあなたの質問へのコメントで指摘しているように、GCCはまだC++-y std::put_time関数をサポートしていません)。

50
HighCommander4

このスニペットはあなたを助けるかもしれません:

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

template<typename Clock, typename Duration>
std::ostream &operator<<(std::ostream &stream,
  const std::chrono::time_point<Clock, Duration> &time_point) {
  const time_t time = Clock::to_time_t(time_point);
#if __GNUC__ > 4 || \
    ((__GNUC__ == 4) && __GNUC_MINOR__ > 8 && __GNUC_REVISION__ > 1)
  // Maybe the put_time will be implemented later?
  struct tm tm;
  localtime_r(&time, &tm);
  return stream << std::put_time(&tm, "%c"); // Print standard date&time
#else
  char buffer[26];
  ctime_r(&time, buffer);
  buffer[24] = '\0';  // Removes the newline that is added
  return stream << buffer;
#endif
}

int main() {
  std::cout << std::chrono::system_clock::now() << std::endl;
  // Wed May 22 14:17:03 2013
}
15
Matt Clarkson

古い質問の回答を更新しました:

のために std::chrono::time_point<std::chrono::system_clock, some-duration>現在、より優れた制御を可能にするサードパーティのライブラリがあります。他のクロックに基づくtime_pointsの場合、内部表現を取得して印刷するよりも優れたソリューションはまだありません。

しかし、system_clockこのライブラリ を使用すると、次のように簡単になります。

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

int
main()
{
    using namespace date;
    using namespace std::chrono;
    std::cout << system_clock::now() << " UTC\n";
}

私のためにちょうど出力されます:

2016-07-19 03:21:01.910626 UTC

これは現在のUTC日時で、マイクロ秒の精度です。プラットフォームの場合system_clock::time_pointにはナノ秒の精度があり、ナノ秒の精度が出力されます。

12
Howard Hinnant

nanosecondsは問題の一部のようです。ドキュメントを見て、これを機能させることができました。

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


int main(){

    //set time_point to current time
    std::chrono::time_point<std::chrono::system_clock> time_point;
    time_point = std::chrono::system_clock::now();

    std::time_t ttp = std::chrono::system_clock::to_time_t(time_point);
    std::cout << "time: " << std::ctime(&ttp);

    return 0;
}

std::chrono::microsecondsうまくいく:

std::chrono::time_point<std::chrono::system_clock,std::chrono::microseconds> time_point;
11
Shafik Yaghmour

time_point<steady_clock>time_point<system_clock>ではなく)を使用するユーザーの場合:

#include <chrono>
#include <iostream>

template<std::intmax_t resolution>
std::ostream &operator<<(
    std::ostream &stream,
    const std::chrono::duration<
        std::intmax_t,
        std::ratio<std::intmax_t(1), resolution>
    > &duration)
{
    const std::intmax_t ticks = duration.count();
    stream << (ticks / resolution) << '.';
    std::intmax_t div = resolution;
    std::intmax_t frac = ticks;
    for (;;) {
        frac %= div;
        if (frac == 0) break;
        div /= 10;
        stream << frac / div;
    }
    return stream;
}

template<typename Clock, typename Duration>
std::ostream &operator<<(
    std::ostream &stream,
    const std::chrono::time_point<Clock, Duration> &timepoint)
{
    typename Duration::duration ago = timepoint.time_since_Epoch();
    return stream << ago;
}

int main(){
    // print time_point
    std::chrono::time_point<std::chrono::steady_clock> now =
        std::chrono::steady_clock::now();
    std::cout << now << "\n";

    // print duration (such as the difference between 2 time_points)
    std::chrono::steady_clock::duration age = now - now;
    std::cout << age << "\n";
}

10進数フォーマッターは最も効率的ではありませんが、resolutionをテンプレート化する場合は、ceil(log10(resolution))の定数式を考え出さない限り、小数の数を事前に知る必要はありません。

2
user2394284

Ctime()はVisual C++では機能しません。私はMS Visual Studio 2013を使用します。MSVCコンパイラのプロンプトに従って、上記のコードを変更してctime_s(...)を使用します。動いた。

//set time_point to current time
std::chrono::time_point<std::chrono::system_clock> time_point;
time_point = std::chrono::system_clock::now();

std::time_t ttp = std::chrono::system_clock::to_time_t(time_point);
char chr[50];
errno_t e = ctime_s(chr, 50, &ttp);
if (e) std::cout << "Error." << std::endl;
else std::cout << chr << std::endl;
1
Longbow