Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2004-04-10 10:00:13


On Sat, 10 Apr 2004 03:43:46 +0100, Val Samko wrote
> I did not find any functions in Date-Time library to add a number of
> months to a given day, or to obtain the last/first day of the month.
> I mean something like
> date add_month(const date&, int month_count);
> date first_date_of_month(const date&);
> date last_date_of_month(const date&);

Ok, sure. There are some examples that show how to do some of this.

> I understand that I can use the month_iterator instead
> of add_month, and end_of_month_day instead of
> last_date_of_month, but since the functionality I described
> is heavily used in some applications (accounting for instance),
> it would be much simpler just to call add_month, ... functions.
>
> Is there any particular reason why they are not provided?

No, not really -- lack of customer request, basically. add_month is a bit
complicated in that it is unclear the desired behavior of adding into the
'ragged month end'. Basically the issue is:

date d1(2004,Jan,28);
date r1 = add_month(d1,1); //2004-Feb-28, fine
date d2(2004,Jan,31);
date r2 = add_month(d2,1); //presumably we want to back up to Feb 29?
date r3 = add_month(d2,13); //presumably we want to back up to Feb 28?

So given that this solution works for your domain, the library does have a
solution which is unfortunately only documented in the iterator.

Here is how I would write the 3 functions you are asking for:

namespace boost {
namespace gregorian {

date first_date_of_month(const date& orig)
{
  return date(orig.year(), orig.month(), 1);
}

date last_date_of_month(const date& orig)
{
  
  int day = gregorian_calendar::end_of_month_day(orig.year(),orig.month());
  return date(orig.year(), orig.month(), day);
}

date add_month(const date& d, int months)
{
  typedef boost::date_time::month_functor<date> add_month_functor;
  add_month_functor mf(months);
  return (d + mf.get_offset(d));
}

}}

Of course the other option would be to include these in the date itself so you
could write:

  date d(2004, Jan, 10);
  date fd = d.first_date_of_month();
  date ld = d.last_date_of_month();

Do you prefer the oo style?

For add month we could do:

  date next = ld.add_month(13);

although the prefered syntax for add_month would actually be something like:

  date next = ld + months(13);

There are some technical complications with the last syntax, but it should be
doable given some time ;-) Thoughts?

Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk