How to Resolve Python Error "TypeError: descriptor 'date' for 'datetime.datetime' objects doesn't apply to a 'int' object"
The TypeError: descriptor 'date' for 'datetime.datetime' objects doesn't apply to a 'int' object
can be a confusing error when working with Python's datetime
module. It typically arises from a misunderstanding of how the date
class relates to the datetime
class within the datetime
module, leading to an incorrect attempt to create a date
object.
This guide clarifies the structure of the datetime
module and provides the correct ways to create date
objects, resolving this specific TypeError
.
Understanding the Error: Module vs. Classes (datetime
, date
, time
)
It's crucial to distinguish between:
datetime
(lowercase): The module you import (import datetime
). It acts as a container for related classes and functions.datetime.date
(Module.Class): The class inside thedatetime
module used to represent a date (year, month, day).datetime.datetime
(Module.Class): The class inside thedatetime
module used to represent a specific point in time (date and time components).
The error message, while mentioning int
objects (because you're likely passing integer arguments like year, month, day), fundamentally arises because you're trying to use the date
component/descriptor of the datetime.datetime
class as if it were the constructor for the date
class itself.
import datetime
# Showing the types clearly:
print(f"Type of 'datetime' module: {type(datetime)}")
# Output: Type of 'datetime' module: <class 'module'>
print(f"Type of 'datetime.date' class: {type(datetime.date)}")
# Output: Type of 'datetime.date' class: <class 'type'> (Note: it's a class)
print(f"Type of 'datetime.datetime' class: {type(datetime.datetime)}")
# Output: Type of 'datetime.datetime' class: <class 'type'> (Note: it's a class)
Output:
Type of 'datetime' module: <class 'module'>
Type of 'datetime.date' class: <class 'type'>
Type of 'datetime.datetime' class: <class 'type'>
The Cause: Incorrectly Accessing date
via datetime.datetime
The TypeError
occurs when you incorrectly try to instantiate a date
object by going through the datetime.datetime
class like this: datetime.datetime.date(...)
.
import datetime
year = 2024
month = 3
day = 15
try:
# ⛔️ TypeError: descriptor 'date' for 'datetime.datetime' objects doesn't apply to a 'int' object
# This attempts to call the 'date' descriptor/attribute of the 'datetime' class,
# not the 'date' class constructor itself.
d = datetime.datetime.date(year, month, day)
print(d)
except TypeError as e:
print(e)
Python interprets datetime.datetime.date
as trying to call an attribute named date
that belongs to the datetime.datetime
class (which is normally used like my_datetime_object.date()
to get the date part from a datetime object), not as the constructor for creating a new date
object.
Solution 1: Access date
Directly from the datetime
Module
The date
class is directly available as an attribute of the top-level datetime
module. Access it as datetime.date()
.
import datetime # Import the module
year = 2025
month = 3
day = 15
# ✅ Correct: Call the 'date' class constructor via the 'datetime' module
d = datetime.date(year, month, day)
print(f"Created date object: {d}") # Output: Created date object: 2025-03-15
print(f"Type of object: {type(d)}") # Output: Type of object: <class 'datetime.date'>
Output:
Created date object: 2025-03-15
Type of object: <class 'datetime.date'>
The datetime.date()
constructor requires three integer arguments: year
, month
, and day
within valid ranges (1 <= month <= 12
, 1 <= day <= number of days in month
). Providing invalid arguments raises a ValueError
.
Solution 2: Import the date
Class Specifically (Recommended)
For better readability and less potential confusion (especially avoiding datetime.datetime
), import the date
class directly from the module.
# ✅ Import the 'date' class specifically
from datetime import date
year = 2025
month = 3
day = 15
# ✅ Correct: Call the imported 'date' class constructor directly
d = date(year, month, day)
print(f"Created date object: {d}") # Output: Created date object: 2025-03-15
print(f"Type of object: {type(d)}") # Output: Type of object: <class 'datetime.date'>
Output:
Created date object: 2025-03-15
Type of object: <class 'datetime.date'>
This approach makes it clearer that you are working with the date
class and avoids the somewhat confusing datetime.datetime
syntax.
When to Use datetime.datetime
vs. datetime.date
- Use
datetime.date()
(ordate()
after import) when you only need to represent a date (year, month, day) without any time information. - Use
datetime.datetime()
(ordatetime()
afterfrom datetime import datetime
) when you need to represent a specific point in time, including hours, minutes, seconds, etc., in addition to the date.
from datetime import date, datetime
just_a_date = date(2025, 3, 15)
date_and_time = datetime(2025, 3, 15, 10, 30, 0) # Year, Month, Day, Hour, Minute, Second
print(f"Date object: {just_a_date}") # Output: Date object: 2025-03-15
print(f"Datetime object: {date_and_time}") # Output: Datetime object: 2025-03-15 10:30:00
Output:
Date object: 2025-03-15
Datetime object: 2025-03-15 10:30:00
Debugging with type()
and dir()
If unsure about what you have imported or created:
print(type(variable))
shows the type of an object.print(dir(module))
shows attributes available directly within the module (likedate
anddatetime
).print(dir(Class))
shows attributes available on the class (like class methodsnow
,strptime
).
import datetime
from datetime import date as date_class_alias # Alias to avoid confusion below
print("--- dir(datetime module) ---")
print(dir(datetime)) # Shows 'date', 'datetime', 'time', 'timedelta' etc.
print()
print("--- dir(datetime.date class) ---")
print(dir(datetime.date)) # Shows methods like 'today', 'fromisoformat', 'weekday' etc.
print()
print("--- dir(datetime.datetime class) ---")
print(dir(datetime.datetime)) # Shows methods like 'now', 'strptime', 'date', 'time' etc.
print()
# Using the imported alias
print("--- dir(date_class_alias) ---")
print(dir(date_class_alias)) # Same as dir(datetime.date)
Output:
--- dir(datetime module) ---
['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo']
--- dir(datetime.date class) ---
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'ctime', 'day', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'min', 'month', 'replace', 'resolution', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday', 'year']
--- dir(datetime.datetime class) ---
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fold', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']
--- dir(date_class_alias) ---
['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 'ctime', 'day', 'fromisocalendar', 'fromisoformat', 'fromordinal', 'fromtimestamp', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'min', 'month', 'replace', 'resolution', 'strftime', 'timetuple', 'today', 'toordinal', 'weekday', 'year']
Pitfall: Variable Shadowing
If you use from datetime import date
, avoid naming one of your own variables date
, as this will overwrite the imported class name in that scope.
from datetime import date
my_year = 2024
# ⚠️ Problematic: Variable named 'date' shadows the imported class
date = (my_year, 3, 15) # This is now a tuple, not the date class
try:
# ⛔️ TypeError: 'tuple' object is not callable
d = date(my_year, 3, 15) # Trying to call the tuple variable
except TypeError as e:
print(e)
Solution: Use distinct variable names (e.g., current_date
, d
, date_obj
).
from datetime import date
my_year = 2025
current_date = (my_year, 3, 15) # This is now a tuple, not the date class
d = date(my_year, 3, 15) # Trying to call the tuple variable
print(d) # Output: 2025-03-15
Conclusion
The TypeError: descriptor 'date' for 'datetime.datetime' objects doesn't apply to a 'int' object
arises from incorrectly trying to create a date
object via datetime.datetime.date(...)
.
The correct ways to create a date
object are:
- Import the module and use the full path:
import datetime; my_date = datetime.date(y, m, d)
- (Recommended) Import the class directly:
from datetime import date; my_date = date(y, m, d)
Understanding the distinction between the datetime
module and the date
and datetime
classes within it is key to using the module correctly and avoiding this error.