Как преобразовать метку времени дробной эпохи (двойную) в точку std::chrono::time_point?
У меня есть отметка времени дробной эпохи, представленная как double
, что я хотел бы преобразовать в соответствующий std::chrono::time_point
, Эпоха - обычная эпоха UNIX с 1 января 1970 года. Я знаю что существует std::chrono::system_clock::from_time_t
, но time_t
не имеет дробной части. Что было бы лучшим способом сделать это с помощью C++11?
Этот вопрос связан с отметкой времени unix для boost:: posix_time:: ptime, за исключением того, что он запрашивает C++11, а не Boost-версию.
1 ответ
Предполагая, что эпоха совпадает с известной clock
типа вы можете использовать продолжительность с double
представление и преобразовать в продолжительность, используемую этими часами.
// change period to appropriate units - I'm assuming seconds
typedef std::chrono::duration<double, std::ratio<1>> d_seconds;
d_seconds since_epoch_full(324324.342);
auto since_epoch = std::chrono::duration_cast<clock::duration>(since_epoch_full);
clock::time_point point(since_epoch);
Это должно быть приемлемо для любых вычислений, связанных с этими часами, поскольку вы используете ту же точность, что и часы, но они могут потерять часть точности при преобразовании. Если вы не хотите терять, вам придется использовать time_point
специализация, которая использует это double
тип продолжительности. И затем используйте это в своих вычислениях (конечно, со всеми предостережениями математики с плавающей точкой).
typedef std::chrono::time_point<clock, d_seconds> d_time_point;
Однако это усложнит любые вычисления с использованием тех же часов, так как потребует преобразований. Чтобы сделать это проще, вы можете создать свою собственную оболочку часов, которая выполняет преобразования, и использовать это:
template <typename Clock>
struct my_clock_with_doubles {
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock_with_doubles<Clock>> time_point;
static const bool is_steady = Clock::is_steady;
static time_point now() noexcept {
return time_point(std::chrono::duration_cast<duration>(
Clock::now().time_since_epoch()
));
}
static time_t to_time_t(const time_point& t) noexcept {
return Clock::to_time_t(typename Clock::time_point(
std::chrono::duration_cast<typename Clock::duration>(
t.time_since_epoch()
)
));
}
static time_point from_time_t(time_t t) noexcept {
return time_point(std::chrono::duration_cast<duration>(
Clock::from_time_t(t).time_since_epoch()
));
}
};