Opened 2 months ago

Closed 2 months ago

Last modified 2 months ago

#35858 closed Bug (invalid)

Issue with make_aware Function Causing Timezone Conversion Errors with pytz

Reported by: acture Owned by: acture
Component: Utilities Version: 5.0
Severity: Normal Keywords: timezone
Cc: acture Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

I have encountered a problem with the make_aware function used in Django for converting naive datetime objects to aware datetime objects.

Steps to Reproduce:

  1. Create a naive datetime object that falls within a DST transition period.
  2. Call make_aware with this naive datetime and a timezone that observes DST.
  3. Observe the incorrect timezone conversion.

Code Snippet to reproduce issue

from datetime import datetime
import pytz
from django.utils.timezone import make_aware

time_str = "2024-10-22"
time_obj = datetime.strptime(time_str, "%Y-%m-%d")
shanghai_tz = pytz.timezone("Asia/Shanghai")

pytz_aware_time = shanghai_tz.localize(time_obj)
django_aware_time = make_aware(time_obj, timezone=shanghai_tz)

print(f"pytz_aware_time: {pytz_aware_time}")
print(f"django_aware_time: {django_aware_time}")

Output:
pytz_aware_time: 2024-10-22 00:00:00+08:00
django_aware_time: 2024-10-22 00:00:00+08:06

Environment:

  • Django version: Django 5.0.9
  • Python version: Python 3.12
  • Operating system: macOS Sonoma 14.5

Change History (3)

comment:1 by Sarah Boyce, 2 months ago

Resolution: invalid
Status: assignedclosed
Summary: Issue with make_aware Function Causing Timezone Conversion ErrorsIssue with make_aware Function Causing Timezone Conversion Errors with pytz

Since Django 4.0, zoneinfo is the default timezone implementation.
I believe you shouldn't be using pytz here

from datetime import datetime
from django.utils.timezone import make_aware
from zoneinfo import ZoneInfo

time_str = "2024-10-22"
time_obj = datetime.strptime(time_str, "%Y-%m-%d")
shanghai_tz = ZoneInfo("Asia/Shanghai")

django_aware_time = make_aware(time_obj, timezone=shanghai_tz)
print(f"django_aware_time: {django_aware_time}")

Returns django_aware_time: 2024-10-22 00:00:00+08:00

in reply to:  1 comment:2 by acture, 2 months ago

I believe adding a warning is still necessary.

It could can help developers recognize that pytz is no longer recommended, and understand the potential risks of continuing to use pytz.

Not all developers stay up-to-date with the latest changes in Django. Some developers might not even be aware that zoneinfo has replaced pytz as the default timezone implementation. A warning would serve as an educational tool, ensuring that both new and experienced developers understand this shift.

Without a clear warning, developers might continue using pytz simply because it's familiar, not knowing that Django has moved on to zoneinfo. A warning helps inform them of best practices moving forward. By adding a warning, we can prompt developers to test and verify that their timezone-related logic behaves as expected

Replying to Sarah Boyce:

Since Django 4.0, zoneinfo is the default timezone implementation.
I believe you shouldn't be using pytz here

from datetime import datetime
from django.utils.timezone import make_aware
from zoneinfo import ZoneInfo

time_str = "2024-10-22"
time_obj = datetime.strptime(time_str, "%Y-%m-%d")
shanghai_tz = ZoneInfo("Asia/Shanghai")

django_aware_time = make_aware(time_obj, timezone=shanghai_tz)
print(f"django_aware_time: {django_aware_time}")

Returns django_aware_time: 2024-10-22 00:00:00+08:00

comment:3 by Mariusz Felisiak, 2 months ago

Not all developers stay up-to-date with the latest changes in Django. Some developers might not even be aware that zoneinfo has replaced pytz as the default timezone implementation. A warning would serve as an educational tool, ensuring that both new and experienced developers understand this shift.

There was a deprecation warning for 3 Django versions about this change.

Note: See TracTickets for help on using tickets.
Back to Top