|
1 | 1 | import mimetypes |
2 | 2 | from base64 import b64encode |
3 | | -from calendar import timegm |
| 3 | +from datetime import datetime |
4 | 4 | from email.mime.base import MIMEBase |
5 | 5 | from email.utils import parseaddr, formatdate |
| 6 | +from time import mktime |
6 | 7 |
|
7 | 8 | import six |
8 | 9 | from django.conf import settings |
9 | 10 | from django.core.exceptions import ImproperlyConfigured |
10 | 11 | from django.core.mail.message import sanitize_address, DEFAULT_ATTACHMENT_MIME_TYPE |
| 12 | +from django.utils.timezone import utc |
11 | 13 |
|
12 | 14 |
|
13 | 15 | UNSET = object() # Used as non-None default value |
@@ -181,9 +183,24 @@ def get_anymail_setting(setting, default=UNSET, allow_bare=False): |
181 | 183 | return default |
182 | 184 |
|
183 | 185 |
|
| 186 | +EPOCH = datetime(1970, 1, 1, tzinfo=utc) |
| 187 | + |
| 188 | + |
| 189 | +def timestamp(dt): |
| 190 | + """Return the unix timestamp (seconds past the epoch) for datetime dt""" |
| 191 | + # This is the equivalent of Python 3.3's datetime.timestamp |
| 192 | + try: |
| 193 | + return dt.timestamp() |
| 194 | + except AttributeError: |
| 195 | + if dt.tzinfo is None: |
| 196 | + return mktime(dt.timetuple()) |
| 197 | + else: |
| 198 | + return (dt - EPOCH).total_seconds() |
| 199 | + |
| 200 | + |
184 | 201 | def rfc2822date(dt): |
185 | | - """Turn an aware datetime into a date string as specified in RFC 2822.""" |
186 | | - # This is the equivalent of Python 3.3's email.utils.format_datetime |
187 | | - assert dt.tzinfo is not None # only aware datetimes allowed |
188 | | - timeval = timegm(dt.utctimetuple()) |
| 202 | + """Turn a datetime into a date string as specified in RFC 2822.""" |
| 203 | + # This is almost the equivalent of Python 3.3's email.utils.format_datetime, |
| 204 | + # but treats naive datetimes as local rather than "UTC with no information ..." |
| 205 | + timeval = timestamp(dt) |
189 | 206 | return formatdate(timeval, usegmt=True) |
0 commit comments