Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2004-04-13 23:05:37


On Tue, 13 Apr 2004 18:30:46 -0700, Robert Bell wrote

Whew, looks like a bad day to be away from my email ;-)

> Powell, Gary wrote:
> >>Bob Bell wrote:
> >>The interpretation that makes sense to me is: adding one month means the
> >>same day of the next month, unless the date's not valid, in which case I
> >>expect moving backwards to the latest date of said month. That's what
> >>humans do when you say "next month", so I would think anything else
> >>would be surprising.

I think that 'least suprising' is actually determined by the application. I
can see at least several 'reasonable behaviors'.
1) Rollback to the end of the month (as Gary points out chained calculation
gets weird here).
2) Throw an exception if an invalid date is generated. That lets the client
app just deal with it.
3) Set the returned date to 'not_a_date_time' if an invalid date is generated.

I think Rob's add 30 days on invalid is less common, but not unreasonable.

In the unreasonable camp I would include:
1) Artificially extend the short months with virtual days -- Yes, I'm told
that in some domains they use this technique.

Of course as soon as I did something in this domain I would be forced to
change my mind on how 'unreasonable' it is. So for me it is becoming ever more
clear that I was right to stay out if this very dark cave in the first place.

BTW, if you are born on Feb 29th of a leap year, when do you celebrate your
birthday? You can only do it on the day of birth every 4 years ;-)

> >
> > That would surprise me as well.
> >
> > date = January 30;
> >
> > add_month(date);
> > add_month(date);
> >
> > date == March 30 ? Not March 28/29 No?
> >
> > Which means of course a lot of state has to be held by date, because
>otherwise February does rounding. As in the number of days until the
>end of the month.

Not going to happen...

> I don't have a problem with your example because it shows two
> discrete operations. I don't expect the date to remember its history
> and apply future operations based on that history, which is what
> you'd need in order to end up with March 30. Otherwise, the date's
> behavior becomes very hard to predict, not to mention implement.

It turns out that the month_iterator in fact does implement this logic. So
starting on Jan 31, 2000 (a leap year) and incrementing by 1 you get:
2000-Jan-31
2000-Feb-29
2000-Mar-31
2000-Apr-30
2000-May-31

By starting in a 'long month' it effectively snaps to the end of the month.

If you start on Feb 29 you get:
2000-Feb-29
2000-Mar-29
2000-Apr-29

Which almost never reaches the end of the month. All of this is the reason
that the month_iterator template allows you to substitute an alternate
algorithm of your liking.
 
> I just wouldn't use the two discrete add_months in your example
> _unless_ I wanted the behavior you see as surprising. Otherwise, I'd
> use
>
> add_month(date, 2);

I can see the bug report now:

void f(date& d)
{
  //...
  d = add_month(d);
}

//somewhere else in program
date d(...);
f(d);
f(d); //oops I really wanted add_month(d,2) behavior

Point is that in a 5 line program it is obvious -- in a million line program
not necessarily so.

This email thread seems to be writing the repsonse to the FAQ:
Q: Why is there no add_month function in the library?
A: Because we can't agree on what it means...

Jeff


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