Skip to main content

How to Resolve Python "TypeError: 'datetime.datetime' object is not subscriptable / iterable"

When working with dates and times in Python using the datetime module, you might encounter TypeError exceptions like 'datetime.datetime' object is not subscriptable or 'datetime.datetime' object is not iterable. These errors indicate that you are trying to use operations (like indexing with [] or looping) on a datetime object that are not supported by its type.

This guide explains why these errors occur and provides clear solutions for accessing datetime attributes correctly and handling iteration issues.

Understanding datetime.datetime Objects

A datetime.datetime object represents a specific point in time, including the date (year, month, day) and time (hour, minute, second, microsecond). It's designed to hold this information and provide methods for formatting (strftime()), calculation (time differences), and accessing specific components.

Crucially, a datetime object is not like a list, tuple, dictionary, or string.

  • It doesn't have ordered elements accessible by numerical index (like a list my_list[0]).
  • It doesn't have key-value pairs accessible by key (like a dictionary my_dict['key']).
  • It doesn't represent a sequence of items that you can loop through one by one (like for char in "string":).

Error 1: TypeError: 'datetime.datetime' object is not subscriptable

This error means you tried to use square brackets [...] (the subscription operator) on a datetime object as if it were a list, dictionary, or string.

Cause: Using Square Brackets ([])

Python raises this error because datetime objects don't implement the necessary internal method (__getitem__) that allows accessing elements via [].

from datetime import datetime

now = datetime.now() # Get the current date and time

print(f"Current datetime object: {now}")
print(f"Type: {type(now)}") # Output: Type: <class 'datetime.datetime'>

try:
# ⛔️ TypeError: 'datetime.datetime' object is not subscriptable
first_element = now[0] # Trying to access like a list/tuple
except TypeError as e:
print(f"Error accessing index 0: {e}")

try:
# ⛔️ TypeError: 'datetime.datetime' object is not subscriptable
year_value = now['year'] # Trying to access like a dictionary
except TypeError as e:
print(f"Error accessing key 'year': {e}")

Solution: Use Dot Notation (.) for Attributes

To get specific components (like year, month, hour), access the attributes of the datetime object using dot notation (.).

from datetime import datetime

now = datetime.now()
dt_object = datetime(2023, 10, 27, 15, 30, 0) # Specific datetime

# ✅ Access attributes using dot notation
print(f"Year: {now.year}")
print(f"Month: {now.month}")
print(f"Day: {now.day}")
print(f"Hour: {now.hour}")
print(f"Minute: {now.minute}")
print(f"Second: {now.second}")
print(f"Microsecond: {now.microsecond}")

# ✅ Use methods using dot notation
print(f"Date only: {now.date()}") # Returns a date object
print(f"Formatted: {dt_object.strftime('%Y-%m-%d %H:%M')}") # Format the string
print(f"ISO format: {dt_object.isoformat()}")
print(f"Weekday (0=Mon): {dt_object.weekday()}")

Use dot notation for any valid attribute or method of the datetime object.

Discovering Available Attributes (dir())

If you're unsure what attributes and methods are available, use the dir() function.

from datetime import datetime

print(dir(datetime.now()))

Output will include:

['__add__', ..., 'astimezone', 'combine', 'ctime', 'date', 'day',
'dst', 'fold', 'fromisocalendar', 'fromisoformat', 'hour',
'isocalendar', 'isoformat', 'isoweekday', 'microsecond', 'minute',
'month', 'now', 'replace', 'second', 'strftime', 'time', 'timestamp',
'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname',
'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple',
'weekday', 'year']
note

Output might vary slightly between Python versions

Any name in this list can potentially be accessed using dot notation (though some are internal methods starting with __).

Error 2: TypeError: 'datetime.datetime' object is not iterable

This error means you tried to use a datetime object in a context that requires an iterable, i.e. something that can be looped over, like a list, tuple, string, or dictionary.

Cause: Attempting to Iterate (e.g., for loop, list())

Python raises this error because datetime objects don't represent a sequence of items and don't implement the necessary methods (__iter__ or __getitem__) to support iteration.

from datetime import datetime

now = datetime.now()

try:
# ⛔️ TypeError: 'datetime.datetime' object is not iterable
for component in now: # Trying to loop directly over the datetime object
print(component)
except TypeError as e:
print(f"For loop error: {e}")

try:
# ⛔️ TypeError: 'datetime.datetime' object is not iterable
# Trying to convert a datetime object into a list
components_list = list(now)
except TypeError as e:
print(f"list() constructor error: {e}")

# Similarly, dict(now), tuple(now), set(now) would also fail.

Solution: Correct Variable Assignment (Find the Real Iterable)

This error almost always indicates a logic flaw where a variable you expected to hold an iterable (like a list of dates, or a string) actually holds a single datetime object.

The solution is to find where this incorrect assignment happened and fix it.

  • Did you mean to iterate over a list containing datetime objects?
  • Did a function accidentally return a single datetime object instead of a list or other iterable?
  • Did you reassign a variable that previously held an iterable?
from datetime import datetime, timedelta

# --- Correct Scenario: Iterating over a LIST of datetimes ---
date_list = [datetime.now() - timedelta(days=x) for x in range(3)]
print(f"List of datetimes: {date_list}")
print(f"Type of date_list: {type(date_list)}") # Output: <class 'list'>

print("\nIterating correctly over the list:")
for dt_item in date_list: # ✅ Looping over the LIST
print(f" - {dt_item.strftime('%Y-%m-%d')}, Type: {type(dt_item)}")

# --- Incorrect Scenario: Variable Reassignment ---
my_iterable = ["event1", "event2"] # Starts as a list
print(f"\nInitially, my_iterable: {my_iterable}, Type: {type(my_iterable)}")

# ⚠️ Accidental reassignment
my_iterable = datetime.now()
print(f"After reassignment, my_iterable: {my_iterable}, Type: {type(my_iterable)}")

try:
# ⛔️ TypeError: 'datetime.datetime' object is not iterable
for item in my_iterable:
print(item)
except TypeError as e:
print(f"Error after reassignment: {e}")

# --- Solution for reassignment ---
# Find and fix the line 'my_iterable = datetime.now()' if you intended
# to keep iterating over the original list.
note

You can not make a single datetime object iterable. You must find the variable that should contain the list, tuple, string, etc., that you intended to iterate over.

Debugging Steps

  1. Check the Type: When you encounter either error, the first step is always to check the type of the variable causing the issue right before the error occurs:
    print(type(variable_causing_error))
    This will confirm it's <class 'datetime.datetime'>.
  2. Trace the Variable: Work backward from the error line. Where did this variable get its value? Was it returned from a function? Was it reassigned?
  3. Apply the Correct Solution:
    • If not subscriptable: Change [...] to . and use the correct attribute name (use dir() if unsure).
    • If not iterable: Find the source of the datetime object and correct the logic so the variable holds the intended iterable type instead.

Conclusion

The errors TypeError: 'datetime.datetime' object is not subscriptable and TypeError: 'datetime.datetime' object is not iterable both stem from misunderstanding the nature of datetime objects.

  • They are not subscriptable: Use dot notation (.) to access attributes like .year, .month, .hour, or call methods like .strftime(). Do not use square brackets ([]).
  • They are not iterable: You can not loop directly over a single datetime object or convert it using list(), tuple(), etc. Find where your code incorrectly assigned a datetime object to a variable that should have held a list, tuple, or other iterable, and fix that assignment logic.

By remembering these distinctions, you can effectively work with datetime objects and avoid these common TypeErrors.