Ticket #9158: boost_date_time_test.cpp

File boost_date_time_test.cpp, 3.1 KB (added by Jon-Terje Lilleby <jon-terje@…>, 9 years ago)
Line 
1#include "boost/date_time/posix_time/posix_time.hpp"
2#include "boost/date_time/local_time_adjustor.hpp"
3#include "boost/date_time/c_local_time_adjustor.hpp"
4#include <iostream>
5
6void convertUtcTime(const boost::posix_time::ptime& tUtc);
7boost::posix_time::ptime utc_to_local_workaround(const boost::posix_time::ptime& t);
8
9int main()
10{
11 using namespace boost::posix_time;
12 using namespace boost::gregorian;
13 typedef boost::date_time::c_local_adjustor<ptime> local_adj;
14
15 const ptime tUtcGood(date(2038,Jan,19), hours(3));
16 const ptime tUtcBad (date(2038,Jan,19), hours(4));
17
18 convertUtcTime(tUtcGood);
19 convertUtcTime(tUtcBad);
20
21 return 0;
22}
23
24
25void convertUtcTime(const boost::posix_time::ptime& tUtc)
26{
27 using namespace boost::posix_time;
28 using namespace boost::gregorian;
29 typedef boost::date_time::c_local_adjustor<ptime> local_adj;
30
31 std::cout << "Converting UTC time " << to_simple_string(tUtc) << ". ";
32 boost::posix_time::ptime tLoc;
33 try
34 {
35 tLoc = local_adj::utc_to_local(tUtc);
36 }
37 catch (std::exception& e)
38 {
39 std::cout << "Ouch, year 2038 problem: " << e.what() << ". " << std::endl << "Applying bug fix... ";
40 tLoc = utc_to_local_workaround(tUtc);
41 }
42 std::cout << "Local time is " << to_simple_string(tLoc) << std::endl;
43}
44
45
46boost::posix_time::ptime utc_to_local_workaround(const boost::posix_time::ptime& t)
47{
48 // This code is a modified, non-templated version of boost::date_time::c_local_adjustor<ptime>
49
50 typedef boost::posix_time::ptime time_type;
51 typedef time_type::time_duration_type time_duration_type;
52 typedef time_type::date_type date_type;
53 typedef date_type::duration_type date_duration_type;
54
55 date_type time_t_start_day(1970,1,1);
56 time_type time_t_start_time(time_t_start_day,time_duration_type(0,0,0));
57 if (t < time_t_start_time) {
58 boost::throw_exception(std::out_of_range("Cannot convert dates prior to Jan 1, 1970"));
59 BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_t_start_time); // should never reach
60 }
61 date_duration_type dd = t.date() - time_t_start_day;
62 time_duration_type td = t.time_of_day();
63
64 // The bugfix, needing generalization:
65 std::time_t t2 = static_cast<__int64>(dd.days())*__int64(86400) + static_cast<__int64>(td.hours()*3600 + td.minutes()*60 + td.seconds());
66
67 std::tm tms, *tms_ptr;
68 tms_ptr = boost::date_time::c_time::localtime(&t2, &tms);
69 date_type d(static_cast<unsigned short>(tms_ptr->tm_year + 1900),
70 static_cast<unsigned short>(tms_ptr->tm_mon + 1),
71 static_cast<unsigned short>(tms_ptr->tm_mday));
72 time_duration_type td2(tms_ptr->tm_hour,
73 tms_ptr->tm_min,
74 tms_ptr->tm_sec,
75 t.time_of_day().fractional_seconds());
76
77 return time_type(d,td2);
78}
79
80
81/* Printout:
82
83Converting UTC time 2038-Jan-19 03:00:00. Local time is 2038-Jan-19 04:00:00
84Converting UTC time 2038-Jan-19 04:00:00. Ouch, year 2038 problem: could not convert calendar time to local time.
85Applying bug fix... Local time is 2038-Jan-19 05:00:00
86*/