Reputation: 5575
I am reading a list of dates which has been saved to a sql file as a string filed - it has the form "[datetime.date(2003, 2, 4), datetime.date(2003, 2, 6)]"
. Is there a easy way of converting this from the string to the original format again?
[n.b. all i can think of would be to parse it by regex, but I am hoping that there would be an easier way]
Upvotes: 1
Views: 364
Reputation: 6243
Sometimes, regex really is the right tool for the job - I don't think the following code is too complex, and seems pretty explicit in its intention:
from dateutil.parser import parse
import re
s = "[datetime.date(2003, 2, 4), datetime.date(2003, 2, 6)]"
c = re.compile("datetime.date\((.*?)\)")
date_strings = c.findall(s)
print [parse(date_string).date() for date_string in date_strings]
If you don't have access to the dateutil
module, then you can also roll your own parse
function:
import datetime
import re
def parse(s):
year, month, day = s.split(', ')
year, month, day = int(year), int(month), int(day)
return datetime.date(year, month, day)
s = "[datetime.date(2003, 2, 4), datetime.date(2003, 2, 6)]"
c = re.compile("datetime.date\((.*?)\)")
date_strings = c.findall(s)
print [parse(date_string) for date_string in date_strings]
Upvotes: 1
Reputation: 298582
You could turn your code into something ast.literal_eval
can parse and then convert it back into datetime.date
objects:
import ast
import datetime
d = "[datetime.date(2003, 2, 4), datetime.date(2003, 2, 6)]"
dates = [datetime.date(*args) for args in ast.literal_eval(d.replace('datetime.date', ''))]
This avoids the potential security problems of eval
while still being reasonably simple.
Upvotes: 4
Reputation: 2697
from dateutil.parser import parse
d = "[datetime.date(2003, 2, 4), datetime.date(2003, 2, 6)]"
reverse_date = lambda x: ','.join(x.split(',')[::-1])
clean_up = lambda x: x.replace('datetime.date(','').replace(')','')
[parse(reverse_date(clean_up(x))) for x in d[1:-1].split('),')]
Output:
[datetime.datetime(2003, 4, 2, 0, 0), datetime.datetime(2003, 6, 2, 0, 0)]
Upvotes: 1
Reputation: 14259
This, but eval is dangerous, so you might want to regex it to check if it is of the format you expect.
import re
import datetime
strdates = "[datetime.date(2003, 2, 4), datetime.date(2003, 2, 6)]"
if re.search(r"\[(datetime\.date\(\d{4},\ *\d{1,2},\ *\d{1,2}\),?\ *)+]", strdates):
dates = eval(strdates)
for date in dates:
print date
So if you trust your database, you can remove the regex.
Upvotes: 0