How to Resolve Python "TypeError: 'datetime.datetime' object is not subscriptable / iterable"
Fix Python errors when trying to use square brackets or loops on datetime objects by learning correct attribute access with dot notation and debugging iterable assignment issues.
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 datetimenow = datetime.now() # Get the current date and timeprint(f"Current datetime object: {now}")print(f"Type: {type(now)}") # Output: Type: <class 'datetime.datetime'>try: first_element = now[0] # Trying to access like a list/tupleexcept TypeError as e: print(f"Error accessing index 0: {e}")try: year_value = now['year'] # Trying to access like a dictionaryexcept 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 datetimenow = datetime.now()dt_object = datetime(2023, 10, 27, 15, 30, 0) # Specific datetimeprint(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}")print(f"Date only: {now.date()}") # Returns a date objectprint(f"Formatted: {dt_object.strftime('%Y-%m-%d %H:%M')}") # Format the stringprint(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 datetimeprint(dir(datetime.now()))
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 datetimenow = datetime.now()try: 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: components_list = list(now)except TypeError as e: print(f"list() constructor error: {e}")
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, timedeltadate_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)}")my_iterable = ["event1", "event2"] # Starts as a listprint(f"\nInitially, my_iterable: {my_iterable}, Type: {type(my_iterable)}")my_iterable = datetime.now()print(f"After reassignment, my_iterable: {my_iterable}, Type: {type(my_iterable)}")try: for item in my_iterable: print(item)except TypeError as e: print(f"Error after reassignment: {e}")
Debugging Steps
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'>.
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?
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.