Parsing date with timezone from an email?
我正在尝试从电子邮件中检索日期。一开始很容易:
1 2 3 | message = email.parser.Parser().parse(file) date = message['Date'] print date |
我收到:
1 | 'Mon, 16 Nov 2009 13:32:02 +0100' |
但我需要一个好的日期时间对象,所以我使用:
1 | datetime.strptime('Mon, 16 Nov 2009 13:32:02 +0100', '%a, %d %b %Y %H:%M:%S %Z') |
它使
用途:
1 2 3 4 5 6 7 8 9 | msg=email.message_from_file(open(file_name)) date=None date_str=msg.get('date') if date_str: date_tuple=email.utils.parsedate_tz(date_str) if date_tuple: date=datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple)) if date: ... # valid date found |
有一
1 2 3 4 5 6 7 8 9 | >>> import email.utils >>> import time >>> import datetime >>> email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0100') (2009, 11, 16, 13, 32, 2, 0, 1, -1) >>> time.mktime((2009, 11, 16, 13, 32, 2, 0, 1, -1)) 1258378322.0 >>> datetime.datetime.fromtimestamp(1258378322.0) datetime.datetime(2009, 11, 16, 13, 32, 2) |
请注意,但是,它是
1 2 3 | >>> (time.mktime(email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0900')) == ... time.mktime(email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0100')) True |
所以你还需要解析出的时区当地时间和需要考虑的差分,太。
1 2 3 4 | >>> REMOTE_TIME_ZONE_OFFSET = +9 * 60 * 60 >>> (time.mktime(email.utils.parsedate('Mon, 16 Nov 2009 13:32:02 +0900')) + ... time.timezone - REMOTE_TIME_ZONE_OFFSET) 1258410122.0 |
在Python
1 2 3 4 5 6 | import email import email.policy headers = email.message_from_file(file, policy=email.policy.default) print(headers.get('date').datetime) # -> 2009-11-16 13:32:02+01:00 |
因为Python 3.2 +,它有
1 2 3 4 5 | >>> from datetime import datetime >>> datetime.strptime("Mon, 16 Nov 2009 13:32:02 +0100", ... "%a, %d %b %Y %H:%M:%S %z") datetime.datetime(2009, 11, 16, 13, 32, 2, tzinfo=datetime.timezone(datetime.timedelta(0, 3600))) |
或使用
1 2 3 4 | >>> from email.utils import parsedate_to_datetime >>> parsedate_to_datetime("Mon, 16 Nov 2009 13:32:02 +0100") datetime.datetime(2009, 11, 16, 13, 32, 2, tzinfo=datetime.timezone(datetime.timedelta(0, 3600))) |
如果是指定的
分析RFC 5322日期时间字符串在Python的早期版本(2 +):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from calendar import timegm from datetime import datetime, timedelta, tzinfo from email.utils import parsedate_tz ZERO = timedelta(0) time_string = 'Mon, 16 Nov 2009 13:32:02 +0100' tt = parsedate_tz(time_string) #NOTE: mktime_tz is broken on Python < 2.7.4, # see https://bugs.python.org/issue21267 timestamp = timegm(tt) - tt[9] # local time - utc offset == utc time naive_utc_dt = datetime(1970, 1, 1) + timedelta(seconds=timestamp) aware_utc_dt = naive_utc_dt.replace(tzinfo=FixedOffset(ZERO, 'UTC')) aware_dt = aware_utc_dt.astimezone(FixedOffset(timedelta(seconds=tt[9]))) print(aware_utc_dt) print(aware_dt) # -> 2009-11-16 12:32:02+00:00 # -> 2009-11-16 13:32:02+01:00 |
在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class FixedOffset(tzinfo): """Fixed UTC offset: `time = utc_time + utc_offset`.""" def __init__(self, offset, name=None): self.__offset = offset if name is None: seconds = abs(offset).seconds assert abs(offset).days == 0 hours, seconds = divmod(seconds, 3600) if offset < ZERO: hours = -hours minutes, seconds = divmod(seconds, 60) assert seconds == 0 #NOTE: the last part is to remind about deprecated POSIX # GMT+h timezones that have the opposite sign in the # name; the corresponding numeric value is not used e.g., # no minutes self.__name = '<%+03d%02d>GMT%+d' % (hours, minutes, -hours) else: self.__name = name def utcoffset(self, dt=None): return self.__offset def tzname(self, dt=None): return self.__name def dst(self, dt=None): return ZERO def __repr__(self): return 'FixedOffset(%r, %r)' % (self.utcoffset(), self.tzname()) |
你可以使用Python 3个parsedate _到_ datetime函数:
1 2 3 4 | >>> from email.utils import parsedate_to_datetime >>> parsedate_to_datetime('Mon, 16 Nov 2009 13:32:02 +0100') ... datetime.datetime(2009, 11, 16, 13, 32, 2, tzinfo=datetime.timezone(datetime.timedelta(0, 3600))) |
你有没有试过
1 | rfc822.parsedate_tz(date) # ? |
更多在RFC822,http://docs.python.org /图书馆/ rfc822.html
它(现在是过时的parsedate _ TZ在
但答案是:论文帮助
如何解析一个日期字符串在Python的行动时区?
Python的时间timezones时代Part 2
1 2 3 4 5 6 7 8 9 10 11 12 | # Parses Nginx' format of"01/Jan/1999:13:59:59 +0400" # Unfortunately, strptime doesn't support %z for the UTC offset (despite what # the docs actually say), hence the need # for this function. def parseDate(dateStr): date = datetime.datetime.strptime(dateStr[:-6],"%d/%b/%Y:%H:%M:%S") offsetDir = dateStr[-5] offsetHours = int(dateStr[-4:-2]) offsetMins = int(dateStr[-2:]) if offsetDir =="-": offsetHours = -offsetHours offsetMins = -offsetMins return date + datetime.timedelta(hours=offsetHours, minutes=offsetMins) |
对于那些想获得正确的本地时间,这是我做的:
1 2 3 4 5 6 7 8 | from datetime import datetime from email.utils import parsedate_to_datetime mail_time_str = 'Mon, 16 Nov 2009 13:32:02 +0100' local_time_str = datetime.fromtimestamp(parsedate_to_datetime(mail_time_str).timestamp()).strftime('%Y-%m-%d %H:%M:%S') print(local_time_str) |
(注:我要到Python 2.7粘在我的案例)
我有类似的问题,在分析提交日期输出
因为我很有
http:/ / / / / github.com Django Django Django的BLOB /硕士/ dateparse.py/utils/
1 2 3 | >>> from django.utils.dateparse import parse_datetime >>> parse_datetime('2013-07-23T15:10:59.342107+01:00') datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100) |
"你可以用你自己的