Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing date with timezone from an email?

I am trying to retrieve date from an email. At first it's easy:

message = email.parser.Parser().parse(file) date = message['Date'] print date 

and I receive:

'Mon, 16 Nov 2009 13:32:02 +0100' 

But I need a nice datetime object, so I use:

datetime.strptime('Mon, 16 Nov 2009 13:32:02 +0100', '%a, %d %b %Y %H:%M:%S %Z') 

which raises ValueError, since %Z isn't format for +0100. But I can't find proper format for timezone in the documentation, there is only this %Z for zone. Can someone help me on that?

like image 776
gruszczy Avatar asked Nov 24 '09 15:11

gruszczy


People also ask

How do I parse a date format from a string in Python?

We can convert a string to datetime using strptime() function. This function is available in datetime and time modules to parse a string to datetime and time objects respectively.

What is date parser?

Date.parse() The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC or NaN if the string is unrecognized or, in some cases, contains illegal date values (e.g. 2015-02-31).


2 Answers

email.utils has a parsedate() function for the RFC 2822 format, which as far as I know is not deprecated.

>>> 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) 

Please note, however, that the parsedate method does not take into account the time zone and time.mktime always expects a local time tuple as mentioned here.

>>> (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 

So you'll still need to parse out the time zone and take into account the local time difference, too:

>>> 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 
like image 132
Ben James Avatar answered Sep 24 '22 04:09

Ben James


Use email.utils.parsedate_tz(date):

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 
like image 27
2 revs, 2 users 92% Avatar answered Sep 22 '22 04:09

2 revs, 2 users 92%