summaryrefslogtreecommitdiffstats
path: root/Lib/email/utils.py
diff options
context:
space:
mode:
authorR David Murray <rdmurray@bitdance.com>2012-05-26 03:22:59 (GMT)
committerR David Murray <rdmurray@bitdance.com>2012-05-26 03:22:59 (GMT)
commitd2d521eafdea651de075f987ca80bece033b9b40 (patch)
treeffec4997db7f5c20cb879d5eac0877154e6e34ad /Lib/email/utils.py
parentdcaf2ece6cbd432f8ad71ca2bebc4f79e3b97fbc (diff)
downloadcpython-d2d521eafdea651de075f987ca80bece033b9b40.zip
cpython-d2d521eafdea651de075f987ca80bece033b9b40.tar.gz
cpython-d2d521eafdea651de075f987ca80bece033b9b40.tar.bz2
#665194: Add a localtime function to email.utils.
Without this function people would be tempted to use the other date functions in email.utils to compute an aware localtime, and those functions are not as good for that purpose as this code. The code is Alexander Belopolsy's from his proposed patch for issue 9527, with a fix (and additional tests) by Brian K. Jones.
Diffstat (limited to 'Lib/email/utils.py')
-rw-r--r--Lib/email/utils.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/Lib/email/utils.py b/Lib/email/utils.py
index b7e1bb9..39f7903 100644
--- a/Lib/email/utils.py
+++ b/Lib/email/utils.py
@@ -363,3 +363,56 @@ def collapse_rfc2231_value(value, errors='replace',
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)