corresponding a :class:`~datetime.timezone` :class:`~datetime.tzinfo`.
.. versionadded:: 3.3
-
-
.. function:: mktime_tz(tuple)
Turn a 10-tuple as returned by :func:`parsedate_tz` into a UTC timestamp. It
.. versionadded:: 3.3
+.. function:: localtime(dt=None)
+
+ Return local time as an aware datetime object. If called without
+ arguments, return current time. Otherwise *dt* argument should be a
+ :class:`~datetime.datetime` instance, and it is converted to the local time
+ zone according to the system time zone database. If *dt* is naive (that
+ is, ``dt.tzinfo`` is ``None``), it is assumed to be in local time. In this
+ case, a positive or zero value for *isdst* causes ``localtime`` to presume
+ initially that summer time (for example, Daylight Saving Time) is or is not
+ (respectively) in effect for the specified time. A negative value for
+ *isdst* causes the ``localtime`` to attempt to divine whether summer time
+ is in effect for the specified time.
+
+ .. versionadded:: 3.3
+
+
.. function:: make_msgid(idstring=None, domain=None)
Returns a string suitable for an :rfc:`2822`\ -compliant
except LookupError:
# charset is not a known codec.
return unquote(text)
+
+
+#
+# datetime doesn't provide a localtime function yet, so provide one. Code
+# adapted from the patch in issue 9527. This may not be perfect, but it is
+# better than not having it.
+#
+
+def localtime(dt=None, isdst=-1):
+ """Return local time as an aware datetime object.
+
+ If called without arguments, return current time. Otherwise *dt*
+ argument should be a datetime instance, and it is converted to the
+ local time zone according to the system time zone database. If *dt* is
+ naive (that is, dt.tzinfo is None), it is assumed to be in local time.
+ In this case, a positive or zero value for *isdst* causes localtime to
+ presume initially that summer time (for example, Daylight Saving Time)
+ is or is not (respectively) in effect for the specified time. A
+ negative value for *isdst* causes the localtime() function to attempt
+ to divine whether summer time is in effect for the specified time.
+
+ """
+ if dt is None:
+ seconds = time.time()
+ else:
+ if dt.tzinfo is None:
+ # A naive datetime is given. Convert to a (localtime)
+ # timetuple and pass to system mktime together with
+ # the isdst hint. System mktime will return seconds
+ # sysce epoch.
+ tm = dt.timetuple()[:-1] + (isdst,)
+ seconds = time.mktime(tm)
+ else:
+ # An aware datetime is given. Use aware datetime
+ # arithmetics to find seconds since epoch.
+ delta = dt - datetime.datetime(1970, 1, 1,
+ tzinfo=datetime.timezone.utc)
+ seconds = delta.total_seconds()
+ tm = time.localtime(seconds)
+
+ # XXX: The following logic may not work correctly if UTC
+ # offset has changed since time provided in dt. This will be
+ # corrected in C implementation for platforms that support
+ # tm_gmtoff.
+ if time.daylight and tm.tm_isdst:
+ offset = time.altzone
+ tzname = time.tzname[1]
+ else:
+ offset = time.timezone
+ tzname = time.tzname[0]
+
+ tz = datetime.timezone(datetime.timedelta(seconds=-offset), tzname)
+ return datetime.datetime.fromtimestamp(seconds, tz)
import datetime
from email import utils
+import test.support
+import time
import unittest
class DateTimeTests(unittest.TestCase):
self.assertEqual(
utils.parsedate_to_datetime(self.datestring + ' -0000'),
self.naive_dt)
+
+
+class LocaltimeTests(unittest.TestCase):
+
+ def test_localtime_is_tz_aware_daylight_true(self):
+ test.support.patch(self, time, 'daylight', True)
+ t = utils.localtime()
+ self.assertIsNot(t.tzinfo, None)
+
+ def test_localtime_is_tz_aware_daylight_false(self):
+ test.support.patch(self, time, 'daylight', False)
+ t = utils.localtime()
+ self.assertIsNot(t.tzinfo, None)
+
+ def test_localtime_daylight_true_dst_false(self):
+ test.support.patch(self, time, 'daylight', True)
+ t0 = datetime.datetime(2012, 3, 12, 1, 1)
+ t1 = utils.localtime(t0, isdst=-1)
+ t2 = utils.localtime(t1)
+ self.assertEqual(t1, t2)
+
+ def test_localtime_daylight_false_dst_false(self):
+ test.support.patch(self, time, 'daylight', False)
+ t0 = datetime.datetime(2012, 3, 12, 1, 1)
+ t1 = utils.localtime(t0, isdst=-1)
+ t2 = utils.localtime(t1)
+ self.assertEqual(t1, t2)
+
+ def test_localtime_daylight_true_dst_true(self):
+ test.support.patch(self, time, 'daylight', True)
+ t0 = datetime.datetime(2012, 3, 12, 1, 1)
+ t1 = utils.localtime(t0, isdst=1)
+ t2 = utils.localtime(t1)
+ self.assertEqual(t1, t2)
+
+ def test_localtime_daylight_false_dst_true(self):
+ test.support.patch(self, time, 'daylight', False)
+ t0 = datetime.datetime(2012, 3, 12, 1, 1)
+ t1 = utils.localtime(t0, isdst=1)
+ t2 = utils.localtime(t1)
+ self.assertEqual(t1, t2)
+
+ def test_localtime_epoch_utc_daylight_true(self):
+ test.support.patch(self, time, 'daylight', True)
+ t0 = datetime.datetime(1970, 1, 1, tzinfo = datetime.timezone.utc)
+ t1 = utils.localtime(t0)
+ self.assertEqual(t0, t1)
+
+ def test_localtime_epoch_utc_daylight_false(self):
+ test.support.patch(self, time, 'daylight', False)
+ t0 = datetime.datetime(1970, 1, 1, tzinfo = datetime.timezone.utc)
+ t1 = utils.localtime(t0)
+ self.assertEqual(t0, t1)
+
+ def test_localtime_epoch_notz_daylight_true(self):
+ test.support.patch(self, time, 'daylight', True)
+ t0 = datetime.datetime(1970, 1, 1)
+ t1 = utils.localtime(t0)
+ t2 = utils.localtime(t0.replace(tzinfo=None))
+ self.assertEqual(t1, t2)
+
+ def test_localtime_epoch_notz_daylight_false(self):
+ test.support.patch(self, time, 'daylight', False)
+ t0 = datetime.datetime(1970, 1, 1)
+ t1 = utils.localtime(t0)
+ t2 = utils.localtime(t0.replace(tzinfo=None))
+ self.assertEqual(t1, t2)
+
+
+if __name__ == '__main__':
+ unittest.main()