Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 57 lines
 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.