gpt4 book ai didi

c++ - 来自 std::string 的 std::chrono::time_point

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:28 27 4
gpt4 key购买 nike

我正在尝试将日期(以 std::string 的形式)转换为 std::chrono::time_point。为此,我使用了 Boost Date Time。下面,您可以找到一个最小的工作示例。但是,我不明白为什么某些在我看来无效的输入字符串似乎不会以某种方式引发异常。我不知道这里发生了什么。

#include <iostream>
#include <chrono>
#include <sstream>
#include <boost/date_time.hpp>

using Clock = std::chrono::system_clock;
using TimePoint = std::chrono::time_point<Clock>;

TimePoint timePointFromString(const std::string& date, const std::string& format) {
// local takes care of destructing time_input_facet
auto loc = std::locale(std::locale::classic(), new boost::posix_time::time_input_facet(format));

std::stringstream ss{date};
ss.imbue(loc);

boost::posix_time::ptime pt;
ss >> pt;

if (!ss.good()) {
throw std::runtime_error("Cannot parse string");
}

boost::posix_time::ptime time_t_epoch{boost::gregorian::date(1970, 1, 1)};
boost::posix_time::time_duration diff = pt - time_t_epoch;

Clock::duration duration{diff.total_nanoseconds()};

return TimePoint{duration};
}

int main() {
std::string format{"%Y-%m-%d"};

std::vector<std::string> strings {"2018", "2018-", "19700101", "19700103", "19700301"};
for (const auto& s: strings) {
auto tp = timePointFromString(s, format);
std::cout << s << ": " << TimePoint::clock::to_time_t(tp) << std::endl;
}
}

输出:

2018: 1514764800
2018-: 1514764800
19700101: 23587200
19700103: 23587200
terminate called after throwing an instance of 'std::runtime_error'
what(): Cannot parse string

更新:我误解了这段代码,认为它会进行某种模式匹配。事实并非如此(请参阅 Öö Tiib 的回答和他的回答下方的评论)!显然,最好使用 Howard Hinnant 的 date/time图书馆。

最佳答案

如果您使用 Howard Hinnant's free, open-source date/time library,您的代码将是这样的:

#include "date/date.h"
#include <chrono>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

std::chrono::system_clock::time_point
timePointFromString(const std::string& date, const std::string& format)
{
std::stringstream ss{date};
std::chrono::system_clock::time_point pt;
ss >> date::parse(format, pt);
if (ss.fail())
throw std::runtime_error("Cannot parse date");
return pt;
}

int
main()
{
std::string format{"%Y-%m-%d"};
std::vector<std::string> strings{"2018", "2018-", "19700101", "19700103", "19700301",
"1970-03-01"};
for (const auto& s: strings)
{
try
{
auto tp = timePointFromString(s, format);
using date::operator<<;
std::cout << s << ": " << tp << '\n';
}
catch (std::exception const& e)
{
std::cout << s << ": " << e.what() << '\n';
}
}
}

输出将是:

2018: Cannot parse date
2018-: Cannot parse date
19700101: Cannot parse date
19700103: Cannot parse date
19700301: Cannot parse date
1970-03-01: 1970-03-01 00:00:00.000000

我在 vector 的末尾添加了一个有效的字符串/日期,以显示它使用这个 format 接受的内容.以及 1970-03-01 00:00:00.0... 上尾随零的数量将根据您平台的 std::chrono::system_clock::time_point 的精度而有所不同.

此外,这段代码应该很容易移植到 C++20:

  • 放下#include "date/date.h" .
  • 放下using date::operator<<;
  • 更改 date::parsestd::chrono::parse .

更新

帮助您解释结果:

  • 1970-01-01 00:00:00 之后的 1514764800s 是 2018-01-01 00:00:00
  • 1970-01-01 00:00:00 之后的 23587200s 是 1970-10-01 00:00:00

(忽略闰秒,这是常态)

关于c++ - 来自 std::string 的 std::chrono::time_point,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52175032/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com