Взаимодействие между boost :: date_time и std :: chrono

Насколько совместимы boost :: date_time и std :: chrono?

Например, есть ли способ конвертировать между boost :: posix_time :: ptime и std :: chrono :: time_point?

Я попытался найти документацию по таким преобразованиям, но не нашел.


person HighCommander4    schedule 05.02.2011    source источник


Ответы (2)


Я нашел это в списке рассылки по усилению коммитов: http://lists.boost.org/boost-commit/2009/04/15209.php

Вот соответствующие функции:

template < class Clock, class Duration> 
struct convert_to<posix_time::ptime, chrono::time_point<Clock, Duration> > { 
    inline static posix_time::ptime apply(const chrono::time_point<Clock, Duration>& from) 
    { 
        typedef chrono::time_point<Clock, Duration> time_point_t; 
        typedef chrono::nanoseconds duration_t; 
        typedef duration_t::rep rep_t; 
        rep_t d = chrono::duration_cast<duration_t>(from.time_since_epoch()).count(); 
        rep_t sec = d/1000000000; 
        rep_t nsec = d%1000000000; 
        return boost::posix_time::from_time_t(0)+ 
        boost::posix_time::seconds(static_cast<long>(sec))+ 
        #ifdef BOOST_DATE_TIME_HAS_NANOSECONDS 
        boost::posix_time::nanoseconds(nsec); 
        #else 
        boost::posix_time::microseconds((nsec+500)/1000); 
        #endif 
    } 
}; 

template < class Clock, class Duration> 
struct convert_to<chrono::time_point<Clock, Duration>, posix_time::ptime> { 
    inline static chrono::time_point<Clock, Duration> apply(const posix_time::ptime& from) 
    { 
        boost::posix_time::time_duration const time_since_epoch=from-boost::posix_time::from_time_t(0); 
        chrono::time_point<Clock, Duration> t=chrono::system_clock::from_time_t(time_since_epoch.total_seconds()); 
        long nsec=time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()); 
        return t+chrono::nanoseconds(nsec); 

    } 
}; 

Я не уверен, когда они станут частью ускоренного выпуска. Похоже, что они сейчас не в форсированном багажнике ...

person HighCommander4    schedule 07.02.2011
comment
Хорошая находка. Эти функции предполагают, что эпоха Clock совпадает с эпохой ptime: New Years, 1970. Если это предположение верно, эти функции работают. В противном случае эти функции являются ошибкой во время выполнения без вывода сообщений. - person Howard Hinnant; 07.02.2011
comment
Можно ли правильно реализовать эти функции, даже если эпохи разные? - person HighCommander4; 07.02.2011
comment
Я верю, что вы можете подойти очень близко. Сначала я бы сделал пользовательский chrono :: clock (не обязательно должен быть chrono пространства имен), который имеет эпоху Нового года, 1970. Преобразование между ptime и вашими новыми Clock, как описано выше. И затем вы можете приблизительно конвертировать между двумя своими хронометрами, получая now () от каждого из них (один сразу за другим). Вычтите time_since_epoch () каждой time_point, чтобы получить продолжительность, которая является разницей между эпохами ваших двух хронографов. Вы добавляете / вычитаете эту разницу для преобразования между двумя хронографическими точками time_points. - person Howard Hinnant; 07.02.2011
comment
Это действительно хорошо, но я думаю, что nsec + 500 должно быть nsec + (nsec ›0–500: -500) для правильного округления с отрицательными числами. - person Johan Lundberg; 18.03.2013

Вы можете преобразовать time_t в std :: chrono :: system_clock :: time_point и обратно:

class system_clock
{
public:
    ...
    static time_t     to_time_t  (const time_point& __t);
    static time_point from_time_t(time_t __t);
};

И вы можете преобразовать time_t в ptime:

ptime from_time_t(time_t t);

Однако я не вижу способа преобразовать ptime в time_t.

person Howard Hinnant    schedule 06.02.2011
comment
вы можете использовать boost to_tm (ptime), чтобы получить структуру tm, а затем использовать mktime (...) из time.h / ctime, чтобы получить time_t. см. cplusplus.com/reference/ctime/mktime - person Arno Duvenhage; 19.06.2014
comment
Убедитесь, что ваше программное обеспечение не будет работать после 2038 года. en.wikipedia.org/wiki/Year_2038_problem - person Darien Pardinas; 18.06.2015
comment
Чтобы расширить комментарий @DarienPardinas, 32-разрядные платформы Linux используют 32-разрядное целое число со знаком для time_t. Это приведет к проблеме Y2038. - person Emile Cormier; 29.07.2015
comment
@EmileCormier: вот альтернативная библиотека datetime с лучшей совместимостью с std::chrono::system_clock: howardhinnant.github.io/date_v2.html Это перенесет вас в 32768 год назад и в 32767 год вперед. - person Howard Hinnant; 29.07.2015