fix: make a few datetime manipulations timezone-aware (#4755)

* fix: set tz when passing a date to timesince_days filter

* fix: fill in tz for a constructed datetime in idindex/index.py

* test: simplify double-negatives in test assertions

* test: fix I-D expiration test cases to be tz aware

* fix: use tz-aware comparisons for in_draft_expire_freeze method

* test: fix tz used for timesince_days filter test case
This commit is contained in:
Jennifer Richards 2022-11-15 09:55:13 -04:00 committed by GitHub
parent 36bbc9bc08
commit 0c458ef048
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 10 deletions

View file

@ -73,10 +73,10 @@ def in_draft_expire_freeze(when=None):
d = meeting.get_second_cut_off() d = meeting.get_second_cut_off()
# for some reason, the old Perl code started at 9 am # for some reason, the old Perl code started at 9 am
second_cut_off = datetime.datetime.combine(d, datetime.time(9, 0)) second_cut_off = d.replace(hour=9, minute=0, second=0, microsecond=0)
d = meeting.get_ietf_monday() d = meeting.get_ietf_monday()
ietf_monday = datetime.datetime.combine(d, datetime.time(0, 0)) ietf_monday = datetime.datetime.combine(d, datetime.time(0, 0), tzinfo=meeting.tz())
return second_cut_off <= when < ietf_monday return second_cut_off <= when < ietf_monday

View file

@ -5,6 +5,7 @@
import datetime import datetime
import re import re
from urllib.parse import urljoin from urllib.parse import urljoin
from zoneinfo import ZoneInfo
from django import template from django import template
from django.conf import settings from django.conf import settings
@ -316,9 +317,18 @@ def underline(string):
@register.filter(name='timesince_days') @register.filter(name='timesince_days')
def timesince_days(date): def timesince_days(date):
"""Returns the number of days since 'date' (relative to now)""" """Returns the number of days since 'date' (relative to now)
>>> timesince_days(timezone.now() - datetime.timedelta(days=2))
2
>>> tz = ZoneInfo(settings.TIME_ZONE)
>>> timesince_days(timezone.now().astimezone(tz).date() - datetime.timedelta(days=2))
2
"""
if date.__class__ is not datetime.datetime: if date.__class__ is not datetime.datetime:
date = datetime.datetime(date.year, date.month, date.day) date = datetime.datetime(date.year, date.month, date.day, tzinfo=ZoneInfo(settings.TIME_ZONE))
delta = timezone.now() - date delta = timezone.now() - date
return delta.days return delta.days

View file

@ -644,11 +644,19 @@ class ExpireIDsTests(DraftFileMixin, TestCase):
second_cut_off = meeting.get_second_cut_off() second_cut_off = meeting.get_second_cut_off()
ietf_monday = meeting.get_ietf_monday() ietf_monday = meeting.get_ietf_monday()
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), datetime.time(0, 0, 0)))) self.assertFalse(in_draft_expire_freeze((second_cut_off - datetime.timedelta(days=7)).replace(hour=0, minute=0, second=0)))
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, datetime.time(0, 0, 0)))) self.assertFalse(in_draft_expire_freeze(second_cut_off.replace(hour=0, minute=0, second=0)))
self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), datetime.time(0, 0, 0)))) self.assertTrue(in_draft_expire_freeze((second_cut_off + datetime.timedelta(days=7)).replace(hour=0, minute=0, second=0)))
self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), datetime.time(0, 0, 0)))) self.assertTrue(in_draft_expire_freeze(
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0)))) datetime.datetime.combine(
ietf_monday - datetime.timedelta(days=1),
datetime.time(0, 0, 0),
tzinfo=datetime.timezone.utc,
)
))
self.assertFalse(in_draft_expire_freeze(
datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0), tzinfo=datetime.timezone.utc)
))
def test_warn_expirable_drafts(self): def test_warn_expirable_drafts(self):
from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft

View file

@ -270,7 +270,7 @@ def active_drafts_index_by_group(extra_values=()):
groups = [g for g in groups_dict.values() if hasattr(g, "active_drafts")] groups = [g for g in groups_dict.values() if hasattr(g, "active_drafts")]
groups.sort(key=lambda g: g.acronym) groups.sort(key=lambda g: g.acronym)
fallback_time = datetime.datetime(1950, 1, 1) fallback_time = datetime.datetime(1950, 1, 1, tzinfo=datetime.timezone.utc)
for g in groups: for g in groups:
g.active_drafts.sort(key=lambda d: d.get("initial_rev_time", fallback_time)) g.active_drafts.sort(key=lambda d: d.get("initial_rev_time", fallback_time))