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
===================================================*/

Reply via email to