Skip to content

Commit e645262

Browse files
iwalucasauvipy
andauthored
Consider server timezone on _get_timezone_offset instead of django's settings (#886)
* Scheduler shouldnt ignore specific times on crontab * Use aware_now to get server's timezone rather than using django's * Update schedulers.py * Update schedulers.py * Update schedulers.py * Update django_celery_beat/schedulers.py * adding tests --------- Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
1 parent 0c5b652 commit e645262

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

django_celery_beat/schedulers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from django.db.models import Case, F, IntegerField, Q, When
2020
from django.db.models.functions import Cast
2121
from django.db.utils import DatabaseError, InterfaceError
22-
from django.utils import timezone
2322
from kombu.utils.encoding import safe_repr, safe_str
2423
from kombu.utils.json import dumps, loads
2524

@@ -364,7 +363,9 @@ def _get_timezone_offset(self, timezone_name):
364363
int: The hour offset
365364
"""
366365
# Get server timezone
367-
server_tz = timezone.get_current_timezone()
366+
server_time = aware_now()
367+
# Use server_time.tzinfo directly if it is already a ZoneInfo instance
368+
server_tz = server_time.tzinfo if isinstance(server_time.tzinfo, ZoneInfo) else ZoneInfo(str(server_time.tzinfo))
368369

369370
if isinstance(timezone_name, ZoneInfo):
370371
timezone_name = timezone_name.key

t/unit/test_schedulers.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,3 +1453,55 @@ def mock_apply_async(*args, **kwargs):
14531453
ma.run_tasks(self.request, PeriodicTask.objects.filter(id=self.m1.id))
14541454
assert 'periodic_task_name' in self.captured_headers
14551455
assert self.captured_headers['periodic_task_name'] == self.m1.name
1456+
1457+
1458+
1459+
@pytest.mark.django_db
1460+
class test_timezone_offset_handling:
1461+
def setup_method(self):
1462+
self.app = patch("django_celery_beat.schedulers.current_app").start()
1463+
1464+
def teardown_method(self):
1465+
patch.stopall()
1466+
1467+
@patch("django_celery_beat.schedulers.aware_now")
1468+
def test_server_timezone_handling_with_zoneinfo(self, mock_aware_now):
1469+
"""Test handling when server timezone is already a ZoneInfo instance."""
1470+
1471+
# Create a mock scheduler with only the methods we need to test
1472+
class MockScheduler:
1473+
_get_timezone_offset = schedulers.DatabaseScheduler._get_timezone_offset
1474+
1475+
s = MockScheduler()
1476+
1477+
tokyo_tz = ZoneInfo("Asia/Tokyo")
1478+
mock_now = datetime(2023, 1, 1, 12, 0, 0, tzinfo=tokyo_tz)
1479+
mock_aware_now.return_value = mock_now
1480+
1481+
# Test with a different timezone
1482+
new_york_tz = "America/New_York"
1483+
offset = s._get_timezone_offset(new_york_tz) # Pass self explicitly
1484+
1485+
# Tokyo is UTC+9, New York is UTC-5, so difference should be 14 hours
1486+
assert offset == 14
1487+
assert mock_aware_now.called
1488+
1489+
@patch("django_celery_beat.schedulers.aware_now")
1490+
def test_timezone_offset_with_zoneinfo_object_param(self, mock_aware_now):
1491+
"""Test handling when timezone_name parameter is a ZoneInfo object."""
1492+
1493+
class MockScheduler:
1494+
_get_timezone_offset = schedulers.DatabaseScheduler._get_timezone_offset
1495+
1496+
s = MockScheduler()
1497+
1498+
tokyo_tz = ZoneInfo("Asia/Tokyo")
1499+
mock_now = datetime(2023, 1, 1, 12, 0, 0, tzinfo=tokyo_tz)
1500+
mock_aware_now.return_value = mock_now
1501+
1502+
# Test with a ZoneInfo object as parameter
1503+
new_york_tz = ZoneInfo("America/New_York")
1504+
offset = s._get_timezone_offset(new_york_tz) # Pass self explicitly
1505+
1506+
# Tokyo is UTC+9, New York is UTC-5, so difference should be 14 hours
1507+
assert offset == 14

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy