1 #ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP 2 #define DATE_TIME_TIME_SYSTEM_SPLIT_HPP 3 4 /* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. 5 * Use, modification and distribution is subject to the 6 * Boost Software License, Version 1.0. (See accompanying 7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 8 * Author: Jeff Garland, Bart Garst 9 * $Date$ 10 */ 11 12 13 #include <string> 14 #include <boost/cstdint.hpp> 15 #include <boost/date_time/compiler_config.hpp> 16 #include <boost/date_time/time_defs.hpp> 17 #include <boost/date_time/special_defs.hpp> 18 #include <boost/date_time/wrapping_int.hpp> 19 20 namespace boost { 21 namespace date_time { 22 23 //! An unadjusted time system implementation. 24 #if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) 25 template<typename config, boost::int32_t ticks_per_second> 26 #else 27 template<typename config> 28 #endif 29 class split_timedate_system 30 { 31 public: 32 typedef typename config::time_rep_type time_rep_type; 33 typedef typename config::date_type date_type; 34 typedef typename config::time_duration_type time_duration_type; 35 typedef typename config::date_duration_type date_duration_type; 36 typedef typename config::int_type int_type; 37 typedef typename config::resolution_traits resolution_traits; 38 39 //86400 is number of seconds in a day... 40 #if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) 41 typedef date_time::wrapping_int<int_type, INT64_C(86400) * ticks_per_second > wrap_int_type; 42 #else 43 private: 44 BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second); 45 public: 46 # if BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0X581) ) 47 typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type; 48 # else 49 typedef date_time::wrapping_int<int_type, ticks_per_day> wrap_int_type; 50 #endif 51 #endif 52 53 static 54 BOOST_CXX14_CONSTEXPR get_time_rep(special_values sv)55 time_rep_type get_time_rep(special_values sv) 56 { 57 switch (sv) { 58 case not_a_date_time: 59 return time_rep_type(date_type(not_a_date_time), 60 time_duration_type(not_a_date_time)); 61 case pos_infin: 62 return time_rep_type(date_type(pos_infin), 63 time_duration_type(pos_infin)); 64 case neg_infin: 65 return time_rep_type(date_type(neg_infin), 66 time_duration_type(neg_infin)); 67 case max_date_time: { 68 time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); 69 return time_rep_type(date_type(max_date_time), td); 70 } 71 case min_date_time: 72 return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); 73 74 default: 75 return time_rep_type(date_type(not_a_date_time), 76 time_duration_type(not_a_date_time)); 77 78 } 79 80 } 81 82 static 83 BOOST_CXX14_CONSTEXPR get_time_rep(const date_type & day,const time_duration_type & tod,date_time::dst_flags=not_dst)84 time_rep_type get_time_rep(const date_type& day, 85 const time_duration_type& tod, 86 date_time::dst_flags /* dst */ = not_dst) 87 { 88 if(day.is_special() || tod.is_special()) { 89 if(day.is_not_a_date() || tod.is_not_a_date_time()) { 90 return time_rep_type(date_type(not_a_date_time), 91 time_duration_type(not_a_date_time)); 92 } 93 else if(day.is_pos_infinity()) { 94 if(tod.is_neg_infinity()) { 95 return time_rep_type(date_type(not_a_date_time), 96 time_duration_type(not_a_date_time)); 97 } 98 else { 99 return time_rep_type(day, time_duration_type(pos_infin)); 100 } 101 } 102 else if(day.is_neg_infinity()) { 103 if(tod.is_pos_infinity()) { 104 return time_rep_type(date_type(not_a_date_time), 105 time_duration_type(not_a_date_time)); 106 } 107 else { 108 return time_rep_type(day, time_duration_type(neg_infin)); 109 } 110 } 111 else if(tod.is_pos_infinity()) { 112 if(day.is_neg_infinity()) { 113 return time_rep_type(date_type(not_a_date_time), 114 time_duration_type(not_a_date_time)); 115 } 116 else { 117 return time_rep_type(date_type(pos_infin), tod); 118 } 119 } 120 else if(tod.is_neg_infinity()) { 121 if(day.is_pos_infinity()) { 122 return time_rep_type(date_type(not_a_date_time), 123 time_duration_type(not_a_date_time)); 124 } 125 else { 126 return time_rep_type(date_type(neg_infin), tod); 127 } 128 } 129 } 130 return time_rep_type(day, tod); 131 } get_date(const time_rep_type & val)132 static BOOST_CONSTEXPR date_type get_date(const time_rep_type& val) 133 { 134 return date_type(val.day); 135 } get_time_of_day(const time_rep_type & val)136 static BOOST_CONSTEXPR time_duration_type get_time_of_day(const time_rep_type& val) 137 { 138 return time_duration_type(val.time_of_day); 139 } zone_name(const time_rep_type &)140 static std::string zone_name(const time_rep_type&) 141 { 142 return std::string(); 143 } 144 static BOOST_CONSTEXPR is_equal(const time_rep_type & lhs,const time_rep_type & rhs)145 bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) 146 { 147 return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day)); 148 } 149 static BOOST_CXX14_CONSTEXPR is_less(const time_rep_type & lhs,const time_rep_type & rhs)150 bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) 151 { 152 if (lhs.day < rhs.day) return true; 153 if (lhs.day > rhs.day) return false; 154 return (lhs.time_of_day < rhs.time_of_day); 155 } 156 static BOOST_CXX14_CONSTEXPR add_days(const time_rep_type & base,const date_duration_type & dd)157 time_rep_type add_days(const time_rep_type& base, 158 const date_duration_type& dd) 159 { 160 return time_rep_type(base.day+dd, base.time_of_day); 161 } 162 static BOOST_CXX14_CONSTEXPR subtract_days(const time_rep_type & base,const date_duration_type & dd)163 time_rep_type subtract_days(const time_rep_type& base, 164 const date_duration_type& dd) 165 { 166 return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day); 167 } 168 static BOOST_CXX14_CONSTEXPR subtract_time_duration(const time_rep_type & base,const time_duration_type & td)169 time_rep_type subtract_time_duration(const time_rep_type& base, 170 const time_duration_type& td) 171 { 172 if(base.day.is_special() || td.is_special()) 173 { 174 return split_timedate_system::get_time_rep(base.day, -td); 175 } 176 if (td.is_negative()) { 177 time_duration_type td1 = td.invert_sign(); 178 return add_time_duration(base,td1); 179 } 180 181 wrap_int_type day_offset(base.time_of_day.ticks()); 182 date_duration_type day_overflow(static_cast<typename date_duration_type::duration_rep_type>(day_offset.subtract(td.ticks()))); 183 184 return time_rep_type(base.day-day_overflow, 185 time_duration_type(0,0,0,day_offset.as_int())); 186 } 187 static BOOST_CXX14_CONSTEXPR add_time_duration(const time_rep_type & base,time_duration_type td)188 time_rep_type add_time_duration(const time_rep_type& base, 189 time_duration_type td) 190 { 191 if(base.day.is_special() || td.is_special()) { 192 return split_timedate_system::get_time_rep(base.day, td); 193 } 194 if (td.is_negative()) { 195 time_duration_type td1 = td.invert_sign(); 196 return subtract_time_duration(base,td1); 197 } 198 199 wrap_int_type day_offset(base.time_of_day.ticks()); 200 date_duration_type day_overflow(static_cast< typename date_duration_type::duration_rep_type >(day_offset.add(td.ticks()))); 201 202 return time_rep_type(base.day+day_overflow, 203 time_duration_type(0,0,0,day_offset.as_int())); 204 } 205 static BOOST_CXX14_CONSTEXPR subtract_times(const time_rep_type & lhs,const time_rep_type & rhs)206 time_duration_type subtract_times(const time_rep_type& lhs, 207 const time_rep_type& rhs) 208 { 209 date_duration_type dd = lhs.day - rhs.day; 210 if (BOOST_LIKELY(!dd.is_special())) { 211 time_duration_type td(dd.days()*24,0,0); // days * 24 hours 212 time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; 213 return td+td2; 214 } else { 215 time_duration_type td(dd.as_special()); 216 time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; 217 return td+td2; 218 } 219 } 220 221 }; 222 223 } } //namespace date_time 224 225 226 #endif 227