Closed warrickball closed 1 month ago
I'm unsure what is your local timezone but datetime.astimezone()
should be used rather than datetime.replace(tzinfo=...)
.
>>> from datetime import datetime
>>> from babel.dates import get_timezone
>>> t = datetime(2024, 5, 9, 12, 30)
>>> localtz = get_timezone()
>>> localtz
<DstTzInfo 'Asia/Tokyo' LMT+9:19:00 STD>
>>>
>>> t.astimezone(localtz)
datetime.datetime(2024, 5, 9, 12, 30, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)
>>> t.astimezone(localtz).astimezone(get_timezone('Europe/London'))
datetime.datetime(2024, 5, 9, 4, 30, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>>
>>> t.replace(tzinfo=localtz)
datetime.datetime(2024, 5, 9, 12, 30, tzinfo=<DstTzInfo 'Asia/Tokyo' LMT+9:19:00 STD>)
>>> t.replace(tzinfo=localtz).astimezone(get_timezone('Europe/London'))
datetime.datetime(2024, 5, 9, 4, 11, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
What is your end goal here? 🤔
Also note that get_timezone()
is just a simple wrapper for pytz.timezone()
(if pytz
is installed) or zoneinfo.ZoneInfo()
; there's nothing Babel-specific about this, really...
This is something I isolated from a MkDocs plugin I've used called mkdocs-git-revision-date-localized-plugin. Specifically, these four lines (dates.py:29-32
) are used to generate the local timestamp that appears on the pages:
utc_revision_date = datetime.fromtimestamp(int(unix_timestamp), tz=timezone.utc)
loc_revision_date = utc_revision_date.replace(
tzinfo=get_timezone("UTC")
).astimezone(get_timezone(time_zone))
I accept that this might be deeper than Babel but I started by digging into the code for the plugin. I'll see if I can reproduce directly with pytz.timezone
or zoneinfo.ZoneInfo
.
I'm happy to close this as a misuse of the functions that doesn't actually appear anywhere. The code in the plugin doesn't reproduce the error anyway, presumably, because it uses .replace(tzinfo=get_timezone("UTC"))
rather than .replace(tzinfo=get_timezone())
.
utc_revision_date = datetime.fromtimestamp(int(unix_timestamp), tz=timezone.utc) loc_revision_date = utc_revision_date.replace( tzinfo=get_timezone("UTC") ).astimezone(get_timezone(time_zone))
You could change that code like the following, simply:
loc_revision_date = datetime.fromtimestamp(int(unix_timestamp), tz=get_timezone(time_zone))
Overview Description
If I convert a
datetime
object to the timezone Europe/London, the time is (largely) unchanged, with no daylight saving applied. The conversion works correctly for a few other timezones I tried (GB, Europe/Berlin, Africa/Johannesburg).I also get an unexpected 1 minute offset.
Reproducibility
Additional Information
Babel 2.15.0 via pip, pytz 2024.1 via package manager (dnf), Python 3.12.3, Fedora 39.