Ankur Agarwal
Ankur Agarwal

Reputation: 24768

datetime.strptime() AM PM specification

>>> datetime.strptime('2017-07-04 12:24:11', "%Y-%m-%d %I:%M:%S")
datetime.datetime(2017, 7, 4, 0, 24, 11)

Why does the above conversion get an hour of 0 ? What if I meant 12:24:11 in the afternoon in 12 hour format ?

In 12 hour format:

12:24:11 on 2017-07-04 soon after midnight will be specified as 12:24:11

and

12:24:11 on 2017-07-04 soon after noon will also be specified as 12:24:11

Why did it assume and convert it to time soon after midnight ?

I was hoping it will give a warning or an error because my time string is not specific enough.

Upvotes: 2

Views: 6641

Answers (3)

wwii
wwii

Reputation: 23753

That behaviour must have been a design decision. Here is the relevant portion of the _strptime function in \Lib\_strptime.py

    elif group_key == 'I':
        hour = int(found_dict['I'])
        ampm = found_dict.get('p', '').lower()
        # If there was no AM/PM indicator, we'll treat this like AM
        if ampm in ('', locale_time.am_pm[0]):
            # We're in AM so the hour is correct unless we're
            # looking at 12 midnight.
            # 12 midnight == 12 AM == hour 0
            if hour == 12:
                hour = 0
        elif ampm == locale_time.am_pm[1]:
            # We're in PM so we need to add 12 to the hour unless
            # we're looking at 12 noon.
            # 12 noon == 12 PM == hour 12
            if hour != 12:

You could customize it to do what you want..

class foo(datetime.datetime):
    """foo(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])

    The year, month and day arguments are required. tzinfo may be None, or an
    instance of a tzinfo subclass. The remaining arguments may be ints.
    """

    @classmethod
    def strptime(cls, datestring, fmt):
        if '%I' in fmt and not any(attr in datestring for attr
                                   in ('AM', 'am', 'PM', 'pm')):
            print('Ambiguous datestring with twelve hour format')
            #raise ValueError('Ambiguous datestring with twelve hour format')
        return super().strptime(datestring, fmt)

I imagine you could go out on a limb and reproduce the _strptime function with your modifications then assign it appropriately to produce something a little more seamless but I don't know how wise that is. Is that what ppl call monkey patching?

Upvotes: 3

Vineet Jain
Vineet Jain

Reputation: 1575

If you use %I then:

>>> datetime.strptime('2017-07-04 12:24:11', "%Y-%m-%d %I:%M:%S")
datetime.datetime(2017, 7, 4, 0, 24, 11)

while if you use %H:

>>> datetime.strptime('2017-07-04 12:24:11', "%Y-%m-%d %H:%M:%S")
datetime.datetime(2017, 7, 4, 12, 24, 11)

strftime and strptime Behavior
NOTE:- %I is for Hour (12-hour clock) as a zero-padded decimal number while %H is for Hour (24-hour clock) as a zero-padded decimal number.

Upvotes: 0

aspo
aspo

Reputation: 374

The date format is the reason you are getting the said format 0. See the the documentation for getting the right format. Use %I for 12 hour format and %H for 24 hour format -- https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

Upvotes: 1

Related Questions