So it turns out that DT.pm has basically been buggy with regards to date
math for any timezone with a DST change basically forever.
The problem is that sometimes people want to do math in terms of the local
time (the clock display time) and sometimes in terms of UTC time (the
actual passing of time based on the atomic clock).
So here's a couple examples:
2005-06-15T00:00:00 America/Chicago
+ 6 (months)
--------------------------------------
= 2005-12-15T00:00:00 America/Chicago
This result is quite reasonable from a user perspective. They added six
months, and the time portion does not change at all.
But in fact, one hour less than 6 months has passed because of the DST
change, so another reasonable result might be this:
2005-06-15T00:00:00 America/Chicago
+ 6 (months)
--------------------------------------
= 2005-12-14T23:00:00 America/Chicago
In this case, we added 6 months to the _UTC_ time and the displayed clock
time changes, due to DST. This is also a reasonable result, since it
reflects the actual amount of time that has passed.
Similarly, subtracting one datetime from another has similar issues:
2005-12-15T00:00:00 America/Chicago
- 2005-06-15T00:00:00 America/Chicago
--------------------------------------
= 6 (months)
Again, this makes sense if you just look at the clock times, but ...
2005-12-15T00:00:00 America/Chicago
- 2005-06-15T00:00:00 America/Chicago
--------------------------------------
= 5 23
months hours
This is the actual amount of UTC time that has passed.
Hopefully this all clear. So what's the upshot of this for DateTime.pm?
Right now all of its math methods operate on the UTC time. This leads to
a lot of bug reports, so its clearly not what people want.
But when it used to operate on local times, some people complained because
it led to other surprising results.
So what's the solution?
I think we need to have dual sets of methods, one for local and one for
UTC:
* add
* add_utc
* subtract_datetime
* subtract_datetime_utc
I think the default should be to operate on the local time, since that's
probably less surprising for _most_ people.
Originally I was thinking that the DT::Duration object should also carry
around a "UTC or local" flag, but it occurs to me that that is pointless
since you can control which type of math you want by calling the right
method.
OTOH, this means that if you get a duration object passed in to your code,
you have no way of knowing what operation produced it. Hmm, so now I'm
thinking that we should store the flag, at least for the purposes of
display/introspection (for example, DT::F::Duration might find this
useful).
But DT.pm won't check this flag, it'll always just do the type of math
specified by the method you call.
Ok, that's my summary of the proposed API changes. Feedback is very
welcome.
BTW, I'm playing with some Perl6 DT stuff, and my plan is to architect the
classes fairly differently, in large because of this problem. That can be
discussed in a separate thread if folks are interested.
-dave
/*===================================================
VegGuide.Org www.BookIRead.com
Your guide to all that's veg. My book blog
===================================================*/