The strptime() method of datetime accepts a format string that you have to specify in advance. What if you want to be more flexible in the kinds of date your program accepts? Here's a recipe for a function that tries many different formats until it finds one that works.
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | """
A function for flexible datetime parsing.
"""
from datetime import datetime
from itertools import permutations
def str2date(string):
"Parse a string into a datetime object."
for fmt in dateformats():
try:
return datetime.strptime(string, fmt)
except ValueError:
pass
raise ValueError("'%s' is not a recognized date/time" % string)
def dateformats():
"Yield all combinations of valid date formats."
years = ("%Y",)
months = ("%b", "%B")
days = ("%d",)
times = ("%I%p", "%I:%M%p", "%H:%M", "")
for year in years:
for month in months:
for day in days:
for args in ((day, month), (month, day)):
date = " ".join(args)
for time in times:
for combo in permutations([year, date, time]):
yield " ".join(combo).strip()
if __name__ == "__main__":
tests = """
10 May 2003 4pm
3 feb 2011 23:32
17 aug 1962
Aug 22 1943 19:22
14:55 aug 15 1976
21 march 2005 6am
2002 apr 10 5:32am
14 Octember 2023
"""
for string in tests.strip().split("\n"):
s = string.strip()
print "%-20s" % s,
try:
print str2date(s)
except ValueError:
print "invalid date/time"
|
Sometimes a full-blown parser is overkill, and BFI will get the job done just fine.