使用std::chrono将32位Unix时间戳转换为std :: string

8
我将尝试使用std::chrono来创建一个std::string,但是遇到了问题。
以下是我想要模仿的 C(-ish) 代码:
std::uint32_t time_date_stamp = 1484693089;
char date[100];
struct tm *t = gmtime(reinterpret_cast<const time_t*>(&time_date_stamp));
strftime(date, sizeof(date), "%Y-%m-%d %I:%M:%S %p", t);

我的起点始终是这个std::uint32_t,它来自于一个我无法控制数据格式。

很抱歉,我没有任何C++的起点,甚至不知道如何正确创建一个std::chrono::time_point


1
我认为你最好使用strftime,因为将std::chrono转换为time_t是通常的字符串化方式。 - Slava
OP可以使用std::put_time - jaggedSpire
1
一个非常紧密的话题:使用std :: chrono在C ++中输出日期和时间 还链接到Howard Hinnant的... 呃...他刚刚发布了一个答案,是吗? - user4581301
2个回答

8

这里有一种简单的方法,可以不用降到C语言的tm级别,而是使用这个便携式的C++11/14免费、开源、仅包含头文件的库

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

int
main()
{
    std::uint32_t time_date_stamp = 1484693089;
    date::sys_seconds tp{std::chrono::seconds{time_date_stamp}};
    std::string s = date::format("%Y-%m-%d %I:%M:%S %p", tp);
    std::cout << s << '\n';
}

这会输出:
2017-01-17 10:44:49 PM

这与古老的C函数gmtime相关的线程安全问题不同。

date::sys_secondsstd::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>的一个typedef


我担心只有头文件的库date.h有8000行,它包含了大约22个其他头文件(标准c++东西,但是...) - Mikolasan
当您的供应商提供完整的C++20时,date.h可以被<chrono>替换,sys_seconds将在命名空间std::chrono中,而format将在命名空间std中。 - Howard Hinnant

7

<chrono>不是一个用于将日期时间格式化为字符串的库。它通常用于将不同的时间表示(毫秒到天等)转换,将时间戳相加等。

标准库中唯一的日期时间格式化函数是从C标准库继承而来的,包括您已在“C-ish”版本中使用的std::strftime。编辑:正如jaggedSpire指出的那样,C++11引入了std::put_time。它提供了一种方便的方式来流式传输格式化的日期,使用与C函数相同的API。

由于std::gmtime(如果您要使用std::localtime)将其参数作为unix时间戳进行处理,因此您不需要使用<chrono>来转换时间。它已经处于正确的表示形式。只有底层类型必须从std::uint32_t转换为std::time_t。这在您的C版本中无法实现可移植性。

使用基于std::put_time的格式化的一个可移植的方法来转换时间戳:

std::uint32_t time_date_stamp = 1484693089;
std::time_t temp = time_date_stamp;
std::tm* t = std::gmtime(&temp);
std::stringstream ss; // or if you're going to print, just input directly into the output stream
ss << std::put_time(t, "%Y-%m-%d %I:%M:%S %p");
std::string output = ss.str();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接