diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py index fe34dea56e..9948edf4cf 100644 --- a/django/contrib/sessions/backends/file.py +++ b/django/contrib/sessions/backends/file.py @@ -59,10 +59,7 @@ class SessionStore(SessionBase): Return the modification time of the file storing the session's content. """ modification = os.stat(self._key_to_file()).st_mtime - if settings.USE_TZ: - modification = datetime.datetime.utcfromtimestamp(modification) - return modification.replace(tzinfo=timezone.utc) - return datetime.datetime.fromtimestamp(modification) + return datetime.datetime.fromtimestamp(modification, timezone.utc if settings.USE_TZ else None) def _expiry_date(self, session_data): """ diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 30788d6d75..1e499ebb1d 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -336,11 +336,7 @@ class FileSystemStorage(Storage): If timezone support is enabled, make an aware datetime object in UTC; otherwise make a naive one in the local timezone. """ - if settings.USE_TZ: - # Safe to use .replace() because UTC doesn't have DST - return datetime.utcfromtimestamp(ts).replace(tzinfo=timezone.utc) - else: - return datetime.fromtimestamp(ts) + return datetime.fromtimestamp(ts, timezone.utc if settings.USE_TZ else None) def get_accessed_time(self, name): return self._datetime_from_timestamp(os.path.getatime(self.path(name))) diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 9b251e54cd..66370cc1d4 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -50,7 +50,7 @@ class DatetimeSerializer(BaseSerializer): def serialize(self): if self.value.tzinfo is not None and self.value.tzinfo != utc: self.value = self.value.astimezone(utc) - value_repr = repr(self.value).replace("", "utc") + value_repr = repr(self.value).replace("datetime.timezone(datetime.timedelta(0), 'UTC')", 'utc') if isinstance(self.value, datetime_safe.datetime): value_repr = "datetime.%s" % value_repr imports = ["import datetime"] diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index e49f534a19..319a017e8c 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -173,8 +173,7 @@ class SyndicationFeed: if latest_date is None or item_date > latest_date: latest_date = item_date - # datetime.now(tz=utc) is slower, as documented in django.utils.timezone.now - return latest_date or datetime.datetime.utcnow().replace(tzinfo=utc) + return latest_date or datetime.datetime.now(utc) class Enclosure: diff --git a/django/utils/timezone.py b/django/utils/timezone.py index c1f0d70bc1..9870cd03a9 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -2,9 +2,10 @@ Timezone-related classes and functions. """ +import datetime import functools from contextlib import ContextDecorator -from datetime import datetime, timedelta, tzinfo +from datetime import timedelta, tzinfo from threading import local import pytz @@ -52,7 +53,8 @@ class FixedOffset(tzinfo): # UTC time zone as a tzinfo instance. -utc = pytz.utc +# (Use utc = datetime.timezone.utc here when PY35 isn't supported.) +utc = datetime.timezone(ZERO, 'UTC') def get_fixed_timezone(offset): @@ -172,7 +174,7 @@ def template_localtime(value, use_tz=None): This function is designed for use by the template engine. """ should_convert = ( - isinstance(value, datetime) and + isinstance(value, datetime.datetime) and (settings.USE_TZ if use_tz is None else use_tz) and not is_naive(value) and getattr(value, 'convert_to_local_time', True) @@ -219,11 +221,7 @@ def now(): """ Return an aware or naive datetime.datetime, depending on settings.USE_TZ. """ - if settings.USE_TZ: - # timeit shows that datetime.now(tz=utc) is 24% slower - return datetime.utcnow().replace(tzinfo=utc) - else: - return datetime.now() + return datetime.datetime.now(utc if settings.USE_TZ else None) # By design, these four functions don't perform any checks on their arguments.