Opened 12 years ago
Last modified 11 years ago
#10863 closed defect
fix to_datetime() when given timezone naive datetime input — at Initial Version
Reported by: | Christian Boos | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | 0.12.5 |
Component: | general | Version: | 0.12-stable |
Severity: | normal | Keywords: | datetime pytz timezone |
Cc: | Branch: | ||
Release Notes: | |||
API Changes: | |||
Internal Changes: |
Description
While looking at some specifics of the trac.util.datefmt.to_datetime
function, I discovered that a particular usage pattern is problematic with pytz timezones:
>>> from trac.util.datefmt import * >>> from datetime import datetime >>> t = to_datetime(datetime(2012,1,1), timezone("Europe/Paris")) >>> t.utcoffset() datetime.timedelta(0, 540)
(from gmessage:trac-dev:V0HeDyfa_pk/5r33UatF3nEJ)
The utcoffset()
plays a role when converting a time to the number of ms (to_utimestamp()
). Here, it has a value of 9 minutes, which is quite wrong for our purpose.
The workaround is to always specify a timezone aware datetime
object to to_datetime
, but this is not documented, and shouldn't be necessary either (assuming a timezone naive datetime
should actually be the same as a datetime
in utc
).
The following should
-
trac/util/datefmt.py
diff --git a/trac/util/datefmt.py b/trac/util/datefmt.py index b59a276..d88d6b1 100644
a b def to_datetime(t, tzinfo=None): 66 66 elif isinstance(t, datetime): 67 67 if tzinfo is not None: 68 68 if t.tzinfo is None: 69 t = t .replace(tzinfo=tzinfo)69 t = tzinfo.localize(t) 70 70 else: 71 71 t = tzinfo.normalize(t.astimezone(tzinfo)) 72 72 return t
With this change, the t.utcoffset()
for the example above would give 3600 seconds, i.e. the one hour we would expect.