Convert Datetime Strings to Python Objects with Strptime
Learn how to convert datetime strings like 'Jun 1 2005 1:33PM' to Python datetime objects using strptime, pandas.to_datetime, and dateutil.parser. Handle lists, edge cases, AM/PM, and locales efficiently.
How to convert datetime strings like “Jun 1 2005 1:33PM” to datetime objects in Python?
I have a list of datetime strings in the format “Month Day Year TimeAM/PM” such as:
[“Jun 1 2005 1:33PM”, “Aug 28 1999 12:00AM”]
What is the proper way to convert these strings into Python datetime objects?
Use Python’s datetime.strptime with the format string “%b %d %Y %I:%M%p” to convert “Jun 1 2005 1:33PM” into a python datetime object. For a list, apply a list comprehension or use pandas.to_datetime for vectorized conversion; for flexible, locale-tolerant parsing use dateutil.parser.parse as a fallback.
Contents
- Convert with datetime.strptime
- Common format string explained
- Parse a list: list comprehension and pandas
- Flexible parsing with dateutil
- Edge cases: AM/PM, locale, whitespace, timezones
- Debugging ValueError and import issues
- Sources
- Conclusion
Convert with python datetime.strptime
The most direct and strict way to convert the string “Jun 1 2005 1:33PM” to a datetime object is datetime.strptime from the standard library. Use the format that matches the input exactly:
from datetime import datetime
s = "Jun 1 2005 1:33PM"
dt = datetime.strptime(s, "%b %d %Y %I:%M%p")
print(dt) # 2005-06-01 13:33:00
Notes:
- If you wrote
import datetimeinstead offrom datetime import datetime, calldatetime.datetime.strptime(...). datetime.strptimeis strict: the format string must match the input (including AM/PM tokens and separators).- See the Python docs for the full list of strptime/strftime directives: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
Common format string for “Jun 1 2005 1:33PM”
The matching format is:
- Format:
"%b %d %Y %I:%M%p"
What each token means:
%b— abbreviated month name (e.g., “Jun”) — depends on the locale%d— day of month as a decimal (01-31). Single-digit days like “1” are accepted%Y— 4-digit year (2005)%I— hour (12-hour clock) (01-12)%M— minute (00-59)%p— locale’s AM/PM (e.g., “AM” or “PM”)
Why %I and %p? Because the input uses a 12-hour clock with an AM/PM suffix (1:33PM), so %H (24-hour) would be wrong.
Converting strings to python datetime: list, pandas, performance
For a Python list you can map or use a list comprehension:
from datetime import datetime
strings = ["Jun 1 2005 1:33PM", "Aug 28 1999 12:00AM"]
datetimes = [datetime.strptime(s, "%b %d %Y %I:%M%p") for s in strings]
If you have large arrays (Pandas Series), pandas.to_datetime is convenient and fast when you give the format:
import pandas as pd
s = pd.Series(["Jun 1 2005 1:33PM", "Aug 28 1999 12:00AM"])
dt = pd.to_datetime(s, format="%b %d %Y %I:%M%p")
- Passing
formatspeeds up parsing because pandas won’t try to infer many different patterns. Seepandas.to_datetimedocs: https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html - If some rows are malformed, use
errors="coerce"to getNaTfor bad values.
Using dateutil.parser.parse for flexible parsing
What if formats vary or you don’t want to write a format string? dateutil’s parser is forgiving:
from dateutil import parser
s = "Jun 1 2005 1:33PM"
dt = parser.parse(s)
dateutil.parser.parseauto-detects the structure (great for mixed inputs). Documentation: https://dateutil.readthedocs.io/en/stable/parser.html- Trade-off: it’s more flexible but slower than a fixed
strptimeand may be too permissive for some use cases. - A common pattern: try strict
strptime, and onValueErrorfall back todateutilfor messy inputs.
Edge cases: AM/PM, locale, whitespace, timezones
AM/PM and 12 o’clock:
12:00AM→ 00:00 (midnight)12:00PM→ 12:00 (noon)
strptimehandles these correctly when you use%I:%M%p.
Locale concerns:
%band%prely on the current locale. If your strings are English but the environment locale is different, parsing can fail.dateutilis often less sensitive to locale; otherwise set the locale explicitly or map month abbreviations yourself.
Hidden whitespace and extra spaces:
- Strings sometimes have multiple spaces (e.g.,
"Jun 1 2005 …"). Collapse whitespace first:
import re
s = re.sub(r"\s+", " ", s).strip()
dt = datetime.strptime(s, "%b %d %Y %I:%M%p")
Timezones (naive vs aware):
- The parsed objects above are naive (no timezone). To attach/convert timezones, use
zoneinfo(Python 3.9+) ordateutil.tz:
from datetime import datetime
from zoneinfo import ZoneInfo
dt = datetime.strptime("Jun 1 2005 1:33PM", "%b %d %Y %I:%M%p")
# attach timezone (assume the string is UTC)
dt_utc = dt.replace(tzinfo=ZoneInfo("UTC"))
# convert to another zone
dt_ny = dt_utc.astimezone(ZoneInfo("America/New_York"))
Docs for zoneinfo: https://docs.python.org/3/library/zoneinfo.html
Be careful: replace(tzinfo=...) just labels the time as being in that zone; if you need to convert from one zone to another, use astimezone.
Debugging ValueError and import issues
Common errors and fixes
-
ValueError: time data ‘…’ does not match format ‘…’
-
Fix: compare
repr(s)to see hidden characters, check for extra spaces, and verify your format tokens. Try collapsing whitespace or print the string characters to spot non-breaking spaces. -
AttributeError: module ‘datetime’ has no attribute ‘strptime’
-
Cause: you did
import datetimeand then calleddatetime.strptime(...). Fix either: -
from datetime import datetimeand calldatetime.strptime(...), or -
import datetimeand calldatetime.datetime.strptime(...). -
Mixed formats in a list
-
Strategy: strict pass first (fast), fallback to
dateutilfor exceptions; or usepandas.to_datetime(..., errors="coerce")then inspectNaTvalues.
Quick debugging helper:
from datetime import datetime
from dateutil import parser
import re
def parse_with_fallback(s):
s = re.sub(r"\s+", " ", s).strip()
try:
return datetime.strptime(s, "%b %d %Y %I:%M%p")
except ValueError:
return parser.parse(s) # slower, but flexible
Sources
- Python datetime strftime/strptime behavior: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
- python-dateutil parser documentation: https://dateutil.readthedocs.io/en/stable/parser.html
- pandas.to_datetime documentation: https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html
- zoneinfo (timezone support in stdlib): https://docs.python.org/3/library/zoneinfo.html
Conclusion
To convert “Jun 1 2005 1:33PM” into a python datetime, the normal approach is datetime.strptime(s, "%b %d %Y %I:%M%p"). For many strings use a list comprehension or pandas.to_datetime with the same format for speed; if inputs vary, fall back to dateutil.parser.parse. That pattern — strict + fast first, flexible fallback second — covers most real-world needs when working with python datetime conversion.