我正在尝试使用c ++ 20 std :: chrono替换一些boost :: gregorian代码,希望消除boost构建的缺陷。代码正在读写json(使用nlohmann),因此在std :: string之间来回转换日期的能力至关重要。
在Ubuntu 20.04上使用g ++ 9.3.0。 2个编译时错误,一个在std :: chrono :: parse()上,另一个在std :: put_time()
对于std :: chrono :: parse()上的错误A,我看到here包括chrono :: parse的日历支持(P0355R7)在gcc libstdc ++中尚不可用。有人知道这是正确的还是为此链接到ETA?还是我调用parse()的方式有问题?
对于std :: put_time()的错误B:因为std:put_time()被记录为c ++ 11,所以我感觉这里缺少一些愚蠢的东西。还发现需要通过c的time_t和tm进行隐蔽是很奇怪的。有没有更好的方法可以直接将std :: chrono :: time_point转换为std :: string而不求助于c?
#include <chrono>
#include <string>
#include <sstream>
#include <iostream>
int main(int argc, char *argv[]) {
std::chrono::system_clock::time_point myDate;
//Create time point from string
//Ref: https://en.cppreference.com/w/cpp/chrono/parse
std::stringstream ss;
ss << "2020-05-24";
ss >> std::chrono::parse("%Y-%m-%e", myDate); //error A: ‘parse’ is not a member of ‘std::chrono’
//Write time point to string
//https://en.cppreference.com/w/cpp/io/manip/put_time
//http://cgi.cse.unsw.edu.au/~cs6771/cppreference/en/cpp/chrono/time_point.html
std::string dateString;
std::time_t dateTime = std::chrono::system_clock::to_time_t(myDate);
std::tm tm = *std::localtime(&dateTime);
dateString = std::put_time(&tm, "%Y-%m-%e"); //error B: ‘put_time’ is not a member of ‘std’
//Write out
std::cout << "date: " << dateString << "\n";
return 0;
}
答案 0 :(得分:3)
C ++ 20 <chrono>
仍在为gcc构建。我还没有看到公开的ETA。
您的std::chrono::parse
语法看起来正确。如果您愿意使用free, open-source, header-only preview of C++20 <chrono>
,则可以通过添加#include "date/date.h"
并改为使用date::parse
来使其正常工作。
请注意,生成的myDate
将是2020-05-24 00:00:00 UTC。
std::put_time
位于标头<iomanip>
中,并且是操纵器。添加该标头和<iostream>
后,您将像这样使用它:
std::cout << "date: " << std::put_time(&tm, "%Y-%m-%e") << '\n';
如果需要在std::string
中进行输出,则必须首先将操纵器流式传输到std::stringstream
。
C ++ 20 <chrono>
将提供C API的另一种格式设置:
std::cout << "date: " << std::format("{%Y-%m-%e}", myDate) << '\n';
preview library还为此提供了稍微改变的格式字符串:
std::cout << "date: " << date::format("%Y-%m-%e", myDate) << '\n';