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
|
||||
|
||||
def localtime(value, timezone=None):
|
||||
def localtime(value=None, timezone=None):
|
||||
"""
|
||||
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
|
||||
is specified.
|
||||
"""
|
||||
if value is None:
|
||||
value = now()
|
||||
if timezone is None:
|
||||
timezone = get_current_timezone()
|
||||
# If `value` is naive, astimezone() will raise a ValueError,
|
||||
|
@ -317,6 +322,19 @@ def localtime(value, timezone=None):
|
|||
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():
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
if settings.USE_TZ:
|
||||
return timezone.localtime(timezone.now()).date()
|
||||
return timezone.localdate()
|
||||
else:
|
||||
return datetime.date.today()
|
||||
|
|
|
@ -974,14 +974,32 @@ appropriate entities.
|
|||
|
||||
``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,
|
||||
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`
|
||||
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()
|
||||
|
||||
Returns a :class:`~datetime.datetime` that represents the
|
||||
|
|
|
@ -4,7 +4,7 @@ import pickle
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
from django.test import SimpleTestCase, mock, override_settings
|
||||
from django.utils import timezone
|
||||
|
||||
try:
|
||||
|
@ -27,7 +27,10 @@ class TimezoneTests(SimpleTestCase):
|
|||
def test_localtime(self):
|
||||
now = datetime.datetime.utcnow().replace(tzinfo=timezone.utc)
|
||||
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)
|
||||
|
||||
def test_localtime_naive(self):
|
||||
|
@ -54,6 +57,27 @@ class TimezoneTests(SimpleTestCase):
|
|||
with override_settings(USE_TZ=False):
|
||||
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):
|
||||
default = timezone.get_default_timezone()
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue