Fixed #32366 -- Updated datetime module usage to recommended approach.
- Replaced datetime.utcnow() with datetime.now(). - Replaced datetime.utcfromtimestamp() with datetime.fromtimestamp(). - Replaced datetime.utctimetuple() with datetime.timetuple(). - Replaced calendar.timegm() and datetime.utctimetuple() with datetime.timestamp().
This commit is contained in:
parent
69ffb1acf3
commit
d06c5b3581
|
@ -59,10 +59,8 @@ class SessionStore(SessionBase):
|
||||||
Return the modification time of the file storing the session's content.
|
Return the modification time of the file storing the session's content.
|
||||||
"""
|
"""
|
||||||
modification = os.stat(self._key_to_file()).st_mtime
|
modification = os.stat(self._key_to_file()).st_mtime
|
||||||
if settings.USE_TZ:
|
tz = timezone.utc if settings.USE_TZ else None
|
||||||
modification = datetime.datetime.utcfromtimestamp(modification)
|
return datetime.datetime.fromtimestamp(modification, tz=tz)
|
||||||
return modification.replace(tzinfo=timezone.utc)
|
|
||||||
return datetime.datetime.fromtimestamp(modification)
|
|
||||||
|
|
||||||
def _expiry_date(self, session_data):
|
def _expiry_date(self, session_data):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import datetime
|
import datetime
|
||||||
from calendar import timegm
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from django.contrib.sites.shortcuts import get_current_site
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
|
@ -7,6 +6,7 @@ from django.core.paginator import EmptyPage, PageNotAnInteger
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils import timezone
|
||||||
from django.utils.http import http_date
|
from django.utils.http import http_date
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,10 +72,10 @@ def sitemap(request, sitemaps, section=None,
|
||||||
if all_sites_lastmod:
|
if all_sites_lastmod:
|
||||||
site_lastmod = getattr(site, 'latest_lastmod', None)
|
site_lastmod = getattr(site, 'latest_lastmod', None)
|
||||||
if site_lastmod is not None:
|
if site_lastmod is not None:
|
||||||
site_lastmod = (
|
if not isinstance(site_lastmod, datetime.datetime):
|
||||||
site_lastmod.utctimetuple() if isinstance(site_lastmod, datetime.datetime)
|
site_lastmod = datetime.datetime.combine(site_lastmod, datetime.time.min)
|
||||||
else site_lastmod.timetuple()
|
if timezone.is_naive(site_lastmod):
|
||||||
)
|
site_lastmod = timezone.make_aware(site_lastmod, timezone.utc)
|
||||||
lastmod = site_lastmod if lastmod is None else max(lastmod, site_lastmod)
|
lastmod = site_lastmod if lastmod is None else max(lastmod, site_lastmod)
|
||||||
else:
|
else:
|
||||||
all_sites_lastmod = False
|
all_sites_lastmod = False
|
||||||
|
@ -88,5 +88,5 @@ def sitemap(request, sitemaps, section=None,
|
||||||
if all_sites_lastmod and lastmod is not None:
|
if all_sites_lastmod and lastmod is not None:
|
||||||
# if lastmod is defined for all sites, set header so as
|
# if lastmod is defined for all sites, set header so as
|
||||||
# ConditionalGetMiddleware is able to send 304 NOT MODIFIED
|
# ConditionalGetMiddleware is able to send 304 NOT MODIFIED
|
||||||
response.headers['Last-Modified'] = http_date(timegm(lastmod))
|
response.headers['Last-Modified'] = http_date(lastmod.timestamp())
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from calendar import timegm
|
|
||||||
|
|
||||||
from django.contrib.sites.shortcuts import get_current_site
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
||||||
from django.http import Http404, HttpResponse
|
from django.http import Http404, HttpResponse
|
||||||
|
@ -42,8 +40,7 @@ class Feed:
|
||||||
if hasattr(self, 'item_pubdate') or hasattr(self, 'item_updateddate'):
|
if hasattr(self, 'item_pubdate') or hasattr(self, 'item_updateddate'):
|
||||||
# if item_pubdate or item_updateddate is defined for the feed, set
|
# if item_pubdate or item_updateddate is defined for the feed, set
|
||||||
# header so as ConditionalGetMiddleware is able to send 304 NOT MODIFIED
|
# header so as ConditionalGetMiddleware is able to send 304 NOT MODIFIED
|
||||||
response.headers['Last-Modified'] = http_date(
|
response.headers['Last-Modified'] = http_date(feedgen.latest_post_date().timestamp())
|
||||||
timegm(feedgen.latest_post_date().utctimetuple()))
|
|
||||||
feedgen.write(response, 'utf-8')
|
feedgen.write(response, 'utf-8')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
|
@ -123,10 +123,9 @@ class DatabaseCache(BaseDatabaseCache):
|
||||||
now = now.replace(microsecond=0)
|
now = now.replace(microsecond=0)
|
||||||
if timeout is None:
|
if timeout is None:
|
||||||
exp = datetime.max
|
exp = datetime.max
|
||||||
elif settings.USE_TZ:
|
|
||||||
exp = datetime.utcfromtimestamp(timeout)
|
|
||||||
else:
|
else:
|
||||||
exp = datetime.fromtimestamp(timeout)
|
tz = timezone.utc if settings.USE_TZ else None
|
||||||
|
exp = datetime.fromtimestamp(timeout, tz=tz)
|
||||||
exp = exp.replace(microsecond=0)
|
exp = exp.replace(microsecond=0)
|
||||||
if num > self._max_entries:
|
if num > self._max_entries:
|
||||||
self._cull(db, cursor, now)
|
self._cull(db, cursor, now)
|
||||||
|
@ -235,11 +234,7 @@ class DatabaseCache(BaseDatabaseCache):
|
||||||
connection = connections[db]
|
connection = connections[db]
|
||||||
quote_name = connection.ops.quote_name
|
quote_name = connection.ops.quote_name
|
||||||
|
|
||||||
if settings.USE_TZ:
|
now = timezone.now().replace(microsecond=0, tzinfo=None)
|
||||||
now = datetime.utcnow()
|
|
||||||
else:
|
|
||||||
now = datetime.now()
|
|
||||||
now = now.replace(microsecond=0)
|
|
||||||
|
|
||||||
with connection.cursor() as cursor:
|
with connection.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
|
|
|
@ -347,11 +347,8 @@ class FileSystemStorage(Storage):
|
||||||
If timezone support is enabled, make an aware datetime object in UTC;
|
If timezone support is enabled, make an aware datetime object in UTC;
|
||||||
otherwise make a naive one in the local timezone.
|
otherwise make a naive one in the local timezone.
|
||||||
"""
|
"""
|
||||||
if settings.USE_TZ:
|
tz = timezone.utc if settings.USE_TZ else None
|
||||||
# Safe to use .replace() because UTC doesn't have DST
|
return datetime.fromtimestamp(ts, tz=tz)
|
||||||
return datetime.utcfromtimestamp(ts).replace(tzinfo=timezone.utc)
|
|
||||||
else:
|
|
||||||
return datetime.fromtimestamp(ts)
|
|
||||||
|
|
||||||
def get_accessed_time(self, name):
|
def get_accessed_time(self, name):
|
||||||
return self._datetime_from_timestamp(os.path.getatime(self.path(name)))
|
return self._datetime_from_timestamp(os.path.getatime(self.path(name)))
|
||||||
|
|
|
@ -203,9 +203,9 @@ class HttpResponseBase:
|
||||||
self.cookies[key] = value
|
self.cookies[key] = value
|
||||||
if expires is not None:
|
if expires is not None:
|
||||||
if isinstance(expires, datetime.datetime):
|
if isinstance(expires, datetime.datetime):
|
||||||
if timezone.is_aware(expires):
|
if timezone.is_naive(expires):
|
||||||
expires = timezone.make_naive(expires, timezone.utc)
|
expires = timezone.make_aware(expires, timezone.utc)
|
||||||
delta = expires - expires.utcnow()
|
delta = expires - datetime.datetime.now(tz=timezone.utc)
|
||||||
# Add one second so the date matches exactly (a fraction of
|
# Add one second so the date matches exactly (a fraction of
|
||||||
# time gets lost between converting to a timedelta and
|
# time gets lost between converting to a timedelta and
|
||||||
# then the date string).
|
# then the date string).
|
||||||
|
|
|
@ -12,7 +12,6 @@ Usage:
|
||||||
"""
|
"""
|
||||||
import calendar
|
import calendar
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
|
||||||
from email.utils import format_datetime as format_datetime_rfc5322
|
from email.utils import format_datetime as format_datetime_rfc5322
|
||||||
|
|
||||||
from django.utils.dates import (
|
from django.utils.dates import (
|
||||||
|
@ -20,7 +19,7 @@ from django.utils.dates import (
|
||||||
)
|
)
|
||||||
from django.utils.regex_helper import _lazy_re_compile
|
from django.utils.regex_helper import _lazy_re_compile
|
||||||
from django.utils.timezone import (
|
from django.utils.timezone import (
|
||||||
_datetime_ambiguous_or_imaginary, get_default_timezone, is_aware, is_naive,
|
_datetime_ambiguous_or_imaginary, get_default_timezone, is_naive,
|
||||||
make_aware,
|
make_aware,
|
||||||
)
|
)
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
@ -295,10 +294,10 @@ class DateFormat(TimeFormat):
|
||||||
|
|
||||||
def U(self):
|
def U(self):
|
||||||
"Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
|
"Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
|
||||||
if isinstance(self.data, datetime.datetime) and is_aware(self.data):
|
value = self.data
|
||||||
return int(calendar.timegm(self.data.utctimetuple()))
|
if not isinstance(value, datetime.datetime):
|
||||||
else:
|
value = datetime.datetime.combine(value, datetime.time.min)
|
||||||
return int(time.mktime(self.data.timetuple()))
|
return int(value.timestamp())
|
||||||
|
|
||||||
def w(self):
|
def w(self):
|
||||||
"Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)"
|
"Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)"
|
||||||
|
|
|
@ -172,8 +172,7 @@ class SyndicationFeed:
|
||||||
if latest_date is None or item_date > latest_date:
|
if latest_date is None or item_date > latest_date:
|
||||||
latest_date = item_date
|
latest_date = item_date
|
||||||
|
|
||||||
# datetime.now(tz=utc) is slower, as documented in django.utils.timezone.now
|
return latest_date or datetime.datetime.now(tz=utc)
|
||||||
return latest_date or datetime.datetime.utcnow().replace(tzinfo=utc)
|
|
||||||
|
|
||||||
|
|
||||||
class Enclosure:
|
class Enclosure:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import base64
|
import base64
|
||||||
import calendar
|
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
@ -112,9 +111,10 @@ def parse_http_date(date):
|
||||||
else:
|
else:
|
||||||
raise ValueError("%r is not in a valid HTTP date format" % date)
|
raise ValueError("%r is not in a valid HTTP date format" % date)
|
||||||
try:
|
try:
|
||||||
|
tz = datetime.timezone.utc
|
||||||
year = int(m['year'])
|
year = int(m['year'])
|
||||||
if year < 100:
|
if year < 100:
|
||||||
current_year = datetime.datetime.utcnow().year
|
current_year = datetime.datetime.now(tz=tz).year
|
||||||
current_century = current_year - (current_year % 100)
|
current_century = current_year - (current_year % 100)
|
||||||
if year - (current_year % 100) > 50:
|
if year - (current_year % 100) > 50:
|
||||||
# year that appears to be more than 50 years in the future are
|
# year that appears to be more than 50 years in the future are
|
||||||
|
@ -127,8 +127,8 @@ def parse_http_date(date):
|
||||||
hour = int(m['hour'])
|
hour = int(m['hour'])
|
||||||
min = int(m['min'])
|
min = int(m['min'])
|
||||||
sec = int(m['sec'])
|
sec = int(m['sec'])
|
||||||
result = datetime.datetime(year, month, day, hour, min, sec)
|
result = datetime.datetime(year, month, day, hour, min, sec, tzinfo=tz)
|
||||||
return calendar.timegm(result.utctimetuple())
|
return int(result.timestamp())
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ValueError("%r is not a valid date" % date) from exc
|
raise ValueError("%r is not a valid date" % date) from exc
|
||||||
|
|
||||||
|
|
|
@ -194,11 +194,7 @@ def now():
|
||||||
"""
|
"""
|
||||||
Return an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
Return an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
||||||
"""
|
"""
|
||||||
if settings.USE_TZ:
|
return datetime.now(tz=utc if settings.USE_TZ else None)
|
||||||
# timeit shows that datetime.now(tz=utc) is 24% slower
|
|
||||||
return datetime.utcnow().replace(tzinfo=utc)
|
|
||||||
else:
|
|
||||||
return datetime.now()
|
|
||||||
|
|
||||||
|
|
||||||
# By design, these four functions don't perform any checks on their arguments.
|
# By design, these four functions don't perform any checks on their arguments.
|
||||||
|
|
|
@ -89,8 +89,9 @@ def get_git_changeset():
|
||||||
shell=True, cwd=repo_dir, universal_newlines=True,
|
shell=True, cwd=repo_dir, universal_newlines=True,
|
||||||
)
|
)
|
||||||
timestamp = git_log.stdout
|
timestamp = git_log.stdout
|
||||||
|
tz = datetime.timezone.utc
|
||||||
try:
|
try:
|
||||||
timestamp = datetime.datetime.utcfromtimestamp(int(timestamp))
|
timestamp = datetime.datetime.fromtimestamp(int(timestamp), tz=tz)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
return timestamp.strftime('%Y%m%d%H%M%S')
|
return timestamp.strftime('%Y%m%d%H%M%S')
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
Decorators for views based on HTTP headers.
|
Decorators for views based on HTTP headers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from calendar import timegm
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from django.http import HttpResponseNotAllowed
|
from django.http import HttpResponseNotAllowed
|
||||||
from django.middleware.http import ConditionalGetMiddleware
|
from django.middleware.http import ConditionalGetMiddleware
|
||||||
|
from django.utils import timezone
|
||||||
from django.utils.cache import get_conditional_response
|
from django.utils.cache import get_conditional_response
|
||||||
from django.utils.decorators import decorator_from_middleware
|
from django.utils.decorators import decorator_from_middleware
|
||||||
from django.utils.http import http_date, quote_etag
|
from django.utils.http import http_date, quote_etag
|
||||||
|
@ -82,7 +82,9 @@ def condition(etag_func=None, last_modified_func=None):
|
||||||
if last_modified_func:
|
if last_modified_func:
|
||||||
dt = last_modified_func(request, *args, **kwargs)
|
dt = last_modified_func(request, *args, **kwargs)
|
||||||
if dt:
|
if dt:
|
||||||
return timegm(dt.utctimetuple())
|
if not timezone.is_aware(dt):
|
||||||
|
dt = timezone.make_aware(dt, timezone.utc)
|
||||||
|
return int(dt.timestamp())
|
||||||
|
|
||||||
# The value from etag_func() could be quoted or unquoted.
|
# The value from etag_func() could be quoted or unquoted.
|
||||||
res_etag = etag_func(request, *args, **kwargs) if etag_func else None
|
res_etag = etag_func(request, *args, **kwargs) if etag_func else None
|
||||||
|
|
|
@ -92,7 +92,7 @@ class MultiColumnFKTests(TestCase):
|
||||||
|
|
||||||
def test_reverse_query_filters_correctly(self):
|
def test_reverse_query_filters_correctly(self):
|
||||||
|
|
||||||
timemark = datetime.datetime.utcnow()
|
timemark = datetime.datetime.now(tz=datetime.timezone.utc).replace(tzinfo=None)
|
||||||
timedelta = datetime.timedelta(days=1)
|
timedelta = datetime.timedelta(days=1)
|
||||||
|
|
||||||
# Creating a to valid memberships
|
# Creating a to valid memberships
|
||||||
|
|
|
@ -479,8 +479,8 @@ class WriterTests(SimpleTestCase):
|
||||||
self.serialize_round_trip(models.SET(42))
|
self.serialize_round_trip(models.SET(42))
|
||||||
|
|
||||||
def test_serialize_datetime(self):
|
def test_serialize_datetime(self):
|
||||||
self.assertSerializedEqual(datetime.datetime.utcnow())
|
self.assertSerializedEqual(datetime.datetime.now())
|
||||||
self.assertSerializedEqual(datetime.datetime.utcnow)
|
self.assertSerializedEqual(datetime.datetime.now)
|
||||||
self.assertSerializedEqual(datetime.datetime.today())
|
self.assertSerializedEqual(datetime.datetime.today())
|
||||||
self.assertSerializedEqual(datetime.datetime.today)
|
self.assertSerializedEqual(datetime.datetime.today)
|
||||||
self.assertSerializedEqual(datetime.date.today())
|
self.assertSerializedEqual(datetime.date.today())
|
||||||
|
@ -662,8 +662,8 @@ class WriterTests(SimpleTestCase):
|
||||||
Tests serializing a simple migration.
|
Tests serializing a simple migration.
|
||||||
"""
|
"""
|
||||||
fields = {
|
fields = {
|
||||||
'charfield': models.DateTimeField(default=datetime.datetime.utcnow),
|
'charfield': models.DateTimeField(default=datetime.datetime.now),
|
||||||
'datetimefield': models.DateTimeField(default=datetime.datetime.utcnow),
|
'datetimefield': models.DateTimeField(default=datetime.datetime.now),
|
||||||
}
|
}
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
|
@ -19,7 +19,7 @@ class SetCookieTests(SimpleTestCase):
|
||||||
# evaluated expiration time and the time evaluated in set_cookie(). If
|
# evaluated expiration time and the time evaluated in set_cookie(). If
|
||||||
# this difference doesn't exist, the cookie time will be 1 second
|
# this difference doesn't exist, the cookie time will be 1 second
|
||||||
# larger. The sleep guarantees that there will be a time difference.
|
# larger. The sleep guarantees that there will be a time difference.
|
||||||
expires = datetime.utcnow() + timedelta(seconds=10)
|
expires = datetime.now(tz=utc).replace(tzinfo=None) + timedelta(seconds=10)
|
||||||
time.sleep(0.001)
|
time.sleep(0.001)
|
||||||
response.set_cookie('datetime', expires=expires)
|
response.set_cookie('datetime', expires=expires)
|
||||||
datetime_cookie = response.cookies['datetime']
|
datetime_cookie = response.cookies['datetime']
|
||||||
|
@ -28,7 +28,7 @@ class SetCookieTests(SimpleTestCase):
|
||||||
def test_aware_expiration(self):
|
def test_aware_expiration(self):
|
||||||
"""set_cookie() accepts an aware datetime as expiration time."""
|
"""set_cookie() accepts an aware datetime as expiration time."""
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
expires = (datetime.utcnow() + timedelta(seconds=10)).replace(tzinfo=utc)
|
expires = datetime.now(tz=utc) + timedelta(seconds=10)
|
||||||
time.sleep(0.001)
|
time.sleep(0.001)
|
||||||
response.set_cookie('datetime', expires=expires)
|
response.set_cookie('datetime', expires=expires)
|
||||||
datetime_cookie = response.cookies['datetime']
|
datetime_cookie = response.cookies['datetime']
|
||||||
|
|
|
@ -54,8 +54,8 @@ class DateFormatTests(SimpleTestCase):
|
||||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt)
|
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt)
|
||||||
# astimezone() is safe here because the target timezone doesn't have DST
|
# astimezone() is safe here because the target timezone doesn't have DST
|
||||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt.astimezone(ltz).replace(tzinfo=None))
|
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt.astimezone(ltz).replace(tzinfo=None))
|
||||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz).utctimetuple(), dt.utctimetuple())
|
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz).timetuple(), dt.astimezone(tz).timetuple())
|
||||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz).utctimetuple(), dt.utctimetuple())
|
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz).timetuple(), dt.astimezone(ltz).timetuple())
|
||||||
|
|
||||||
def test_epoch(self):
|
def test_epoch(self):
|
||||||
udt = datetime(1970, 1, 1, tzinfo=utc)
|
udt = datetime(1970, 1, 1, tzinfo=utc)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import platform
|
import platform
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
|
@ -288,38 +288,52 @@ class HttpDateProcessingTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_parsing_rfc1123(self):
|
def test_parsing_rfc1123(self):
|
||||||
parsed = parse_http_date('Sun, 06 Nov 1994 08:49:37 GMT')
|
parsed = parse_http_date('Sun, 06 Nov 1994 08:49:37 GMT')
|
||||||
self.assertEqual(datetime.utcfromtimestamp(parsed), datetime(1994, 11, 6, 8, 49, 37))
|
self.assertEqual(
|
||||||
|
datetime.fromtimestamp(parsed, timezone.utc),
|
||||||
|
datetime(1994, 11, 6, 8, 49, 37, tzinfo=timezone.utc),
|
||||||
|
)
|
||||||
|
|
||||||
@unittest.skipIf(platform.architecture()[0] == '32bit', 'The Year 2038 problem.')
|
@unittest.skipIf(platform.architecture()[0] == '32bit', 'The Year 2038 problem.')
|
||||||
@mock.patch('django.utils.http.datetime.datetime')
|
@mock.patch('django.utils.http.datetime.datetime')
|
||||||
def test_parsing_rfc850(self, mocked_datetime):
|
def test_parsing_rfc850(self, mocked_datetime):
|
||||||
mocked_datetime.side_effect = datetime
|
mocked_datetime.side_effect = datetime
|
||||||
mocked_datetime.utcnow = mock.Mock()
|
mocked_datetime.now = mock.Mock()
|
||||||
utcnow_1 = datetime(2019, 11, 6, 8, 49, 37)
|
now_1 = datetime(2019, 11, 6, 8, 49, 37, tzinfo=timezone.utc)
|
||||||
utcnow_2 = datetime(2020, 11, 6, 8, 49, 37)
|
now_2 = datetime(2020, 11, 6, 8, 49, 37, tzinfo=timezone.utc)
|
||||||
utcnow_3 = datetime(2048, 11, 6, 8, 49, 37)
|
now_3 = datetime(2048, 11, 6, 8, 49, 37, tzinfo=timezone.utc)
|
||||||
tests = (
|
tests = (
|
||||||
(utcnow_1, 'Tuesday, 31-Dec-69 08:49:37 GMT', datetime(2069, 12, 31, 8, 49, 37)),
|
(now_1, 'Tuesday, 31-Dec-69 08:49:37 GMT', datetime(2069, 12, 31, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
(utcnow_1, 'Tuesday, 10-Nov-70 08:49:37 GMT', datetime(1970, 11, 10, 8, 49, 37)),
|
(now_1, 'Tuesday, 10-Nov-70 08:49:37 GMT', datetime(1970, 11, 10, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
(utcnow_1, 'Sunday, 06-Nov-94 08:49:37 GMT', datetime(1994, 11, 6, 8, 49, 37)),
|
(now_1, 'Sunday, 06-Nov-94 08:49:37 GMT', datetime(1994, 11, 6, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
(utcnow_2, 'Wednesday, 31-Dec-70 08:49:37 GMT', datetime(2070, 12, 31, 8, 49, 37)),
|
(now_2, 'Wednesday, 31-Dec-70 08:49:37 GMT', datetime(2070, 12, 31, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
(utcnow_2, 'Friday, 31-Dec-71 08:49:37 GMT', datetime(1971, 12, 31, 8, 49, 37)),
|
(now_2, 'Friday, 31-Dec-71 08:49:37 GMT', datetime(1971, 12, 31, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
(utcnow_3, 'Sunday, 31-Dec-00 08:49:37 GMT', datetime(2000, 12, 31, 8, 49, 37)),
|
(now_3, 'Sunday, 31-Dec-00 08:49:37 GMT', datetime(2000, 12, 31, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
(utcnow_3, 'Friday, 31-Dec-99 08:49:37 GMT', datetime(1999, 12, 31, 8, 49, 37)),
|
(now_3, 'Friday, 31-Dec-99 08:49:37 GMT', datetime(1999, 12, 31, 8, 49, 37, tzinfo=timezone.utc)),
|
||||||
)
|
)
|
||||||
for utcnow, rfc850str, expected_date in tests:
|
for now, rfc850str, expected_date in tests:
|
||||||
with self.subTest(rfc850str=rfc850str):
|
with self.subTest(rfc850str=rfc850str):
|
||||||
mocked_datetime.utcnow.return_value = utcnow
|
mocked_datetime.now.return_value = now
|
||||||
parsed = parse_http_date(rfc850str)
|
parsed = parse_http_date(rfc850str)
|
||||||
self.assertEqual(datetime.utcfromtimestamp(parsed), expected_date)
|
mocked_datetime.now.assert_called_once_with(tz=timezone.utc)
|
||||||
|
self.assertEqual(
|
||||||
|
datetime.fromtimestamp(parsed, timezone.utc),
|
||||||
|
expected_date,
|
||||||
|
)
|
||||||
|
mocked_datetime.reset_mock()
|
||||||
|
|
||||||
def test_parsing_asctime(self):
|
def test_parsing_asctime(self):
|
||||||
parsed = parse_http_date('Sun Nov 6 08:49:37 1994')
|
parsed = parse_http_date('Sun Nov 6 08:49:37 1994')
|
||||||
self.assertEqual(datetime.utcfromtimestamp(parsed), datetime(1994, 11, 6, 8, 49, 37))
|
self.assertEqual(
|
||||||
|
datetime.fromtimestamp(parsed, timezone.utc),
|
||||||
|
datetime(1994, 11, 6, 8, 49, 37, tzinfo=timezone.utc),
|
||||||
|
)
|
||||||
|
|
||||||
def test_parsing_year_less_than_70(self):
|
def test_parsing_year_less_than_70(self):
|
||||||
parsed = parse_http_date('Sun Nov 6 08:49:37 0037')
|
parsed = parse_http_date('Sun Nov 6 08:49:37 0037')
|
||||||
self.assertEqual(datetime.utcfromtimestamp(parsed), datetime(2037, 11, 6, 8, 49, 37))
|
self.assertEqual(
|
||||||
|
datetime.fromtimestamp(parsed, timezone.utc),
|
||||||
|
datetime(2037, 11, 6, 8, 49, 37, tzinfo=timezone.utc),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EscapeLeadingSlashesTests(unittest.TestCase):
|
class EscapeLeadingSlashesTests(unittest.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue