使用std :: chrono在C++中输出日期和时间

con*_*ref 61 c++ time date c++11 c++-chrono

我一直在升级一些旧代码,并且尽可能地尝试更新到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;
}
Run Code Online (Sandbox Code Playgroud)

我想使用std :: chrono(或类似的)以类似的格式输出当前时间和日期,但我不确定如何这样做.任何帮助将不胜感激.谢谢

bam*_*s53 87

<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();
}
Run Code Online (Sandbox Code Playgroud)

请注意,std::localtime可能会导致数据争用.localtime_r或类似的功能可能在您的平台上可用.

更新:

使用新版本的Howard Hinnant的日期库,您可以写:

#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();
}
Run Code Online (Sandbox Code Playgroud)

这将打印出类似"2015-07-24 05:15:34.043473124 UTC"的内容.


在一个不相关的说明中,const使用C++ 11 返回对象已经变得不可取; const返回值无法移动.我还删除了尾随const,因为尾随const仅对成员函数有效,并且此函数不需要是成员.

  • 请注意,一些旧的编译器可能无法识别`std :: put_time`.一旦我尝试使用g ++编译我在CentOS 7上使用`std :: put_time`的代码,它就失败了.GCC中`std :: put_time`支持的状态http://stackoverflow.com/q/14136833/4694036 (8认同)
  • 如果您不使用 `using namespace date;`,则 `&lt;&lt; today` 将不起作用。 (3认同)

Bjö*_*din 49

这是一个 C++20 解决方案:

#include <chrono>
#include <format>

std::string get_current_time_and_date()
{
    auto const time = std::chrono::current_zone()
        ->to_local(std::chrono::system_clock::now());
    return std::format("{:%Y-%m-%d %X}", time);
}
Run Code Online (Sandbox Code Playgroud)

std::chrono::time_zone::to_local将系统时钟时间点 ( std::chrono::time_point<std::chrono::system_clock, TDuration>) 转换为本地时间点 ( std::chrono::local_time<TDuration>)。然后可以使用std::format类似于 的格式化选项来格式化该本地时间点strftime

目前,只有 MSVC 实现了std::format. chrono 的日历和时区添加目前“部分”由 Clang 和 GCC 实现,但请在此处查看更新状态: https: //en.cppreference.com/w/cpp/compiler_support。有关该chrono库的更多信息,请阅读此处: https: //en.cppreference.com/w/cpp/chrono


Jay*_*llo 8

一个例子:

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

}
Run Code Online (Sandbox Code Playgroud)

输出如下:

在此处输入图片说明

  • Downvote:当前答案返回一个 30 个字符的长字符串,末尾有很多空字符。如果您尝试将某些内容连接到它,它将不起作用。我确实建议进行编辑以使其工作,但它被 Django 程序员拒绝了...... (11认同)
  • 线程不安全请参阅[数据竞争](http://www.cplusplus.com/reference/ctime/localtime/) (3认同)

rod*_*olk 6

为了获得毫秒,我使用 chrono 和 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;
}
Run Code Online (Sandbox Code Playgroud)

格式:http : //www.cplusplus.com/reference/ctime/strftime/


Gan*_*ang 6

fmt 库具有格式化结构的能力tm:它与 strftime 具有相同的规范。

#include <ctime>
#include <fmt/chrono.h>

std::string current_datetime(void)
{
  std::time_t tt = std::time(nullptr);
  std::tm *tm = std::localtime(&tt);
  return fmt::format("{:%Y%m%d}", *tm);
}
Run Code Online (Sandbox Code Playgroud)


Yan*_*niv 5

bames53 解决方案很好,但不能在我的 VS2017 上编译。使用 ctime 的解决方案无法编译,因为 localtime 非常不推荐使用。带有 date.h 的那个不能用当前的 date.h 编译,尽管文档说他们应该删除 github,但我刚刚删除了 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
Run Code Online (Sandbox Code Playgroud)

随意修复 bames53 解决方案并删除我的。我的文字不适合评论。我相信它可以使许多人免于悲伤。