118

I want to get datetimes from timestamps like the following :3/1/2014 9:55 with datetime.strptime, or something equivalent.

The month, day of month, and hour is not zero padded, but there doesn't seem to be a formatting directive listed here that is able to parse this automatically.

What's the best approach to do so? Thanks!

Pythontology
  • 1,494
  • 2
  • 12
  • 15

5 Answers5

167

strptime is able to parse non-padded values. The fact that they are noted as being padded in the formatting codes table applies to strftime's output. So you can just use

datetime.strptime(datestr, "%m/%d/%Y %H:%M")
Jason S
  • 13,538
  • 2
  • 37
  • 42
10

strptime isdo not require 0-padded values. See example below

datetime.strptime("3/1/2014 9:55", "%m/%d/%Y %H:%M")
output:   datetime.datetime(2014, 3, 1, 9, 55)
gaw
  • 1,960
  • 2
  • 14
  • 18
4

The non-pattern way is use dateutil.parse module, it lets to parse the common date formats, even if you don't know what it is using currently
Ex:

>>> import dateutil.parser
>>> 
>>> utc_time     = '2014-08-13T00:00:00'
>>> verbose_time = '13-Aug-2014'
>>> some_locale  = '3/1/2014 9:55'
>>> dateutil.parser.parse(utc_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(verbose_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(some_locale)
datetime.datetime(2014, 3, 1, 9, 55)
xecgr
  • 5,095
  • 3
  • 19
  • 28
4

Just in case this answer helps someone else -- I came here thinking I had a problem with zero padding, but it was actually to do with 12:00 vs 00:00 and the %I formatter.

The %I formatter is meant to match 12-hour-clock hours, optionally zero-padded. But depending on your data source, you might get data that says that midnight or midday is actually zero, eg:

>>> datetime.strptime('2015/01/01 0:12am', "%Y/%m/%d %I:%M%p")
ValueError: time data '2015/01/01 0:12am' does not match format '%Y/%m/%d %I:%M'

What strptime actually wanted was a 12, not a zero:

>>> datetime.strptime('2015/01/01 12:12am', "%Y/%m/%d %I:%M%p")
datetime.datetime(2015, 1, 1, 0, 12)

But we don't always control our data sources! My solution for this edge case was to catch the exception, try parsing it with a %H, with a quick check that we are in the edge case we think we are in.

def get_datetime(string):
    try:
        timestamp = datetime.strptime(string, "%m/%d/%Y %I:%M%p")
    except ValueError:
        # someone used zero for midnight?
        timestamp = datetime.strptime(string, "%m/%d/%Y %H:%M%p")
        assert string.lower().endswith('am')
        assert timestamp.hour == 0
    return timestamp
hwjp
  • 15,359
  • 7
  • 71
  • 70
  • `0:12am` is invalid input. It should be `12:12am`. `11:59 pm` is followed by `12:00 am`, not `0:00am`. There could be variety of ways to supply data in a wrong time format e.g., input may use two-digit year (`%y`) instead of four-digit year (`%Y`) or day/month may be swapped (`%m/%d` vs. `%d/%m`), etc. The day/month case may be ambiguous e.g., `2015/10/12` is it "Oct 12" or "Dec 10"? btw, you should use `%Y/%m/%d` instead of `%m/%d/%Y` to match you input format. – jfs Oct 24 '15 at 12:58
  • Thanks, I do realise it's invalid input, as I say, it's coming from a data source which I don't control. – hwjp Oct 25 '15 at 08:03
2

You can see the strftime document here,but in fact they aren't all working well in all platforms,for instance,%-d,%-m don't work on win7 by python 2.7,so you can accomplish like this

>>> date_str = '{d.year}-{d.month}-{d.day}'.format(d=datetime.datetime.now())  
>>> print(date_str)
2016-5-23
黄东辉
  • 111
  • 1
  • 3
  • 2
    In native Windows, hash is substituted for dash: `%#d`, `%#m`. But both dash and hash mods are only needed in string formatting (`strftime`), not in parsing (`strptime`). – Nuno André Jul 04 '19 at 13:52