The function below takes a datestring in the form d-mmm-yyyy and converts it to ISO date format (yyyy-mm-dd). Delimiters may be hyphen, space or /
, and Dutch or English month abbreviations may be used.
Now, I know there is dateutil
, but it returns unknown string format
if you try to parse something with a non-English month in it. I haven't digested all its documentation, but I think dateutil
is mainly intended for date calculation. I'm not doing that, I'm just cleaning up user input.
So I wrote my own.
import re
.
.
def ISOdate(date):
'''
converts the following date string format to ISO (yyyy-mm-dd):
28-okt-1924 (dutch month abbreviations)
28 oct 1924 (english..)
9/nov/2012 (single digit)
'''
shortmonths = [
'jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
'jul', 'aug', 'sep', 'okt', 'nov', 'dec',
'jan', 'feb', 'mar', 'apr', 'may', 'jun',
'jul', 'aug', 'sep', 'oct', 'nov', 'dec'
]
# Month abbrevs are only different march, may and october.
pat = r'(\d{1,2})\s?[-\/]?\s?(\w{3})\s?[-\/]?\s?(\d{4})'
q = re.match(pat, date)
if q:
year = q.group(3)
day = int(q.group(1))
month = shortmonths.index(q.group(2).lower()) % 12 + 1
return u'{}-{:02d}-{:02d}'.format(year, month, day)
else:
# just return input, date fields may be empty
return date
The regex match parses date month and year may not be pretty, but it works and it's easy to expand for other patterns. Likewise for the month number lookup with index
, which is more concise than a chain of if, elif
to match month strings to numbers.
Instead of the code between if q:
and else:
, I also had this, which uses datetime:
year = int(q.group(3))
day = int(q.group(1))
month = shortmonths.index(q.group(2).lower()) % 12 + 1
d = datetime.datetime(year, month, day)
return u'{:%YY-%m-%d}'.format(d)
This works too, but I think the first version is more to-the-point.
I'm always striving for optimal Pythonicness, but I'm by no means a seasoned coder.
Please comment.