web-dev-qa-db-ja.com

std :: chronoを使用してC ++で日付と時刻を出力する

古いコードをいくつかアップグレードしており、可能な場合はc ++ 11に更新しようとしています。次のコードは、プログラムで時刻と日付を表示する方法です

#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>

const std::string return_current_time_and_date() const
{
    time_t now = time(0);
    struct tm tstruct;
    char buf[80];
    tstruct = *localtime(&now);
    strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
    return buf;
}

Std :: chrono(またはsimilar)を使用して同様の形式で現在の時刻と日付を出力したいのですが、どうすればよいのかわかりません。どんな助けも大歓迎です。ありがとう

56
const_ref

<chrono>ライブラリは、タイムポイントをsystem_clockに変換する機能を備えたtime_tを除いて、時刻のみを扱い、日付は扱いません。したがって、日付に<chrono>を使用しても、状況はそれほど改善されません。うまくいけば、あまり遠くない将来に chrono::date のようなものが得られます。

ただし、次のように<chrono>を使用できます。

#include <chrono>  // chrono::system_clock
#include <ctime>   // localtime
#include <sstream> // stringstream
#include <iomanip> // put_time
#include <string>  // string

std::string return_current_time_and_date()
{
    auto now = std::chrono::system_clock::now();
    auto in_time_t = std::chrono::system_clock::to_time_t(now);

    std::stringstream ss;
    ss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
    return ss.str();
}

std::localtimeはデータ競合を引き起こす可能性があることに注意してください。 localtime_rまたは同様の機能がプラットフォームで利用できる場合があります。

更新:

ハワードヒナントの新しいバージョン 日付ライブラリ を使用すると、次のように記述できます。

#include "date.h"
#include <chrono>
#include <string>
#include <sstream>

std::string return_current_time_and_date() {
  auto now = std::chrono::system_clock::now();
  auto today = date::floor<days>(now);

  std::stringstream ss;
  ss << today << ' ' << date::make_time(now - today) << " UTC";
  return ss.str();
}

これにより、「2015-07-24 05:15:34.043473124 UTC」のようなものが出力されます。


無関係な注意として、constオブジェクトを返すことはC++ 11では望ましくなくなりました。 const戻り値は移動できません。末尾のconstはメンバー関数に対してのみ有効であり、この関数はメンバーである必要がないため、末尾のconstも削除しました。

85
bames53

例:

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

std::string getTimeStr(){
    std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

    std::string s(30, '\0');
    std::strftime(&s[0], s.size(), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
    return s;
}
int main(){

    std::cout<<getTimeStr()<<std::endl;
    return 0;

}

以下のように出力します。

enter image description here

6
Jayhello

bames53ソリューションは優れていますが、VS2017ではコンパイルしません。 localtimeは非推奨であるため、ctimeを使用したソリューションはコンパイルされません。 date.hのあるものは、現在のdate.hでコンパイルされません。ドキュメントではそうすべきだと言われていますが、今日はそのままではストリーミングできないため、githubを削除しました。私はインクルードを省略しましたが、ここに機能するコードがあります:

void TimeTest()
{
    auto n = std::chrono::system_clock::now();
    auto in_time_t = std::chrono::system_clock::to_time_t(n);
    std::tm buf;
    localtime_s(&buf, &in_time_t);
    std::cout << std::put_time(&buf, "%Y-%m-%d %X") << std::endl;

}

// I just added date.h from this link's guthub to the project.
// https://howardhinnant.github.io/date/date.html
void TimeTest1() {
    auto now = std::chrono::system_clock::now();
    auto today =  floor<date::days>(std::chrono::system_clock::now());
    std::cout << date::year_month_day{ today } << ' ' << date::make_time(now - today) << std::endl;
}

// output is 
// 2018-04-08 21:19:49
// 2018-04-08 18:19:49.8408289

Bames53ソリューションを修正して削除してください。私のテキストはコメントに収まりません。多くの人を悲しみから救うことができると確信しています。

2
Yaniv

また、ミリ秒を取得するために、クロノおよびC関数localtime_rを使用します。これは、スレッドセーフです(std :: localtimeに反して)。

#include <iostream>
#include <chrono>
#include <ctime>
#include <time.h>
#include <iomanip>


int main() {
  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
  std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
  std::chrono::milliseconds now2 = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_Epoch());
  struct tm currentLocalTime;
  localtime_r(&currentTime, &currentLocalTime);
  char timeBuffer[80];
  std::size_t charCount { std::strftime( timeBuffer, 80,
                                         "%D %T",
                                          &currentLocalTime)
                         };

  if (charCount == 0) return -1;

  std::cout << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << std::endl;
  return 0;
}

形式の場合: http://www.cplusplus.com/reference/ctime/strftime/

1
rodolk

文字列ストリーム操作の代わりにBoost lexical_castを使用して、@ bames53からの回答を改善できます。

ここに私がやることがあります:

#include <boost/lexical_cast.hpp>
#include <ctime>

std::string return_current_time_and_date() {
    auto current_time = std::time(0);
    return boost::lexical_cast<std::string>(std::put_time(std::gmtime(& current_time), "%Y-%m-%d %X"));
}
0