Line data Source code
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; 71 0 : date(year_type y, month_type m, day_type d) 72 0 : : days_(calendar::day_number(ymd_type(y, m, d))) 73 : {} 74 0 : date(const ymd_type& ymd) 75 0 : : days_(calendar::day_number(ymd)) 76 : {} 77 : //let the compiler write copy, assignment, and destructor 78 0 : year_type year() const 79 : { 80 0 : ymd_type ymd = calendar::from_day_number(days_); 81 0 : return ymd.year; 82 : } 83 : month_type month() const 84 : { 85 : ymd_type ymd = calendar::from_day_number(days_); 86 : return ymd.month; 87 : } 88 : day_type day() const 89 : { 90 : ymd_type ymd = calendar::from_day_number(days_); 91 : return ymd.day; 92 : } 93 : 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 : } 98 0 : ymd_type year_month_day() const 99 : { 100 0 : return calendar::from_day_number(days_); 101 : } 102 : bool operator<(const date_type& rhs) const 103 : { 104 : return days_ < rhs.days_; 105 : } 106 : bool operator==(const date_type& rhs) const 107 : { 108 : return days_ == rhs.days_; 109 : } 110 : //! check to see if date is a special value 111 0 : bool is_special()const 112 : { 113 0 : return(is_not_a_date() || is_infinity()); 114 : } 115 : //! check to see if date is not a value 116 0 : bool is_not_a_date() const 117 : { 118 0 : return traits_type::is_not_a_number(days_); 119 : } 120 : //! check to see if date is one of the infinity values 121 0 : bool is_infinity() const 122 : { 123 0 : return traits_type::is_inf(days_); 124 : } 125 : //! check to see if date is greater than all possible dates 126 : 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 131 : 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 136 0 : special_values as_special() const 137 : { 138 0 : return traits_type::to_special(days_); 139 : } 140 0 : duration_type operator-(const date_type& d) const 141 : { 142 0 : 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 0 : 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 0 : date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_); 153 0 : return duration_type(val.as_special()); 154 : } 155 : } 156 : 157 : 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 : } 165 : date_type operator-=(const duration_type& dd) 166 : { 167 : *this = *this - dd; 168 : return date_type(days_); 169 : } 170 0 : date_rep_type day_count() const 171 : { 172 0 : return days_; 173 : } 174 : //allow internal access from operators 175 : 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 : } 183 : 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 : */ 195 : explicit date(date_int_type days) : days_(days) {} 196 0 : 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