datetime1 - datetime0, same tzinfo, different dst

Tim Peters tim.one at comcast.net
Sun Jul 27 11:33:01 EDT 2003


[Stéphane Bidoul]
> I'm playing around with the new datetime module.
> Looks nice, and a welcome addition to the core...
>
> I've a question about a behaviour of
> substractions of "aware" datetimes around DST switch.
>
> The problem is that the difference gives wrong results
> when the 2 datetimes have the same tzinfo instance,
> but have different utc offsets due to DST.

According to the docs, the results are correct <wink>.

> The behaviour is consistent with what the documentation
> says, but I find it quite unintuitive.
>
> Is that the designed behaviour?

Yes.  You can read Guido's thinking here:

    http://www.zope.org/Members/fdrake/DateTimeWiki/NaiveTime

and here:

    http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo

and at other less relevant pages in that Wiki.

The first link explains that when you do

    datetime2 = datetime1 + timedelta

there are 3 different answers people *might* expect.  Guido picked the one
that seemed best to him (if, say, timedelta is 24 hours, move to the same
clock time on the next day, ignoring the deviations from that result
accounting for DST boundaries would entail).  The meaning of

    timedelta = datetime2 - datetime1

when datetime2 and datetime1 are in the same time zone follows from that
decision.  Throughout the implementation, combining (regardless of the
specific operation involved) two datetimes with the same tzinfo members
effectively treats them as naive datetimes.

> ...
> Well, it's actually consistent with the documentation
> that says that no utc conversion is done when the 2 dates
> have the same tzinfo, but I find it somewhat unintuitive
> in this case.

Yup, and other people (particularly Guido <wink>) would find it unintuitive
if it did what you expected instead.  If it's any consolation, I originally
implemented datetime to act the way you expect in this regard, but changed
it at Guido's request.  It seems odd to me too that whether time zone
adjustments occur depend on whether the tzinfo members are or aren't the
same.

> ...
> So in this case it works, but should we create
> new tzinfo instances for each datetime we create.

No, if you want DST-aware datetime differences, you can get them by
converting to UTC first; or, effectively the same thing, instead of

    d1 - d2

do

    (d1 - d1.utcoffset()) - (d2 - (d2.utcoffset())

You already figured that out, of course -- that's what your

    d1.astimezone(utc) - d0.astimezone(utc)

did, and that's the intended way to do it (provided you've written a utc
class to model UTC).

> The sample tzinfo module seems to imply they
> are best used as singletons.

Yes, for purposes of determining whether two datetimes are "in the same time
zone", their tzinfo members are compared by object identity, so they pretty
much have to be singletons to work as intended.






More information about the Python-list mailing list