$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Larry (lknain_at_[hidden])
Date: 2006-09-01 22:01:33
Here is a scheme I tried when first trying to use Boost date-time that would 
approximate the initial request. It is hardly elegant code but it worked for 
me at the time. I haven't needed it in quite awhile.
typedef vector<date> Holidays;
typedef vector<int> WeekendDays;
//-------------------------------------------------------------------------------------
// Calculate number of business days between two dates
//
// Input dates are yyyymmdd strings - sd1 <= sd2
// Holidays is a vector of dates for "holidays"
// WeekenDays is a vector of days of the week considered "weekend" days
//
// Holidays are excluded only if not on a "weekend" day
//-------------------------------------------------------------------------------------
long BusinessDays(const string &sd1,const string &sd2,Holidays 
&holidays,WeekendDays c)
{
    long f, adj, days, startday;
    date d1(from_undelimited_string(sd1));
    date d2(from_undelimited_string(sd2));
    date_duration dd = d2 - d1;
    days = dd.days();
    // Adjust for "weekends" as needed
    f = (long)c.size();
    adj = 0;
    if (f) {
        // Compute adjustment for initial week
        date td = d1;
        date te = d1 + date_duration(7);
        if (te > d2) te = d2;
        date_duration one_day(1);
        for (;td < te;td += one_day) {
            startday = td.day_of_week();
            if (find(c.begin(),c.end(),startday) != c.end()) {
                adj++;
            }
        }
    }
    days -= ((days / 7) * f + adj);
    // Adjust for "other" days like holidays from "calendar"
    date_period dp(d1,d2);
    Holidays::iterator hli;
    for (hli = holidays.begin();hli != holidays.end();hli++) {
        if (dp.contains(*hli)) {
            startday = (*hli).day_of_week();
            if (find(c.begin(),c.end(),startday) == c.end()) {
                days--;
            }
        }
    }
    return days;
}
Larry
----- Original Message ----- 
From: "Jeff Garland" <jeff_at_[hidden]>
To: <boost-users_at_[hidden]>
Sent: Friday, September 01, 2006 11:31 AM
Subject: Re: [Boost-users] Date calculations with exclusions
> kingos_at_[hidden] wrote:
>> Hi,
>>
>> I am hoping to use boost::date_time to do some date calculations. What I 
>> want to do is
>> basically work out the number of days to a given date with various 
>> exclusions applied.
>>
>> eg.
>>
>> How many working days are there to christmas?
>>
>> using namespace boost::gregorian;
>>
>> int CalculateDaysToChristmas()
>> {
>> date_period someHoliday(date(2006, Dec, 01), date_duration(1));
>>
>>     date today(2006, Sep, 1);
>>
>>     date christmas(2006, Dec, 25);
>>
>>     int days = 0;
>>     for (day_iterator i = today; i != christmas; ++i)
>>     {
>>         if (is_weekday(*i) && !someHoliday.contains(*i))
>>             ++days;
>>     }
>>
>>     return days;
>> }
>>
>> However, I can't find a simply way to work out is_weekday ...
>
> Here's something I have laying around that does this:
>
> using namespace boost::gregorian;
>   inline
>   bool is_weekday(date d)
>   {
>     greg_weekday dow = d.day_of_week();
>     if (dow == Saturday || dow == Sunday) {
>       return false;
>     }
>     return true;
>   }
>
>   inline
>   int weekdays_in_period(const date_period& dp)
>   {
>     day_iterator i(dp.begin());
>     int count = 0;
>     while ( i <= dp.end()) {
>       if (is_weekday(*i)) {
>         count++;
>       }
>       ++i;
>     }
>     return count;
>   }
>
>
> When I'm writing this sort of code I also like to hide the details of 
> getting
> the date period.  Something like this:
>
> class holiday_period : public date_period
> {
>  public:
>   holiday_period(const date& holiday_date) :
>     date_period(day_clock::local_day(), holiday_date)
>   {};
>  private:
> };
>
> Now you can write:
>
>    date christmas(2006, Dec, 25);
>    hoiday_period hp(christmas);
>    days days_until = weekdays_in_period(hp);
>
>> Secondly, is there some way to put every sunday in as a date_period?
>
> Not sure what you have in mind here?
>
>> Thirdly, this doesn't seem very optimal ... is there a better way of 
>> doing this?
>
> No doubt, this is suboptimal.  A better way to do this is to figure out is 
> to
> take advantage of the fact that a week is exactly 7 days and each week
> contains 5 non-weekend days (note that the weekend days aren't Sat/Sun in 
> all
> parts of the world).  The tricky part is that you have to account for the
> boundary conditions of landing on a weekend, or starting on a weekend, 
> less
> than one week, etc.  My guess is it would take an hour or two to really 
> write
> it up and test all the cases.  Anyway, I've not had a real reason to ever
> write this one up.  Contributions always welcome ;-)
>
> Jeff
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://listarchives.boost.org/mailman/listinfo.cgi/boost-users
>