How to Resolve Python "AttributeError: module 'datetime' has no attribute ..." (strptime, strftime, today, fromtimestamp, now)
When working with dates and times in Python, the datetime
module is indispensable. However, its structure can sometimes lead to AttributeError
exceptions, such as AttributeError: module 'datetime' has no attribute 'strptime'
, 'strftime'
, 'now'
, 'today'
, or 'fromtimestamp'
. These errors typically arise from confusion between the datetime
module itself and the datetime
class contained within it, or from attempting to call instance methods inappropriately.
This guide clarifies the structure of the datetime
module and provides clear solutions to fix these common attribute errors.
Understanding the datetime
Module vs. datetime
Class
This is the most crucial point:
datetime
(lowercase): Refers to the module you import (import datetime
). It acts as a container.datetime.datetime
(Module.Class): Refers to the primary class inside thedatetime
module. This class represents a specific point in time (date and time).datetime.date
(Module.Class): Refers to another class inside thedatetime
module, representing only a date (year, month, day).
Many useful functions for creating or manipulating date/time objects are class methods or static methods belonging to the datetime.datetime
or datetime.date
classes, not methods of the top-level datetime
module itself. Methods for formatting existing date/time objects (like strftime
) are instance methods.
Error Type 1: Calling Class/Static Methods on the Module
This covers errors like AttributeError: module 'datetime' has no attribute 'strptime'
, 'now'
, 'today'
, 'fromtimestamp'
.
Examples
import datetime # Importing the MODULE
try:
# ⛔️ AttributeError: module 'datetime' has no attribute 'strptime'
dt_obj = datetime.strptime("21/11/25 09:30", "%d/%m/%y %H:%M")
except AttributeError as e:
print(f"strptime Error: {e}")
try:
# ⛔️ AttributeError: module 'datetime' has no attribute 'now'
now_time = datetime.now()
except AttributeError as e:
print(f"now Error: {e}")
try:
# ⛔️ AttributeError: module 'datetime' has no attribute 'today'
# Note: .today() exists on BOTH datetime.date and datetime.datetime classes
today_date = datetime.today()
except AttributeError as e:
print(f"today Error: {e}")
try:
# ⛔️ AttributeError: module 'datetime' has no attribute 'fromtimestamp'
ts_obj = datetime.fromtimestamp(1678886400)
except AttributeError as e:
print(f"fromtimestamp Error: {e}")
Cause: Method Belongs to the Class, Not the Module
The methods strptime
, now
, today
, and fromtimestamp
are defined within the datetime.datetime
class (and today
is also in datetime.date
). You cannot call them directly on the datetime
module object obtained via import datetime
.
Solution 1: Use Full datetime.datetime
or datetime.date
Path
Access the methods through the class they belong to, using the full path module.class.method()
.
import datetime # Import the module
# ✅ Access via module.class
dt_obj = datetime.datetime.strptime("21/11/25 09:30", "%d/%m/%y %H:%M")
now_time = datetime.datetime.now()
today_datetime = datetime.datetime.today() # today() from datetime class
today_date = datetime.date.today() # today() from date class
ts_obj = datetime.datetime.fromtimestamp(1678886400)
print(f"strptime: {dt_obj}") # strptime: 2025-11-21 09:30:00
print(f"now: {now_time}") # now: 2025-04-17 09:36:27.839274
print(f"today (datetime): {today_datetime}") # today (datetime): 2025-04-17 09:36:27.839279
print(f"today (date): {today_date}") # today (date): 2025-04-17
print(f"fromtimestamp: {ts_obj}") # fromtimestamp: 2023-03-15 13:20:00
Solution 2: Import the Class Directly (Recommended)
This is often clearer and avoids the repetitive datetime.datetime
. Import the specific class(es) you need from the module.
# ✅ Import the specific class(es)
from datetime import datetime, date, time # Import classes needed
dt_obj = datetime.strptime("21/11/25 09:30", "%d/%m/%y %H:%M")
now_time = datetime.now()
today_datetime = datetime.today()
today_date = date.today()
ts_obj = datetime.fromtimestamp(1678886400)
print(f"strptime: {dt_obj}") # strptime: 2025-11-21 09:30:00
print(f"now: {now_time}") # now: 2025-04-17 09:37:27.994833
print(f"today (datetime): {today_datetime}") # today (datetime): 2025-04-17 09:37:27.994838
print(f"today (date): {today_date}") # today (date): 2025-04-17
print(f"fromtimestamp: {ts_obj}") # fromtimestamp: 2023-03-15 13:20:00
Now you can call the class/static methods directly on the imported class name (datetime
or date
).
Solution 3: Use Aliases (as dt
)
If you prefer shorter names, especially when importing the class directly, use an alias.
# ✅ Import the class with an alias
from datetime import datetime as dt, date
dt_obj = dt.strptime("21/11/22 09:30", "%d/%m/%y %H:%M")
now_time = dt.now()
today_dt = dt.today()
today_d = date.today()
ts_obj = dt.fromtimestamp(1678886400)
print(f"strptime: {dt_obj}") # strptime: 2022-11-21 09:30:00
print(f"now: {now_time}") # now: 2025-04-17 09:39:18.822739
print(f"today (datetime): {today_dt}") # today (datetime): 2025-04-17 09:39:18.822748
print(f"today (date): {today_d}") # today (date): 2025-04-17
print(f"fromtimestamp: {ts_obj}") # fromtimestamp: 2023-03-15 13:20:00
Error Type 2: Calling Instance Methods on the Module or Class
This covers errors like AttributeError: module 'datetime' has no attribute 'strftime'
.
Example: strftime
import datetime
# Or: from datetime import datetime
try:
# ⛔️ AttributeError: module 'datetime' has no attribute 'strftime'
# Trying to call strftime on the module
formatted = datetime.strftime("%Y-%m-%d")
except AttributeError as e:
print(f"Error calling on module: {e}")
try:
# ⛔️ TypeError: descriptor 'strftime' for 'datetime.date' objects doesn't apply to a 'datetime.datetime' object
# (or similar TypeError if called on the class directly)
# Although the error message might differ slightly, the cause is the same:
# strftime needs an INSTANCE.
formatted_class = datetime.datetime.strftime("%Y-%m-%d")
except TypeError as e:
print(f"Error calling on class: {e}")
Cause: Method Belongs to an Instance, Not the Module/Class
Methods like strftime()
are instance methods. They operate on a specific datetime
object (an instance of the datetime.datetime
class) that holds a particular date and time value. You cannot call them on the module or the class itself.
Solution: Create an Instance First, Then Call the Method
First, create a datetime
object (using datetime.datetime.now()
, datetime.datetime.today()
, datetime.datetime.strptime(...)
, datetime.datetime(...)
constructor, etc.). Then, call the instance method on that object.
from datetime import datetime # Import the class
# ✅ Create datetime instances first
now_instance = datetime.now()
specific_dt_instance = datetime(2023, 10, 27, 14, 0)
# ✅ Call strftime() on the instances
formatted_now = now_instance.strftime("%Y-%m-%d %H:%M:%S")
formatted_specific = specific_dt_instance.strftime("%A, %B %d, %Y")
print(f"Now instance: {now_instance}") # Now instance: 2025-04-17 09:40:11.431121
print(f"Formatted now: {formatted_now}") # Formatted now: 2025-04-17 09:40:11
print(f"Specific instance: {specific_dt_instance}") # Specific instance: 2023-10-27 14:00:00
print(f"Formatted specific: {formatted_specific}") # Formatted specific: Friday, October 27, 2023
Common Issue: Filename Shadowing (datetime.py
)
Cause: Local File Interferes with Standard Module
If you name your own script datetime.py
, Python's import system will likely find and import your file instead of the standard library datetime
module when you write import datetime
. Your file won't have the expected classes or methods, leading to AttributeError
.
Solution: Rename Your Local datetime.py
File
Avoid using standard library module names for your own files. Rename your datetime.py
to something else (e.g., date_utils.py
, main_app.py
).
Debugging: Identifying the Conflict (__file__
, dir()
)
- Check
__file__
:import datetime; print(datetime.__file__)
. If it points to your project directory instead of the Python library path, you have a naming conflict. - Check
dir()
:import datetime; print(dir(datetime))
. If the output lacksdatetime
,date
,time
,timedelta
, etc., you've imported your local file.
Related Error: Circular Import (partially initialized module
)
If you use import datetime
inside a file named datetime.py
, you might get an error like AttributeError: partially initialized module 'datetime' has no attribute '...' (most likely due to a circular import)
.
Solution: Rename your datetime.py
file.
Debugging with dir()
Using dir()
helps clarify what's available:
dir(datetime)
(afterimport datetime
): Shows contents of the module (includesdatetime
class,date
class,timedelta
, etc.).dir(datetime.datetime)
(afterimport datetime
) ordir(datetime)
(afterfrom datetime import datetime
): Shows contents of the class (includes class/static methods likenow
,strptime
).dir(my_dt_object)
(wheremy_dt_object = datetime.datetime.now()
): Shows contents of an instance (includes instance methods likestrftime
,weekday
, and attributes likeyear
,month
).
Conclusion
AttributeError
s related to the datetime
module usually stem from:
- Confusing the module
datetime
with the classdatetime.datetime
: Class/static methods (now
,strptime
, etc.) must be called via the class (e.g.,datetime.datetime.now()
ordt.now()
afterfrom datetime import datetime as dt
). - Calling instance methods (
strftime
) on the module or class: These methods must be called on an actualdatetime
object instance. - Filename shadowing: Naming your script
datetime.py
prevents the correct module from being imported. Rename your file.
By understanding the module's structure and using the correct import and access patterns, you can reliably use Python's date and time functionalities. Importing the specific classes (from datetime import datetime, date
) is often the clearest approach.