Я получаю человеческие читаемые временные метки в свою программу. Я хочу хранить их в базе данных и работать с ними по-разному. Я бы предпочел представить их как долгое время, поскольку это проще и эффективнее, но это также удобно, когда вы можете переключаться между тем, что удобно для читаемой машины и что полезно для человека.Преобразование человекочитаемых дат в миллисекунды и обратно без потери информации
Я взломал следующую тестовую программу, включающую функции, которые можно преобразовать в человеческие читаемые временные метки и обратно, и обратно.
// g++ -o timetest timetest.cpp -std=c++11
#include <iostream>
#include <sstream>
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
long millis_from_date(const std::string& s)
{
boost::posix_time::ptime pt;
std::istringstream is(s);
auto* f = new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%S.%FZ");
std::locale loc(std::locale(""), f);
is.imbue(loc);
is >> pt;
boost::posix_time::ptime timet_start(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration diff = pt - timet_start;
return diff.total_milliseconds();
}
std::string date_from_millis(long ms)
{
static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%Y-%m-%dT%H:%M:%S.%fZ");
std::ostringstream stream;
stream.imbue(std::locale(stream.getloc(), facet));
stream << epoch + boost::posix_time::milliseconds(ms);;
return stream.str();
}
int main()
{
std::string time = "2016-04-14T07:47:50.120043Z";
std::cout << "Initial input: " << time << std::endl;
std::cout << std::endl;
{
long millis = millis_from_date(time);
std::cout << "Initial input in millis: " << millis << std::endl;
std::string newtime = date_from_millis(millis);
std::cout << "Converted back to date: " << newtime << std::endl;
}
{
long millis = millis_from_date(time);
std::cout << "Initial input in millis: " << millis << std::endl;
std::string newtime = date_from_millis(millis);
std::cout << "Converted back to date: " << newtime << std::endl;
}
return 0;
}
Вот пример вывода.
Initial input: 2016-04-14T07:47:50.120043Z
Initial input in millis: 1460620070000
Converted back to date: 2016-04-14T07:47:50.000000Z
Initial input in millis: 1460620070000
Converted back to date: 2016-04-14T07:47:50.000000Z
Как вы можете видеть, при преобразовании в миллисекунды, дробно вторая информация теряется, так что вы получите секунды, так как начало эпохи с 000
прикрепили на конце. Таким образом, при преобразовании полученного длинного назад в человекообразную метку времени теряется дробная вторая информация.
Я уже пробовал немало вещей, и я не могу понять, как должна работать функция millis_from_date, не теряя дробную вторую информацию. Есть идеи??
Спасибо Михаил, я последовал вашему советовать и теперь все работает точно так же, как это должно быть. – user6247858
@ user6247858 Добро пожаловать! – Mikhail