Are there any "correct" implementations of tzinfo?

Akira Li 4kir4.1i at gmail.com
Sat Sep 12 15:32:45 EDT 2015


Random832 <random832 at fastmail.com> writes:

> I was trying to find out how arithmetic on aware datetimes is "supposed
> to" work, and tested with pytz. When I posted asking why it behaves this
> way I was told that pytz doesn't behave correctly according to the way
> the API was designed. The tzlocal module, on the other hand, appears to
> simply defer to pytz on Unix systems.
>
> My question is, _are_ there any correct reference implementations that
> demonstrate the proper behavior in the presence of a timezone that has
> daylight saving time transitions?

The only way to get correct[*] results now is to use *pytz*. PEP 495
might allow to fix some of non-avoidable (at the moment) bugs[1] in
*dateutil* (another library that provides access to the tz database).

Some core Python developers feel that pytz model does not implement the
initial datetime design intent: both naive and timezone-aware datetime
objects use the same model for arihtmetic (though the actual
implementation contains a mix: aware datetime objects are treated as
naive datetime objects in some cases but in others they behave as though
they are utc-based).

pytz model: aware datetime objects behave *as if* they are converted to
UTC during arithmetic operations, comparisons, etc:

  # d = datetime.now(tz)
  (d2 - d1) == (d2.astimezone(utc) - d1.astimezone(utc))
  tz.normalize(d + delta) == (d.astimezone(utc) + delta).astimezone(tz)

tz.normalize() is necessary to get the correct local time (utc time is
correct even without tz.normalize()) in presence of DST transitions (or
other changes in UTC offset for any reason).

Here's how the stdlib implementation behaves at the moment for a
timezone-aware datetime object that represents local time (the only
timezone with a non-fixed utc offset that is available in stdlib):

  # d = datetime.now(utc).astimezone()
  (d2 - d1) == (d2.astimezone(utc) - d1.astimezone(utc))
  (d + delta).astimezone() == (d.astimezone(utc) + delta).astimezone()

If utc offset is fixed then both naive and aware models are the same.

[*] according to the tz database
[1] https://github.com/dateutil/dateutil/issues/112




More information about the Python-list mailing list