Я пытаюсь преобразовать дату (в виде 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 и комментарии под его ответом)! По-видимому, лучше всего использовать библиотеку даты / времени Говарда Хиннанта.