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
& d
) const
28 // why is 'd' a parameter???
29 // fix compiler warnings
31 return duration_type(f_
);
33 duration_type
get_neg_offset(const date_type
& d
) const
35 // fix compiler warnings
37 return duration_type(-f_
);
44 //! Provides calculation to find next nth month given a date
45 /*! This adjustment function provides the logic for 'month-based'
46 * advancement on a ymd based calendar. The policy it uses
47 * to handle the non existant end of month days is to back
48 * up to the last day of the month. Also, if the starting
49 * date is the last day of a month, this functor will attempt
50 * to adjust to the end of the month.
53 template<class date_type
>
57 typedef typename
date_type::duration_type duration_type
;
58 typedef typename
date_type::calendar_type cal_type
;
59 typedef typename
cal_type::ymd_type ymd_type
;
60 typedef typename
cal_type::day_type day_type
;
62 month_functor(int f
) : f_(f
), origDayOfMonth_(0) {}
63 duration_type
get_offset(const date_type
& d
) const
65 ymd_type
ymd(d
.year_month_day());
66 if (origDayOfMonth_
== 0) {
67 origDayOfMonth_
= ymd
.day
;
68 day_type
endOfMonthDay(cal_type::end_of_month_day(ymd
.year
,ymd
.month
));
69 if (endOfMonthDay
== ymd
.day
) {
70 origDayOfMonth_
= -1; //force the value to the end of month
73 typedef date_time::wrapping_int2
<short,1,12> wrap_int2
;
74 typedef typename
wrap_int2::int_type int_type
;
75 wrap_int2
wi(ymd
.month
);
76 //calc the year wrap around, add() returns 0 or 1 if wrapped
77 int_type year
= wi
.add(static_cast<int_type
>(f_
));
78 year
= static_cast<int_type
>(year
+ ymd
.year
); //calculate resulting year
79 // std::cout << "trace wi: " << wi.as_int() << std::endl;
80 // std::cout << "trace year: " << year << std::endl;
81 //find the last day for the new month
82 day_type
resultingEndOfMonthDay(cal_type::end_of_month_day(year
, wi
.as_int()));
83 //original was the end of month -- force to last day of month
84 if (origDayOfMonth_
== -1) {
85 return date_type(year
, wi
.as_int(), resultingEndOfMonthDay
) - d
;
87 day_type dayOfMonth
= origDayOfMonth_
;
88 if (dayOfMonth
> resultingEndOfMonthDay
) {
89 dayOfMonth
= resultingEndOfMonthDay
;
91 return date_type(year
, wi
.as_int(), dayOfMonth
) - d
;
93 //! Returns a negative duration_type
94 duration_type
get_neg_offset(const date_type
& d
) const
96 ymd_type
ymd(d
.year_month_day());
97 if (origDayOfMonth_
== 0) {
98 origDayOfMonth_
= ymd
.day
;
99 day_type
endOfMonthDay(cal_type::end_of_month_day(ymd
.year
,ymd
.month
));
100 if (endOfMonthDay
== ymd
.day
) {
101 origDayOfMonth_
= -1; //force the value to the end of month
104 typedef date_time::wrapping_int2
<short,1,12> wrap_int2
;
105 typedef typename
wrap_int2::int_type int_type
;
106 wrap_int2
wi(ymd
.month
);
107 //calc the year wrap around, add() returns 0 or 1 if wrapped
108 int_type year
= wi
.subtract(static_cast<int_type
>(f_
));
109 year
= static_cast<int_type
>(year
+ ymd
.year
); //calculate resulting year
110 //find the last day for the new month
111 day_type
resultingEndOfMonthDay(cal_type::end_of_month_day(year
, wi
.as_int()));
112 //original was the end of month -- force to last day of month
113 if (origDayOfMonth_
== -1) {
114 return date_type(year
, wi
.as_int(), resultingEndOfMonthDay
) - d
;
116 day_type dayOfMonth
= origDayOfMonth_
;
117 if (dayOfMonth
> resultingEndOfMonthDay
) {
118 dayOfMonth
= resultingEndOfMonthDay
;
120 return date_type(year
, wi
.as_int(), dayOfMonth
) - d
;
124 mutable short origDayOfMonth_
;
128 //! Functor to iterate a over weeks
129 template<class date_type
>
133 typedef typename
date_type::duration_type duration_type
;
134 typedef typename
date_type::calendar_type calendar_type
;
135 week_functor(int f
) : f_(f
) {}
136 duration_type
get_offset(const date_type
& d
) const
138 // why is 'd' a parameter???
139 // fix compiler warnings
141 return duration_type(f_
*calendar_type::days_in_week());
143 duration_type
get_neg_offset(const date_type
& d
) const
145 // fix compiler warnings
147 return duration_type(-f_
*calendar_type::days_in_week());
153 //! Functor to iterate by a year adjusting for leap years
154 template<class date_type
>
158 //typedef typename date_type::year_type year_type;
159 typedef typename
date_type::duration_type duration_type
;
160 year_functor(int f
) : _mf(f
* 12) {}
161 duration_type
get_offset(const date_type
& d
) const
163 return _mf
.get_offset(d
);
165 duration_type
get_neg_offset(const date_type
& d
) const
167 return _mf
.get_neg_offset(d
);
170 month_functor
<date_type
> _mf
;
174 } }//namespace date_time