std::chrono::time_point from std::string
std::chrono::time_point from std::string
我正在尝试将日期(以std::string
的形式(转换为std::chrono::time_point
。为此,我使用提升日期时间。 下面,您可以找到一个执行此操作的最小工作示例。 但是,我不明白为什么某些在我看来无效的输入字符串似乎没有以某种方式引发异常。 我不知道这里发生了什么。
#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 的免费开源日期/时间库时代码的外观:
#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
我在向量的末尾添加了一个有效的字符串/日期,以显示它使用此format
接受的内容。1970-03-01 00:00:00.0...
上的尾随零数将根据平台std::chrono::system_clock::time_point
的精度而有所不同。
此外,此代码应该很容易移植到 C++20:
- 放下
#include "date/date.h"
. - 掉落
using date::operator<<;
- 将
date::parse
更改为std::chrono::parse
。
更新
为了帮助您解释结果,请执行以下操作:
- 1514764800s 之后 1970-01-01 00:00:00 是 2018-01-01 00:00:00 23587200s 在 1970-01-01 00:00:00
- 之后是 1970-10-01 00:00:00
(都忽略了闰秒,这是常态(
你没有解释你的期望和原因,所以我只是描述你的程序是做什么的。
使用"19700101"和"19700103",它解析"1970"跳过一个字符,解析"10"跳过一个字符并找到字符串的结尾,因此它得出结论,两者都是1970年10月的第一个。
使用"19700301"它解析"1970"跳过一个字符解析"30"并抛出,因为第 30 个月是无稽之谈。
此外,您的输出描述有拼写错误,您抛出"无法解析日期"而不是"无法解析字符串"。
相关文章:
- std::async from std::async in windows xp
- std::is_reference from std::any
- std::time_point from and to std::string
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- std::chrono::time_point from std::string
- Visual accept std::string from std::byte iterator
- from std::vector to adept::avector
- std::chrono 在从 main 或 from 类方法使用时给出不同的值
- std::remove, std::move(range) and moved-from elements
- 将 2D 数组插入 std::vector 时"cannot convert from 'const GLfloat [12]' to '_Objty'"错误消息
- get radix from std::stoi
- 返回"Cannot convert from 'std::ofstream {aka std::basic_ofstream<char>}' to bool"错误
- std::get from teplate argument
- reinterpret_cast std::function* to and from void*
- cvc4 mkconst from std::string in C++ api
- 为什么我的"choose k from n"算法适用于 std::vector,而不适用于 std::map?
- 我收到一个" conversion from ‘std::string (*)[50]’ to non-scalar type ‘std::string’ requested"错误,似乎无法修复它
- std::none_of example from cppreference.com
- "cannot convert argument 1 from 'Node<T>' to 'std::nullptr_t"编译器错误
- Create Eigen::Ref from std::vector