1 #ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP 2 #define DATE_TIME_TIME_SYSTEM_COUNTED_HPP 3 4 /* Copyright (c) 2002,2003 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 <boost/date_time/compiler_config.hpp> 14 #include <boost/date_time/time_defs.hpp> 15 #include <boost/date_time/special_defs.hpp> 16 #include <string> 17 18 19 namespace boost { 20 namespace date_time { 21 22 //! Time representation that uses a single integer count 23 template<class config> 24 struct counted_time_rep 25 { 26 typedef typename config::int_type int_type; 27 typedef typename config::date_type date_type; 28 typedef typename config::impl_type impl_type; 29 typedef typename date_type::duration_type date_duration_type; 30 typedef typename date_type::calendar_type calendar_type; 31 typedef typename date_type::ymd_type ymd_type; 32 typedef typename config::time_duration_type time_duration_type; 33 typedef typename config::resolution_traits resolution_traits; 34 35 BOOST_CXX14_CONSTEXPR counted_time_repboost::date_time::counted_time_rep36 counted_time_rep(const date_type& d, const time_duration_type& time_of_day) 37 : time_count_(1) 38 { 39 if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) { 40 time_count_ = time_of_day.get_rep() + d.day_count(); 41 //std::cout << time_count_ << std::endl; 42 } 43 else { 44 time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks(); 45 } 46 } 47 BOOST_CXX14_CONSTEXPR counted_time_repboost::date_time::counted_time_rep48 explicit counted_time_rep(int_type count) : 49 time_count_(count) 50 {} 51 BOOST_CXX14_CONSTEXPR counted_time_repboost::date_time::counted_time_rep52 explicit counted_time_rep(impl_type count) : 53 time_count_(count) 54 {} 55 BOOST_CXX14_CONSTEXPR dateboost::date_time::counted_time_rep56 date_type date() const 57 { 58 if(time_count_.is_special()) { 59 return date_type(time_count_.as_special()); 60 } 61 else { 62 typename calendar_type::date_int_type dc = static_cast<typename calendar_type::date_int_type>(day_count()); 63 //std::cout << "time_rep here:" << dc << std::endl; 64 ymd_type ymd = calendar_type::from_day_number(dc); 65 return date_type(ymd); 66 } 67 } 68 //int_type day_count() const 69 BOOST_CXX14_CONSTEXPR day_countboost::date_time::counted_time_rep70 unsigned long day_count() const 71 { 72 /* resolution_traits::as_number returns a boost::int64_t & 73 * frac_sec_per_day is also a boost::int64_t so, naturally, 74 * the division operation returns a boost::int64_t. 75 * The static_cast to an unsigned long is ok (results in no data loss) 76 * because frac_sec_per_day is either the number of 77 * microseconds per day, or the number of nanoseconds per day. 78 * Worst case scenario: resolution_traits::as_number returns the 79 * maximum value an int64_t can hold and frac_sec_per_day 80 * is microseconds per day (lowest possible value). 81 * The division operation will then return a value of 106751991 - 82 * easily fitting in an unsigned long. 83 */ 84 return static_cast<unsigned long>(resolution_traits::as_number(time_count_) / frac_sec_per_day()); 85 } time_countboost::date_time::counted_time_rep86 BOOST_CXX14_CONSTEXPR int_type time_count() const 87 { 88 return resolution_traits::as_number(time_count_); 89 } todboost::date_time::counted_time_rep90 BOOST_CXX14_CONSTEXPR int_type tod() const 91 { 92 return resolution_traits::as_number(time_count_) % frac_sec_per_day(); 93 } frac_sec_per_dayboost::date_time::counted_time_rep94 static BOOST_CXX14_CONSTEXPR int_type frac_sec_per_day() 95 { 96 int_type seconds_per_day = 60*60*24; 97 int_type fractional_sec_per_sec(resolution_traits::res_adjust()); 98 return seconds_per_day*fractional_sec_per_sec; 99 } is_pos_infinityboost::date_time::counted_time_rep100 BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const 101 { 102 return impl_type::is_pos_inf(time_count_.as_number()); 103 } is_neg_infinityboost::date_time::counted_time_rep104 BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const 105 { 106 return impl_type::is_neg_inf(time_count_.as_number()); 107 } is_not_a_date_timeboost::date_time::counted_time_rep108 BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const 109 { 110 return impl_type::is_not_a_number(time_count_.as_number()); 111 } is_specialboost::date_time::counted_time_rep112 BOOST_CXX14_CONSTEXPR bool is_special()const 113 { 114 return time_count_.is_special(); 115 } get_repboost::date_time::counted_time_rep116 BOOST_CXX14_CONSTEXPR impl_type get_rep()const 117 { 118 return time_count_; 119 } 120 private: 121 impl_type time_count_; 122 }; 123 124 //! An unadjusted time system implementation. 125 template<class time_rep> 126 class counted_time_system 127 { 128 public: 129 typedef time_rep time_rep_type; 130 typedef typename time_rep_type::impl_type impl_type; 131 typedef typename time_rep_type::time_duration_type time_duration_type; 132 typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type; 133 typedef typename time_rep_type::date_type date_type; 134 typedef typename time_rep_type::date_duration_type date_duration_type; 135 136 unused_var(const T &)137 template<class T> static BOOST_CXX14_CONSTEXPR void unused_var(const T&) {} 138 139 static BOOST_CXX14_CONSTEXPR get_time_rep(const date_type & day,const time_duration_type & tod,date_time::dst_flags dst=not_dst)140 time_rep_type get_time_rep(const date_type& day, 141 const time_duration_type& tod, 142 date_time::dst_flags dst=not_dst) 143 { 144 unused_var(dst); 145 return time_rep_type(day, tod); 146 } 147 get_time_rep(special_values sv)148 static BOOST_CXX14_CONSTEXPR time_rep_type get_time_rep(special_values sv) 149 { 150 switch (sv) { 151 case not_a_date_time: 152 return time_rep_type(date_type(not_a_date_time), 153 time_duration_type(not_a_date_time)); 154 case pos_infin: 155 return time_rep_type(date_type(pos_infin), 156 time_duration_type(pos_infin)); 157 case neg_infin: 158 return time_rep_type(date_type(neg_infin), 159 time_duration_type(neg_infin)); 160 case max_date_time: { 161 time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); 162 return time_rep_type(date_type(max_date_time), td); 163 } 164 case min_date_time: 165 return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); 166 167 default: 168 return time_rep_type(date_type(not_a_date_time), 169 time_duration_type(not_a_date_time)); 170 171 } 172 173 } 174 175 static BOOST_CXX14_CONSTEXPR date_type get_date(const time_rep_type & val)176 get_date(const time_rep_type& val) 177 { 178 return val.date(); 179 } 180 static BOOST_CXX14_CONSTEXPR get_time_of_day(const time_rep_type & val)181 time_duration_type get_time_of_day(const time_rep_type& val) 182 { 183 if(val.is_special()) { 184 return time_duration_type(val.get_rep().as_special()); 185 } 186 else{ 187 return time_duration_type(0,0,0,val.tod()); 188 } 189 } zone_name(const time_rep_type &)190 static std::string zone_name(const time_rep_type&) 191 { 192 return ""; 193 } is_equal(const time_rep_type & lhs,const time_rep_type & rhs)194 static BOOST_CXX14_CONSTEXPR bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) 195 { 196 return (lhs.time_count() == rhs.time_count()); 197 } 198 static BOOST_CXX14_CONSTEXPR is_less(const time_rep_type & lhs,const time_rep_type & rhs)199 bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) 200 { 201 return (lhs.time_count() < rhs.time_count()); 202 } 203 static BOOST_CXX14_CONSTEXPR add_days(const time_rep_type & base,const date_duration_type & dd)204 time_rep_type add_days(const time_rep_type& base, 205 const date_duration_type& dd) 206 { 207 if(base.is_special() || dd.is_special()) { 208 return(time_rep_type(base.get_rep() + dd.get_rep())); 209 } 210 else { 211 return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day())); 212 } 213 } 214 static BOOST_CXX14_CONSTEXPR subtract_days(const time_rep_type & base,const date_duration_type & dd)215 time_rep_type subtract_days(const time_rep_type& base, 216 const date_duration_type& dd) 217 { 218 if(base.is_special() || dd.is_special()) { 219 return(time_rep_type(base.get_rep() - dd.get_rep())); 220 } 221 else{ 222 return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day())); 223 } 224 } 225 static BOOST_CXX14_CONSTEXPR subtract_time_duration(const time_rep_type & base,const time_duration_type & td)226 time_rep_type subtract_time_duration(const time_rep_type& base, 227 const time_duration_type& td) 228 { 229 if(base.is_special() || td.is_special()) { 230 return(time_rep_type(base.get_rep() - td.get_rep())); 231 } 232 else { 233 return time_rep_type(base.time_count() - td.ticks()); 234 } 235 } 236 static BOOST_CXX14_CONSTEXPR add_time_duration(const time_rep_type & base,time_duration_type td)237 time_rep_type add_time_duration(const time_rep_type& base, 238 time_duration_type td) 239 { 240 if(base.is_special() || td.is_special()) { 241 return(time_rep_type(base.get_rep() + td.get_rep())); 242 } 243 else { 244 return time_rep_type(base.time_count() + td.ticks()); 245 } 246 } 247 static BOOST_CXX14_CONSTEXPR subtract_times(const time_rep_type & lhs,const time_rep_type & rhs)248 time_duration_type subtract_times(const time_rep_type& lhs, 249 const time_rep_type& rhs) 250 { 251 if(lhs.is_special() || rhs.is_special()) { 252 return(time_duration_type( 253 impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number()))); 254 } 255 else { 256 fractional_seconds_type fs = lhs.time_count() - rhs.time_count(); 257 return time_duration_type(0,0,0,fs); 258 } 259 } 260 261 }; 262 263 264 } } //namespace date_time 265 266 267 268 #endif 269 270