#include "boost/date_time/posix_time/posix_time.hpp" #include "boost/date_time/local_time_adjustor.hpp" #include "boost/date_time/c_local_time_adjustor.hpp" #include void convertUtcTime(const boost::posix_time::ptime& tUtc); boost::posix_time::ptime utc_to_local_workaround(const boost::posix_time::ptime& t); int main() { using namespace boost::posix_time; using namespace boost::gregorian; typedef boost::date_time::c_local_adjustor local_adj; const ptime tUtcGood(date(2038,Jan,19), hours(3)); const ptime tUtcBad (date(2038,Jan,19), hours(4)); convertUtcTime(tUtcGood); convertUtcTime(tUtcBad); return 0; } void convertUtcTime(const boost::posix_time::ptime& tUtc) { using namespace boost::posix_time; using namespace boost::gregorian; typedef boost::date_time::c_local_adjustor local_adj; std::cout << "Converting UTC time " << to_simple_string(tUtc) << ". "; boost::posix_time::ptime tLoc; try { tLoc = local_adj::utc_to_local(tUtc); } catch (std::exception& e) { std::cout << "Ouch, year 2038 problem: " << e.what() << ". " << std::endl << "Applying bug fix... "; tLoc = utc_to_local_workaround(tUtc); } std::cout << "Local time is " << to_simple_string(tLoc) << std::endl; } boost::posix_time::ptime utc_to_local_workaround(const boost::posix_time::ptime& t) { // This code is a modified, non-templated version of boost::date_time::c_local_adjustor typedef boost::posix_time::ptime time_type; typedef time_type::time_duration_type time_duration_type; typedef time_type::date_type date_type; typedef date_type::duration_type date_duration_type; date_type time_t_start_day(1970,1,1); time_type time_t_start_time(time_t_start_day,time_duration_type(0,0,0)); if (t < time_t_start_time) { boost::throw_exception(std::out_of_range("Cannot convert dates prior to Jan 1, 1970")); BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_t_start_time); // should never reach } date_duration_type dd = t.date() - time_t_start_day; time_duration_type td = t.time_of_day(); // The bugfix, needing generalization: std::time_t t2 = static_cast<__int64>(dd.days())*__int64(86400) + static_cast<__int64>(td.hours()*3600 + td.minutes()*60 + td.seconds()); std::tm tms, *tms_ptr; tms_ptr = boost::date_time::c_time::localtime(&t2, &tms); date_type d(static_cast(tms_ptr->tm_year + 1900), static_cast(tms_ptr->tm_mon + 1), static_cast(tms_ptr->tm_mday)); time_duration_type td2(tms_ptr->tm_hour, tms_ptr->tm_min, tms_ptr->tm_sec, t.time_of_day().fractional_seconds()); return time_type(d,td2); } /* Printout: Converting UTC time 2038-Jan-19 03:00:00. Local time is 2038-Jan-19 04:00:00 Converting UTC time 2038-Jan-19 04:00:00. Ouch, year 2038 problem: could not convert calendar time to local time. Applying bug fix... Local time is 2038-Jan-19 05:00:00 */