datetime
Python
programming
time-formatting
strftime

How can I account for period AM/PM using strftime?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To show AM or PM in Python time formatting, use %p together with the 12-hour clock token %I. The mistake people usually make is pairing %p with the 24-hour token %H, which produces odd output such as 15:45 PM. Once you separate 12-hour and 24-hour formatting clearly, the behavior is predictable.

Use %I and %p Together

The normal 12-hour format is %I:%M %p.

python
1from datetime import datetime
2
3dt = datetime(2024, 1, 1, 15, 45)
4print(dt.strftime("%I:%M %p"))

That prints 03:45 PM. The pieces mean:

  • '%I for the hour on a 12-hour clock'
  • '%M for minutes'
  • '%p for the locale-specific period marker'

If you want seconds too, extend the same pattern:

python
print(dt.strftime("%I:%M:%S %p"))

Do Not Mix %H with %p

A common mistake is writing this:

python
1from datetime import datetime
2
3dt = datetime(2024, 1, 1, 15, 45)
4print(dt.strftime("%H:%M %p"))

%H is the 24-hour clock token, so the output can look like 15:45 PM. That is syntactically allowed, but it is not the display format most people want.

The rule is simple:

  • use %H for 24-hour time with no AM or PM
  • use %I with %p for 12-hour time
python
print(dt.strftime("%H:%M"))
print(dt.strftime("%I:%M %p"))

Midnight and Noon Are the Important Edge Cases

People often hesitate around midnight and noon because 12-hour clocks represent them differently from 24-hour clocks.

python
1from datetime import datetime
2
3midnight = datetime(2024, 1, 1, 0, 0)
4noon = datetime(2024, 1, 1, 12, 0)
5
6print(midnight.strftime("%I:%M %p"))
7print(noon.strftime("%I:%M %p"))

The results are:

  • midnight becomes 12:00 AM
  • noon becomes 12:00 PM

That is correct for 12-hour display, even though the underlying hour values are 0 and 12 in the datetime object.

Parsing AM and PM Uses strptime

Formatting is only one side of the problem. If you also need to read an input string such as 03:45 PM, use strptime with the same 12-hour pattern.

python
1from datetime import datetime
2
3text = "03:45 PM"
4dt = datetime.strptime(text, "%I:%M %p")
5print(dt.hour)

The parsed hour becomes 15. Matching the format string for both directions keeps the code easier to reason about.

A useful rule is this: if you format with %I:%M %p, parse with %I:%M %p. If you later change the display format, update both sides together.

%p Depends on Locale

%p is locale-sensitive. In many English-language environments it produces AM and PM, but other locales may use different text. That is helpful for localized output, but it also means you should not assume the exact string is always English.

If you specifically want lowercase am and pm, format first and then transform the result.

python
1from datetime import datetime
2
3dt = datetime(2024, 1, 1, 15, 45)
4print(dt.strftime("%I:%M %p").lower())

That keeps the clock logic in strftime and the stylistic choice as a separate presentation step.

Common Pitfalls

  • Using %H with %p and producing a confusing 24-hour-plus-period format.
  • Forgetting that %I is the 12-hour token and %H is the 24-hour token.
  • Misreading midnight and noon when checking formatted output.
  • Parsing an AM or PM time string with %H instead of %I.
  • Assuming %p will always render as literal English AM and PM in every locale.

Summary

  • Use %I with %p to format 12-hour times that include AM or PM.
  • Use %H only for 24-hour formatting.
  • Midnight formats as 12:00 AM, and noon formats as 12:00 PM.
  • Use the same %I and %p pattern with strptime when parsing input.
  • Remember that %p is locale-aware and may vary by environment.

Course illustration
Course illustration

All Rights Reserved.