Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No daylight saving time applied for Europe/London timezone #1082

Closed
warrickball opened this issue May 9, 2024 · 5 comments
Closed

No daylight saving time applied for Europe/London timezone #1082

warrickball opened this issue May 9, 2024 · 5 comments

Comments

@warrickball
Copy link

warrickball commented May 9, 2024

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

>>> from datetime import datetime
>>> from babel.dates import get_timezone
>>> t = datetime(2024, 5, 9, 12, 30)
>>> t
datetime.datetime(2024, 5, 9, 12, 30)
>>> t.replace(tzinfo=get_timezone()).astimezone(get_timezone('Europe/London'))
datetime.datetime(2024, 5, 9, 12, 30, tzinfo=<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>)
>>> t.replace(tzinfo=get_timezone()).astimezone(get_timezone('GB'))
datetime.datetime(2024, 5, 9, 13, 31, tzinfo=<DstTzInfo 'GB' BST+1:00:00 DST>)
>>> t.replace(tzinfo=get_timezone()).astimezone(get_timezone('Europe/Berlin'))
datetime.datetime(2024, 5, 9, 14, 31, tzinfo=<DstTzInfo 'Europe/Berlin' CEST+2:00:00 DST>)
>>> t.replace(tzinfo=get_timezone()).astimezone(get_timezone('Africa/Johannesburg'))
datetime.datetime(2024, 5, 9, 14, 31, tzinfo=<DstTzInfo 'Africa/Johannesburg' SAST+2:00:00 STD>)

Additional Information

Babel 2.15.0 via pip, pytz 2024.1 via package manager (dnf), Python 3.12.3, Fedora 39.

@jun66j5
Copy link
Contributor

jun66j5 commented May 13, 2024

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>)

@akx
Copy link
Member

akx commented May 15, 2024

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...

@warrickball
Copy link
Author

warrickball commented May 30, 2024

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.

@warrickball
Copy link
Author

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()).

@jun66j5
Copy link
Contributor

jun66j5 commented May 30, 2024

    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))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants