Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-04-14 07:56:43


"Jeff Garland" <jeff_at_[hidden]> writes:

> 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).

reasonable

> 2) Throw an exception if an invalid date is generated. That lets the client
> app just deal with it.

reasonable

> 3) Set the returned date to 'not_a_date_time' if an invalid date is
> generated.

marginally reasonable.
very inconvenient.

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

I'm not comfortable with it. It's too nonuniform.

>
> 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.

Hang on a sec. I think a variation of this one isn't so bad: if you
ask for the day when it's invalid, it rolls back to the end of the
month (and there's another way to find out the day number that's
really stored). The result is sort of like #1, but where chained
calculations magically "do the right thing".

> 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.

... but it's warm in here! ...

> 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 ;-)

Some people like the idea of growing old at 1/4 speed.

> 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

That looks like what I was suggesting above.

> 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.

Hmpf; too much parameterization? I guess I'd be inclined to rely on
people to know that you can't iterate through "end of months" by
simply repeatedly adding a month to a date. You have to iterate over
months and then pass through an end-of-month transformation.

>> 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.

Yep. I like your iterator's behavior.

> 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...

I think making the behavior consistent with month_iterator can be the
only right answer. If you were to change the behavior of
month_iterator I'd still think that (but please don't! It's already
perfect! ;->)

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

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