14

I have a text file with a lot of datetime strings in isoformat. The strings are similar to this:

'2009-02-10 16:06:52.598800'

These strings were generated using str(datetime_object). The problem is that, for some reason, str(datetime_object) generates a different format when the datetime object has microseconds set to zero and some strings look like this:

'2009-02-10 16:06:52'

How can I parse these strings and convert them into a datetime object?

It's very important to get all the data in the object, including microseconds.

NOTE: I have to use Python 2.5, the format directive %f for microseconds doesn't exist in 2.5.

smci
  • 32,567
  • 20
  • 113
  • 146
Manuel Ceron
  • 8,268
  • 8
  • 31
  • 38

4 Answers4

21

Alternatively:

from datetime import datetime

def str2datetime(s):
    parts = s.split('.')
    dt = datetime.strptime(parts[0], "%Y-%m-%d %H:%M:%S")
    return dt.replace(microsecond=int(parts[1]))

Using strptime itself to parse the date/time string (so no need to think up corner cases for a regex).

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • Thanks for this answer! I'd suggest to change the last line to: return dt.replace(microsecond=int(1000 * float( '0.' + parts[1]))) this handles all cases correctly, like e.g. '2017-03-16 21:20:57.31' which should give 310us rather than 31us. – denizb Mar 17 '17 at 14:54
11

Use the dateutil module. It supports a much wider range of date and time formats than the built in Python ones.

You'll need to easy_install dateutil for the following code to work:

from dateutil.parser import parser

p = parser()
datetime_with_microseconds = p.parse('2009-02-10 16:06:52.598800')
print datetime_with_microseconds.microsecond

results in:

598799
Soviut
  • 88,194
  • 49
  • 192
  • 260
5

Someone has already filed a bug with this issue: Issue 1982. Since you need this to work with python 2.5 you must parse the value manualy and then manipulate the datetime object.

RSabet
  • 6,130
  • 3
  • 27
  • 26
2

It might not be the best solution, but you can use a regular expression:

m = re.match(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(?:\.(\d{6}))?', datestr)
dt = datetime.datetime(*[int(x) for x in m.groups() if x])
David Z
  • 128,184
  • 27
  • 255
  • 279