Skip to main content

How to Format Python datetime Objects with AM/PM

This guide explains how to format datetime and time objects in Python to display time using the AM/PM (12-hour clock) format. We'll focus on using the strftime() method with the correct format codes (%I and %p) and cover various scenarios, including formatting existing datetime objects, formatting the current time, and parsing strings.

Formatting a datetime Object with AM/PM

The strftime() method (string format time) is the standard way to format datetime objects into strings. To get the AM/PM format, use the %I and %p directives:

  • %I: Hour (12-hour clock) as a zero-padded decimal number (01, 02, ..., 12).
  • %p: Locale's equivalent of either AM or PM.
from datetime import datetime

dt_string = '2024-07-21 04:50 PM' # string representing the date
dt_object = datetime.strptime(dt_string, '%Y-%m-%d %I:%M %p') # Parse into object
print(dt_object)
# Output: 2024-07-21 16:50:00 (Notice, this use 24h format)

# Format with AM/PM:
formatted_time = dt_object.strftime('%Y-%m-%d %I:%M %p')
print(formatted_time) # Output: 2024-07-21 04:50 PM

# Including seconds
dt_string_seconds = '2024-07-21 04:50:34 PM'
dt_object_seconds = datetime.strptime(dt_string_seconds, '%Y-%m-%d %I:%M:%S %p')
print(dt_object_seconds.strftime('%Y-%m-%d %I:%M:%S %p'))
# Output: 2024-07-21 04:50:34 PM
  • The %p directive automatically handles the AM/PM based on the hour.

Formatting the Current Time with AM/PM

To get and format the current time with AM/PM:

from datetime import datetime

# Without seconds:
print(datetime.now().strftime('%I:%M %p')) # Output: (e.g.,) 02:35 PM

# With seconds:
print(datetime.now().strftime('%I:%M:%S %p')) # Output: (e.g.,) 02:35:22 PM
  • The %H directive would format hours as a 24-hour clock number.

Parsing a Time String with AM/PM

To convert a string containing AM/PM into a datetime object, use strptime() (string parse time) with the same %I and %p directives:

from datetime import datetime

time_string = '11:50:23 PM'
dt_object = datetime.strptime(time_string, '%I:%M:%S %p')
print(dt_object) # Output: 1900-01-01 23:50:23
print(dt_object.strftime('%I:%M:%S %p')) # Output: 11:50:23 PM

time_string = '11:50:23 PM'
dt_object = datetime.strptime(time_string, '%H:%M:%S %p') # Using %H to parse
print(dt_object.strftime('%H:%M:%S %p')) # Output: 11:50:23 AM # Using %H during format.
  • When parsing using only time information, the strptime will generate a datetime object by using the time values and replacing date components with default ones (in this case 1900-01-01).

Handling Potential ValueError with Input Strings

When parsing date/time strings from user input or external sources, it's crucial to handle potential ValueError exceptions if the input doesn't match the expected format:

from datetime import datetime

dt_string = '2025-07-01 04:50 p.m.' # Incorrect format

try:
dt_string = dt_string.replace('p.m.', 'PM').replace('a.m.', 'AM') # Replace the p.m. with PM
dt_object = datetime.strptime(dt_string, '%Y-%m-%d %H:%M %p')
print(dt_object)
print(dt_object.strftime('%Y-%m-%d %H:%M %p'))

except ValueError as e:
print(f"Invalid date/time format: {e}")

# Output:
# 2025-07-01 04:50:00
# 2025-07-01 04:50 AM
  • The .replace('p.m.', 'PM').replace('a.m.', 'AM') calls make sure that the string follows the correct format.
  • The try...except ValueError block catches the error, providing a user-friendly message instead of crashing.