Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:21

0001 #ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___
0002 #define _DATE_TIME_ADJUST_FUNCTORS_HPP___
0003 
0004 /* Copyright (c) 2002,2003 CrystalClear Software, Inc.
0005  * Use, modification and distribution is subject to the
0006  * Boost Software License, Version 1.0. (See accompanying
0007  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
0008  * Author: Jeff Garland, Bart Garst
0009  * $Date$
0010  */
0011 
0012 #include "boost/date_time/date.hpp"
0013 #include "boost/date_time/wrapping_int.hpp"
0014 
0015 namespace boost {
0016 namespace date_time {
0017 
0018 
0019   //! Functor to iterate a fixed number of days
0020   template<class date_type>
0021   class day_functor
0022   {
0023   public:
0024     typedef typename date_type::duration_type duration_type;
0025     day_functor(int f) : f_(f) {}
0026     duration_type get_offset(const date_type&) const
0027     {
0028       return duration_type(f_);
0029     }
0030     duration_type get_neg_offset(const date_type&) const
0031     {
0032       return duration_type(-f_);
0033     }
0034   private:
0035     int f_;
0036   };
0037 
0038 
0039   //! Provides calculation to find next nth month given a date
0040   /*! This adjustment function provides the logic for 'month-based'
0041    *  advancement on a ymd based calendar.  The policy it uses
0042    *  to handle the non existant end of month days is to back
0043    *  up to the last day of the month.  Also, if the starting
0044    *  date is the last day of a month, this functor will attempt
0045    *  to adjust to the end of the month.
0046 
0047    */
0048   template<class date_type>
0049   class month_functor
0050   {
0051   public:
0052     typedef typename date_type::duration_type duration_type;
0053     typedef typename date_type::calendar_type cal_type;
0054     typedef typename cal_type::ymd_type ymd_type;
0055     typedef typename cal_type::day_type day_type;
0056 
0057     month_functor(int f) : f_(f), origDayOfMonth_(0) {}
0058     duration_type get_offset(const date_type& d) const
0059     {
0060       ymd_type ymd(d.year_month_day());
0061       if (origDayOfMonth_ == 0) {
0062         origDayOfMonth_ = ymd.day;
0063         day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
0064         if (endOfMonthDay == ymd.day) {
0065           origDayOfMonth_ = -1; //force the value to the end of month
0066         }
0067       }
0068       typedef date_time::wrapping_int2<short,1,12> wrap_int2;
0069       wrap_int2 wi(ymd.month);
0070       //calc the year wrap around, add() returns 0 or 1 if wrapped
0071       const typename ymd_type::year_type year(static_cast<typename ymd_type::year_type::value_type>(ymd.year + wi.add(f_)));
0072 //       std::cout << "trace wi: " << wi.as_int() << std::endl;
0073 //       std::cout << "trace year: " << year << std::endl;
0074       //find the last day for the new month
0075       day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
0076       //original was the end of month -- force to last day of month
0077       if (origDayOfMonth_ == -1) {
0078         return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
0079       }
0080       day_type dayOfMonth = origDayOfMonth_;
0081       if (dayOfMonth > resultingEndOfMonthDay) {
0082         dayOfMonth = resultingEndOfMonthDay;
0083       }
0084       return date_type(year, wi.as_int(), dayOfMonth) - d;
0085     }
0086     //! Returns a negative duration_type
0087     duration_type get_neg_offset(const date_type& d) const
0088     {
0089       ymd_type ymd(d.year_month_day());
0090       if (origDayOfMonth_ == 0) {
0091         origDayOfMonth_ = ymd.day;
0092         day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
0093         if (endOfMonthDay == ymd.day) {
0094           origDayOfMonth_ = -1; //force the value to the end of month
0095         }
0096       }
0097       typedef date_time::wrapping_int2<short,1,12> wrap_int2;
0098       wrap_int2 wi(ymd.month);
0099       //calc the year wrap around, add() returns 0 or 1 if wrapped
0100       const typename ymd_type::year_type year(static_cast<typename ymd_type::year_type::value_type>(ymd.year + wi.subtract(f_)));
0101       //find the last day for the new month
0102       day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
0103       //original was the end of month -- force to last day of month
0104       if (origDayOfMonth_ == -1) {
0105         return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
0106       }
0107       day_type dayOfMonth = origDayOfMonth_;
0108       if (dayOfMonth > resultingEndOfMonthDay) {
0109         dayOfMonth = resultingEndOfMonthDay;
0110       }
0111       return date_type(year, wi.as_int(), dayOfMonth) - d;
0112     }
0113   private:
0114     int f_;
0115     mutable short origDayOfMonth_;
0116   };
0117 
0118 
0119   //! Functor to iterate a over weeks
0120   template<class date_type>
0121   class week_functor
0122   {
0123   public:
0124     typedef typename date_type::duration_type duration_type;
0125     typedef typename date_type::calendar_type calendar_type;
0126     week_functor(int f) : f_(f) {}
0127     duration_type get_offset(const date_type&) const
0128     {
0129       return duration_type(f_*static_cast<int>(calendar_type::days_in_week()));
0130     }
0131     duration_type get_neg_offset(const date_type&) const
0132     {
0133       return duration_type(-f_*static_cast<int>(calendar_type::days_in_week()));
0134     }
0135   private:
0136     int f_;
0137   };
0138 
0139   //! Functor to iterate by a year adjusting for leap years
0140   template<class date_type>
0141   class year_functor
0142   {
0143   public:
0144     //typedef typename date_type::year_type year_type;
0145     typedef typename date_type::duration_type duration_type;
0146     year_functor(int f) : _mf(f * 12) {}
0147     duration_type get_offset(const date_type& d) const
0148     {
0149       return _mf.get_offset(d);
0150     }
0151     duration_type get_neg_offset(const date_type& d) const
0152     {
0153       return _mf.get_neg_offset(d);
0154     }
0155   private:
0156     month_functor<date_type> _mf;
0157   };
0158 
0159 
0160 } }//namespace date_time
0161 
0162 
0163 #endif
0164