1 #ifndef DATE_TIME_DATE_HPP___ 2 #define DATE_TIME_DATE_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 #include <boost/operators.hpp> 13 #include <boost/date_time/compiler_config.hpp> 14 #include <boost/date_time/year_month_day.hpp> 15 #include <boost/date_time/special_defs.hpp> 16 17 namespace boost { 18 namespace date_time { 19 20 //!Representation of timepoint at the one day level resolution. 21 /*! 22 The date template represents an interface shell for a date class 23 that is based on a year-month-day system such as the gregorian 24 or iso systems. It provides basic operations to enable calculation 25 and comparisons. 26 27 <b>Theory</b> 28 29 This date representation fundamentally departs from the C tm struct 30 approach. The goal for this type is to provide efficient date 31 operations (add, subtract) and storage (minimize space to represent) 32 in a concrete class. Thus, the date uses a count internally to 33 represent a particular date. The calendar parameter defines 34 the policies for converting the the year-month-day and internal 35 counted form here. Applications that need to perform heavy 36 formatting of the same date repeatedly will perform better 37 by using the year-month-day representation. 38 39 Internally the date uses a day number to represent the date. 40 This is a monotonic time representation. This representation 41 allows for fast comparison as well as simplifying 42 the creation of writing numeric operations. Essentially, the 43 internal day number is like adjusted julian day. The adjustment 44 is determined by the Epoch date which is represented as day 1 of 45 the calendar. Day 0 is reserved for negative infinity so that 46 any actual date is automatically greater than negative infinity. 47 When a date is constructed from a date or formatted for output, 48 the appropriate conversions are applied to create the year, month, 49 day representations. 50 */ 51 52 53 template<class T, class calendar, class duration_type_> 54 class BOOST_SYMBOL_VISIBLE date : private 55 boost::less_than_comparable<T 56 , boost::equality_comparable<T 57 > > 58 { 59 public: 60 typedef T date_type; 61 typedef calendar calendar_type; 62 typedef typename calendar::date_traits_type traits_type; 63 typedef duration_type_ duration_type; 64 typedef typename calendar::year_type year_type; 65 typedef typename calendar::month_type month_type; 66 typedef typename calendar::day_type day_type; 67 typedef typename calendar::ymd_type ymd_type; 68 typedef typename calendar::date_rep_type date_rep_type; 69 typedef typename calendar::date_int_type date_int_type; 70 typedef typename calendar::day_of_week_type day_of_week_type; date(year_type y,month_type m,day_type d)71 BOOST_CXX14_CONSTEXPR date(year_type y, month_type m, day_type d) 72 : days_(calendar::day_number(ymd_type(y, m, d))) 73 {} date(const ymd_type & ymd)74 BOOST_CXX14_CONSTEXPR date(const ymd_type& ymd) 75 : days_(calendar::day_number(ymd)) 76 {} 77 //let the compiler write copy, assignment, and destructor year() const78 BOOST_CXX14_CONSTEXPR year_type year() const 79 { 80 ymd_type ymd = calendar::from_day_number(days_); 81 return ymd.year; 82 } month() const83 BOOST_CXX14_CONSTEXPR month_type month() const 84 { 85 ymd_type ymd = calendar::from_day_number(days_); 86 return ymd.month; 87 } day() const88 BOOST_CXX14_CONSTEXPR day_type day() const 89 { 90 ymd_type ymd = calendar::from_day_number(days_); 91 return ymd.day; 92 } day_of_week() const93 BOOST_CXX14_CONSTEXPR day_of_week_type day_of_week() const 94 { 95 ymd_type ymd = calendar::from_day_number(days_); 96 return calendar::day_of_week(ymd); 97 } year_month_day() const98 BOOST_CXX14_CONSTEXPR ymd_type year_month_day() const 99 { 100 return calendar::from_day_number(days_); 101 } operator <(const date_type & rhs) const102 BOOST_CONSTEXPR bool operator<(const date_type& rhs) const 103 { 104 return days_ < rhs.days_; 105 } operator ==(const date_type & rhs) const106 BOOST_CONSTEXPR bool operator==(const date_type& rhs) const 107 { 108 return days_ == rhs.days_; 109 } 110 //! check to see if date is a special value is_special() const111 BOOST_CONSTEXPR bool is_special()const 112 { 113 return(is_not_a_date() || is_infinity()); 114 } 115 //! check to see if date is not a value is_not_a_date() const116 BOOST_CONSTEXPR bool is_not_a_date() const 117 { 118 return traits_type::is_not_a_number(days_); 119 } 120 //! check to see if date is one of the infinity values is_infinity() const121 BOOST_CONSTEXPR bool is_infinity() const 122 { 123 return traits_type::is_inf(days_); 124 } 125 //! check to see if date is greater than all possible dates is_pos_infinity() const126 BOOST_CONSTEXPR bool is_pos_infinity() const 127 { 128 return traits_type::is_pos_inf(days_); 129 } 130 //! check to see if date is greater than all possible dates is_neg_infinity() const131 BOOST_CONSTEXPR bool is_neg_infinity() const 132 { 133 return traits_type::is_neg_inf(days_); 134 } 135 //! return as a special value or a not_special if a normal date as_special() const136 BOOST_CXX14_CONSTEXPR special_values as_special() const 137 { 138 return traits_type::to_special(days_); 139 } operator -(const date_type & d) const140 BOOST_CXX14_CONSTEXPR duration_type operator-(const date_type& d) const 141 { 142 if (!this->is_special() && !d.is_special()) 143 { 144 // The duration underlying type may be wider than the date underlying type. 145 // Thus we calculate the difference in terms of two durations from some common fixed base date. 146 typedef typename duration_type::duration_rep_type duration_rep_type; 147 return duration_type(static_cast< duration_rep_type >(days_) - static_cast< duration_rep_type >(d.days_)); 148 } 149 else 150 { 151 // In this case the difference will be a special value, too 152 date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_); 153 return duration_type(val.as_special()); 154 } 155 } 156 operator -(const duration_type & dd) const157 BOOST_CXX14_CONSTEXPR date_type operator-(const duration_type& dd) const 158 { 159 if(dd.is_special()) 160 { 161 return date_type(date_rep_type(days_) - dd.get_rep()); 162 } 163 return date_type(date_rep_type(days_) - static_cast<date_int_type>(dd.days())); 164 } operator -=(const duration_type & dd)165 BOOST_CXX14_CONSTEXPR date_type operator-=(const duration_type& dd) 166 { 167 *this = *this - dd; 168 return date_type(days_); 169 } day_count() const170 BOOST_CONSTEXPR date_rep_type day_count() const 171 { 172 return days_; 173 } 174 //allow internal access from operators operator +(const duration_type & dd) const175 BOOST_CXX14_CONSTEXPR date_type operator+(const duration_type& dd) const 176 { 177 if(dd.is_special()) 178 { 179 return date_type(date_rep_type(days_) + dd.get_rep()); 180 } 181 return date_type(date_rep_type(days_) + static_cast<date_int_type>(dd.days())); 182 } operator +=(const duration_type & dd)183 BOOST_CXX14_CONSTEXPR date_type operator+=(const duration_type& dd) 184 { 185 *this = *this + dd; 186 return date_type(days_); 187 } 188 189 //see reference 190 protected: 191 /*! This is a private constructor which allows for the creation of new 192 dates. It is not exposed to users since that would require class 193 users to understand the inner workings of the date class. 194 */ date(date_int_type days)195 BOOST_CONSTEXPR explicit date(date_int_type days) : days_(days) {} date(date_rep_type days)196 BOOST_CXX14_CONSTEXPR explicit date(date_rep_type days) : days_(days.as_number()) {} 197 date_int_type days_; 198 199 }; 200 201 202 203 204 } } // namespace date_time 205 206 207 208 209 #endif 210