Fixed #25181 -- Added localdate() function to get date in a different time zone.
Thanks Konrad Świat for the original patch.
This commit is contained in:
parent
d8ef5b0e65
commit
ff1e7b4eb4
|
@ -299,13 +299,18 @@ def template_localtime(value, use_tz=None):
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
|
|
||||||
def localtime(value, timezone=None):
|
def localtime(value=None, timezone=None):
|
||||||
"""
|
"""
|
||||||
Converts an aware datetime.datetime to local time.
|
Converts an aware datetime.datetime to local time.
|
||||||
|
|
||||||
|
Only aware datetimes are allowed. When value is omitted, it defaults to
|
||||||
|
now().
|
||||||
|
|
||||||
Local time is defined by the current time zone, unless another time zone
|
Local time is defined by the current time zone, unless another time zone
|
||||||
is specified.
|
is specified.
|
||||||
"""
|
"""
|
||||||
|
if value is None:
|
||||||
|
value = now()
|
||||||
if timezone is None:
|
if timezone is None:
|
||||||
timezone = get_current_timezone()
|
timezone = get_current_timezone()
|
||||||
# If `value` is naive, astimezone() will raise a ValueError,
|
# If `value` is naive, astimezone() will raise a ValueError,
|
||||||
|
@ -317,6 +322,19 @@ def localtime(value, timezone=None):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def localdate(value=None, timezone=None):
|
||||||
|
"""
|
||||||
|
Convert an aware datetime to local time and return the value's date.
|
||||||
|
|
||||||
|
Only aware datetimes are allowed. When value is omitted, it defaults to
|
||||||
|
now().
|
||||||
|
|
||||||
|
Local time is defined by the current time zone, unless another time zone is
|
||||||
|
specified.
|
||||||
|
"""
|
||||||
|
return localtime(value, timezone).date()
|
||||||
|
|
||||||
|
|
||||||
def now():
|
def now():
|
||||||
"""
|
"""
|
||||||
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
||||||
|
|
|
@ -792,6 +792,6 @@ def timezone_today():
|
||||||
Return the current date in the current time zone.
|
Return the current date in the current time zone.
|
||||||
"""
|
"""
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
return timezone.localtime(timezone.now()).date()
|
return timezone.localdate()
|
||||||
else:
|
else:
|
||||||
return datetime.date.today()
|
return datetime.date.today()
|
||||||
|
|
|
@ -974,14 +974,32 @@ appropriate entities.
|
||||||
|
|
||||||
``override`` is also usable as a function decorator.
|
``override`` is also usable as a function decorator.
|
||||||
|
|
||||||
.. function:: localtime(value, timezone=None)
|
.. function:: localtime(value=None, timezone=None)
|
||||||
|
|
||||||
Converts an aware :class:`~datetime.datetime` to a different time zone,
|
Converts an aware :class:`~datetime.datetime` to a different time zone,
|
||||||
by default the :ref:`current time zone <default-current-time-zone>`.
|
by default the :ref:`current time zone <default-current-time-zone>`.
|
||||||
|
|
||||||
|
When ``value`` is omitted, it defaults to :func:`now`.
|
||||||
|
|
||||||
This function doesn't work on naive datetimes; use :func:`make_aware`
|
This function doesn't work on naive datetimes; use :func:`make_aware`
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.11
|
||||||
|
|
||||||
|
In older versions, ``value`` is a required argument.
|
||||||
|
|
||||||
|
.. function:: localdate(value=None, timezone=None)
|
||||||
|
|
||||||
|
.. versionadded:: 1.11
|
||||||
|
|
||||||
|
Uses :func:`localtime` to convert an aware :class:`~datetime.datetime` to a
|
||||||
|
:meth:`~datetime.datetime.date` in a different time zone, by default the
|
||||||
|
:ref:`current time zone <default-current-time-zone>`.
|
||||||
|
|
||||||
|
When ``value`` is omitted, it defaults to :func:`now`.
|
||||||
|
|
||||||
|
This function doesn't work on naive datetimes.
|
||||||
|
|
||||||
.. function:: now()
|
.. function:: now()
|
||||||
|
|
||||||
Returns a :class:`~datetime.datetime` that represents the
|
Returns a :class:`~datetime.datetime` that represents the
|
||||||
|
|
|
@ -4,7 +4,7 @@ import pickle
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, mock, override_settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -27,7 +27,10 @@ class TimezoneTests(SimpleTestCase):
|
||||||
def test_localtime(self):
|
def test_localtime(self):
|
||||||
now = datetime.datetime.utcnow().replace(tzinfo=timezone.utc)
|
now = datetime.datetime.utcnow().replace(tzinfo=timezone.utc)
|
||||||
local_tz = timezone.LocalTimezone()
|
local_tz = timezone.LocalTimezone()
|
||||||
local_now = timezone.localtime(now, local_tz)
|
with timezone.override(local_tz):
|
||||||
|
local_now = timezone.localtime(now)
|
||||||
|
self.assertEqual(local_now.tzinfo, local_tz)
|
||||||
|
local_now = timezone.localtime(now, timezone=local_tz)
|
||||||
self.assertEqual(local_now.tzinfo, local_tz)
|
self.assertEqual(local_now.tzinfo, local_tz)
|
||||||
|
|
||||||
def test_localtime_naive(self):
|
def test_localtime_naive(self):
|
||||||
|
@ -54,6 +57,27 @@ class TimezoneTests(SimpleTestCase):
|
||||||
with override_settings(USE_TZ=False):
|
with override_settings(USE_TZ=False):
|
||||||
self.assertTrue(timezone.is_naive(timezone.now()))
|
self.assertTrue(timezone.is_naive(timezone.now()))
|
||||||
|
|
||||||
|
def test_localdate(self):
|
||||||
|
naive = datetime.datetime(2015, 1, 1, 0, 0, 1)
|
||||||
|
if PY36:
|
||||||
|
self.assertEqual(timezone.localdate(naive), datetime.date(2015, 1, 1))
|
||||||
|
self.assertEqual(timezone.localdate(naive, timezone=EAT), datetime.date(2015, 1, 1))
|
||||||
|
else:
|
||||||
|
with self.assertRaisesMessage(ValueError, 'astimezone() cannot be applied to a naive datetime'):
|
||||||
|
timezone.localdate(naive)
|
||||||
|
with self.assertRaisesMessage(ValueError, 'astimezone() cannot be applied to a naive datetime'):
|
||||||
|
timezone.localdate(naive, timezone=EAT)
|
||||||
|
|
||||||
|
aware = datetime.datetime(2015, 1, 1, 0, 0, 1, tzinfo=ICT)
|
||||||
|
self.assertEqual(timezone.localdate(aware, timezone=EAT), datetime.date(2014, 12, 31))
|
||||||
|
with timezone.override(EAT):
|
||||||
|
self.assertEqual(timezone.localdate(aware), datetime.date(2014, 12, 31))
|
||||||
|
|
||||||
|
with mock.patch('django.utils.timezone.now', return_value=aware):
|
||||||
|
self.assertEqual(timezone.localdate(timezone=EAT), datetime.date(2014, 12, 31))
|
||||||
|
with timezone.override(EAT):
|
||||||
|
self.assertEqual(timezone.localdate(), datetime.date(2014, 12, 31))
|
||||||
|
|
||||||
def test_override(self):
|
def test_override(self):
|
||||||
default = timezone.get_default_timezone()
|
default = timezone.get_default_timezone()
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue