date_duration_types.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #ifndef DATE_DURATION_TYPES_HPP___
  2. #define DATE_DURATION_TYPES_HPP___
  3. /* Copyright (c) 2004 CrystalClear Software, Inc.
  4. * Subject to the Boost Software License, Version 1.0.
  5. * (See accompanying file LICENSE_1_0.txt or
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. * Author: Jeff Garland, Bart Garst
  8. * $Date$
  9. */
  10. #include <boost/date_time/compiler_config.hpp>
  11. #include <boost/date_time/int_adapter.hpp>
  12. #include <boost/date_time/special_defs.hpp>
  13. #include <boost/date_time/date_duration.hpp>
  14. namespace boost {
  15. namespace date_time {
  16. //! Additional duration type that represents a number of n*7 days
  17. template <class duration_config>
  18. class BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration<duration_config> {
  19. public:
  20. weeks_duration(typename duration_config::impl_type w)
  21. : date_duration<duration_config>(w * 7) {}
  22. weeks_duration(special_values sv)
  23. : date_duration<duration_config>(sv) {}
  24. };
  25. // predeclare
  26. template<class t>
  27. class BOOST_SYMBOL_VISIBLE years_duration;
  28. //! additional duration type that represents a logical month
  29. /*! A logical month enables things like: "date(2002,Mar,2) + months(2) ->
  30. * 2002-May2". If the date is a last day-of-the-month, the result will
  31. * also be a last-day-of-the-month.
  32. */
  33. template<class base_config>
  34. class BOOST_SYMBOL_VISIBLE months_duration
  35. {
  36. private:
  37. typedef typename base_config::int_rep int_rep;
  38. typedef typename int_rep::int_type int_type;
  39. typedef typename base_config::date_type date_type;
  40. typedef typename date_type::duration_type duration_type;
  41. typedef typename base_config::month_adjustor_type month_adjustor_type;
  42. typedef months_duration<base_config> months_type;
  43. typedef years_duration<base_config> years_type;
  44. public:
  45. months_duration(int_rep num) : _m(num) {}
  46. months_duration(special_values sv) : _m(sv)
  47. {
  48. _m = int_rep::from_special(sv);
  49. }
  50. int_rep number_of_months() const { return _m; }
  51. //! returns a negative duration
  52. duration_type get_neg_offset(const date_type& d) const
  53. {
  54. month_adjustor_type m_adj(_m.as_number());
  55. return duration_type(m_adj.get_neg_offset(d));
  56. }
  57. duration_type get_offset(const date_type& d) const
  58. {
  59. month_adjustor_type m_adj(_m.as_number());
  60. return duration_type(m_adj.get_offset(d));
  61. }
  62. bool operator==(const months_type& rhs) const
  63. {
  64. return(_m == rhs._m);
  65. }
  66. bool operator!=(const months_type& rhs) const
  67. {
  68. return(_m != rhs._m);
  69. }
  70. months_type operator+(const months_type& rhs)const
  71. {
  72. return months_type(_m + rhs._m);
  73. }
  74. months_type& operator+=(const months_type& rhs)
  75. {
  76. _m = _m + rhs._m;
  77. return *this;
  78. }
  79. months_type operator-(const months_type& rhs)const
  80. {
  81. return months_type(_m - rhs._m);
  82. }
  83. months_type& operator-=(const months_type& rhs)
  84. {
  85. _m = _m - rhs._m;
  86. return *this;
  87. }
  88. months_type operator*(const int_type rhs)const
  89. {
  90. return months_type(_m * rhs);
  91. }
  92. months_type& operator*=(const int_type rhs)
  93. {
  94. _m = _m * rhs;
  95. return *this;
  96. }
  97. months_type operator/(const int_type rhs)const
  98. {
  99. return months_type(_m / rhs);
  100. }
  101. months_type& operator/=(const int_type rhs)
  102. {
  103. _m = _m / rhs;
  104. return *this;
  105. }
  106. months_type operator+(const years_type& y)const
  107. {
  108. return months_type(y.number_of_years() * 12 + _m);
  109. }
  110. months_type& operator+=(const years_type& y)
  111. {
  112. _m = y.number_of_years() * 12 + _m;
  113. return *this;
  114. }
  115. months_type operator-(const years_type& y) const
  116. {
  117. return months_type(_m - y.number_of_years() * 12);
  118. }
  119. months_type& operator-=(const years_type& y)
  120. {
  121. _m = _m - y.number_of_years() * 12;
  122. return *this;
  123. }
  124. //
  125. friend date_type operator+(const date_type& d, const months_type& m)
  126. {
  127. return d + m.get_offset(d);
  128. }
  129. friend date_type operator+=(date_type& d, const months_type& m)
  130. {
  131. return d += m.get_offset(d);
  132. }
  133. friend date_type operator-(const date_type& d, const months_type& m)
  134. {
  135. // get_neg_offset returns a negative duration, so we add
  136. return d + m.get_neg_offset(d);
  137. }
  138. friend date_type operator-=(date_type& d, const months_type& m)
  139. {
  140. // get_neg_offset returns a negative duration, so we add
  141. return d += m.get_neg_offset(d);
  142. }
  143. private:
  144. int_rep _m;
  145. };
  146. //! additional duration type that represents a logical year
  147. /*! A logical year enables things like: "date(2002,Mar,2) + years(2) ->
  148. * 2004-Mar-2". If the date is a last day-of-the-month, the result will
  149. * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) ->
  150. * 2004-Feb-29).
  151. */
  152. template<class base_config>
  153. class BOOST_SYMBOL_VISIBLE years_duration
  154. {
  155. private:
  156. typedef typename base_config::int_rep int_rep;
  157. typedef typename int_rep::int_type int_type;
  158. typedef typename base_config::date_type date_type;
  159. typedef typename date_type::duration_type duration_type;
  160. typedef typename base_config::month_adjustor_type month_adjustor_type;
  161. typedef years_duration<base_config> years_type;
  162. typedef months_duration<base_config> months_type;
  163. public:
  164. years_duration(int_rep num) : _y(num) {}
  165. years_duration(special_values sv) : _y(sv)
  166. {
  167. _y = int_rep::from_special(sv);
  168. }
  169. int_rep number_of_years() const { return _y; }
  170. //! returns a negative duration
  171. duration_type get_neg_offset(const date_type& d) const
  172. {
  173. month_adjustor_type m_adj(_y.as_number() * 12);
  174. return duration_type(m_adj.get_neg_offset(d));
  175. }
  176. duration_type get_offset(const date_type& d) const
  177. {
  178. month_adjustor_type m_adj(_y.as_number() * 12);
  179. return duration_type(m_adj.get_offset(d));
  180. }
  181. bool operator==(const years_type& rhs) const
  182. {
  183. return(_y == rhs._y);
  184. }
  185. bool operator!=(const years_type& rhs) const
  186. {
  187. return(_y != rhs._y);
  188. }
  189. years_type operator+(const years_type& rhs)const
  190. {
  191. return years_type(_y + rhs._y);
  192. }
  193. years_type& operator+=(const years_type& rhs)
  194. {
  195. _y = _y + rhs._y;
  196. return *this;
  197. }
  198. years_type operator-(const years_type& rhs)const
  199. {
  200. return years_type(_y - rhs._y);
  201. }
  202. years_type& operator-=(const years_type& rhs)
  203. {
  204. _y = _y - rhs._y;
  205. return *this;
  206. }
  207. years_type operator*(const int_type rhs)const
  208. {
  209. return years_type(_y * rhs);
  210. }
  211. years_type& operator*=(const int_type rhs)
  212. {
  213. _y = _y * rhs;
  214. return *this;
  215. }
  216. years_type operator/(const int_type rhs)const
  217. {
  218. return years_type(_y / rhs);
  219. }
  220. years_type& operator/=(const int_type rhs)
  221. {
  222. _y = _y / rhs;
  223. return *this;
  224. }
  225. months_type operator+(const months_type& m) const
  226. {
  227. return(months_type(_y * 12 + m.number_of_months()));
  228. }
  229. months_type operator-(const months_type& m) const
  230. {
  231. return(months_type(_y * 12 - m.number_of_months()));
  232. }
  233. //
  234. friend date_type operator+(const date_type& d, const years_type& y)
  235. {
  236. return d + y.get_offset(d);
  237. }
  238. friend date_type operator+=(date_type& d, const years_type& y)
  239. {
  240. return d += y.get_offset(d);
  241. }
  242. friend date_type operator-(const date_type& d, const years_type& y)
  243. {
  244. // get_neg_offset returns a negative duration, so we add
  245. return d + y.get_neg_offset(d);
  246. }
  247. friend date_type operator-=(date_type& d, const years_type& y)
  248. {
  249. // get_neg_offset returns a negative duration, so we add
  250. return d += y.get_neg_offset(d);
  251. }
  252. private:
  253. int_rep _y;
  254. };
  255. }} // namespace boost::date_time
  256. #endif // DATE_DURATION_TYPES_HPP___