1 #ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___
2 #define _DATE_TIME_ADJUST_FUNCTORS_HPP___
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
12 #include "boost/date_time/date.hpp"
13 #include "boost/date_time/wrapping_int.hpp"
19 //! Functor to iterate a fixed number of days
20 template<class date_type>
24 typedef typename date_type::duration_type duration_type;
25 day_functor(int f) : f_(f) {}
26 duration_type get_offset(const date_type&) const
28 return duration_type(f_);
30 duration_type get_neg_offset(const date_type&) const
32 return duration_type(-f_);
39 //! Provides calculation to find next nth month given a date
40 /*! This adjustment function provides the logic for 'month-based'
41 * advancement on a ymd based calendar. The policy it uses
42 * to handle the non existant end of month days is to back
43 * up to the last day of the month. Also, if the starting
44 * date is the last day of a month, this functor will attempt
45 * to adjust to the end of the month.
48 template<class date_type>
52 typedef typename date_type::duration_type duration_type;
53 typedef typename date_type::calendar_type cal_type;
54 typedef typename cal_type::ymd_type ymd_type;
55 typedef typename cal_type::day_type day_type;
57 month_functor(int f) : f_(f), origDayOfMonth_(0) {}
58 duration_type get_offset(const date_type& d) const
60 ymd_type ymd(d.year_month_day());
61 if (origDayOfMonth_ == 0) {
62 origDayOfMonth_ = ymd.day;
63 day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
64 if (endOfMonthDay == ymd.day) {
65 origDayOfMonth_ = -1; //force the value to the end of month
68 typedef date_time::wrapping_int2<short,1,12> wrap_int2;
69 wrap_int2 wi(ymd.month);
70 //calc the year wrap around, add() returns 0 or 1 if wrapped
71 const typename ymd_type::year_type year(static_cast<typename ymd_type::year_type::value_type>(ymd.year + wi.add(f_)));
72 // std::cout << "trace wi: " << wi.as_int() << std::endl;
73 // std::cout << "trace year: " << year << std::endl;
74 //find the last day for the new month
75 day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
76 //original was the end of month -- force to last day of month
77 if (origDayOfMonth_ == -1) {
78 return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
80 day_type dayOfMonth = origDayOfMonth_;
81 if (dayOfMonth > resultingEndOfMonthDay) {
82 dayOfMonth = resultingEndOfMonthDay;
84 return date_type(year, wi.as_int(), dayOfMonth) - d;
86 //! Returns a negative duration_type
87 duration_type get_neg_offset(const date_type& d) const
89 ymd_type ymd(d.year_month_day());
90 if (origDayOfMonth_ == 0) {
91 origDayOfMonth_ = ymd.day;
92 day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
93 if (endOfMonthDay == ymd.day) {
94 origDayOfMonth_ = -1; //force the value to the end of month
97 typedef date_time::wrapping_int2<short,1,12> wrap_int2;
98 wrap_int2 wi(ymd.month);
99 //calc the year wrap around, add() returns 0 or 1 if wrapped
100 const typename ymd_type::year_type year(static_cast<typename ymd_type::year_type::value_type>(ymd.year + wi.subtract(f_)));
101 //find the last day for the new month
102 day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
103 //original was the end of month -- force to last day of month
104 if (origDayOfMonth_ == -1) {
105 return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
107 day_type dayOfMonth = origDayOfMonth_;
108 if (dayOfMonth > resultingEndOfMonthDay) {
109 dayOfMonth = resultingEndOfMonthDay;
111 return date_type(year, wi.as_int(), dayOfMonth) - d;
115 mutable short origDayOfMonth_;
119 //! Functor to iterate a over weeks
120 template<class date_type>
124 typedef typename date_type::duration_type duration_type;
125 typedef typename date_type::calendar_type calendar_type;
126 week_functor(int f) : f_(f) {}
127 duration_type get_offset(const date_type&) const
129 return duration_type(f_*static_cast<int>(calendar_type::days_in_week()));
131 duration_type get_neg_offset(const date_type&) const
133 return duration_type(-f_*static_cast<int>(calendar_type::days_in_week()));
139 //! Functor to iterate by a year adjusting for leap years
140 template<class date_type>
144 //typedef typename date_type::year_type year_type;
145 typedef typename date_type::duration_type duration_type;
146 year_functor(int f) : _mf(f * 12) {}
147 duration_type get_offset(const date_type& d) const
149 return _mf.get_offset(d);
151 duration_type get_neg_offset(const date_type& d) const
153 return _mf.get_neg_offset(d);
156 month_functor<date_type> _mf;
160 } }//namespace date_time