comamitc
comamitc

Reputation: 841

A better way to parse time strings

I have been wondering if there is a more concise and faster way to parse a timestamp that could be of 3 formats coming from several locations / log files. The below code is what I have currently, but its a very ugly working version and terribly slow. Is there a more pythonic and faster way to accomplish this?

FORMATS = ["%Y-%m-%d %H:%M:%S"      ,
           "%Y%m%d_%H.%M.%S"        ,
           "%a %b %d %H:%M:%S %Y"]


def _hacktime(self, t):
    # CAUTION: 
    # The nastiest time hack of all TIME
    #
    try:
        t = time.mktime(time.strptime(t, self.FORMATS[0]))
    except:
        try:
            t = time.mktime(time.strptime(t, self.FORMATS[1]))
        except:
            try:
                t = time.mktime(time.strptime(' '.join([t, 
                                                time.strftime('%Y')]),
                                                self.FORMATS[2]))
            except Exception as e:
                print('could not convert time %s: %s' % (t, e))
                t = time.time()   
    return [t, time.ctime(t)]

Upvotes: 3

Views: 196

Answers (3)

S.Lott
S.Lott

Reputation: 391932

Use a loop

the_time= None
for f in FORMATS:
    try:
        the_time = time.mktime(time.strptime(t, f))
        return the_time # or break 
    except ValueError: 
        continue
if the_time is None:
    raise ValueError( "{0!r} is not a valid time".format(t) )

Upvotes: 5

Alexander
Alexander

Reputation: 10396

You could check the "-", ":" and " " count for the string before trying to convert them with strptime. Instead of trying and catching exceptions while indenting more for each attempt, use a loop and break out of the loop (or just return) once a conversion works.

Upvotes: 0

Useless
Useless

Reputation: 67752

Well you could make a regex to match both of the first two, pulling out the component fields.

I guess that reduces it to two branches, because if the match fails, it must be the third pattern.

If it does match, you might as well populate the struct_time directly since you have all the matched fields.

Upvotes: 1

Related Questions