
Last updated: Apr 12, 2024
Reading time·4 min

Note: If you got the error DateParseError: day is out of range for month, click on the second subheading.
The Pandas "ValueError: NaTType does not support strftime" occurs when you
incorrectly convert a value to a datetime object, e.g. when iterating or when
iterating in a for loop or when using DataFrame.apply().
To solve the error, call the pandas.to_datetime() method with the specific
DataFrame column.
Here is an example of how the error occurs.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) for date_joined in df['date_joined']: date = pd.to_datetime(date_joined, errors='coerce').strftime('%Y-%m-%d') # ⛔️ ValueError: NaTType does not support strftime print(date)

Notice that we tried using the
pandas.to_datetime() method in a for
loop.
This is not necessary and caused the error.
pandas.to_datetime() method outside a loopTo solve the error, call the pandas.to_datetime() method directly.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) date = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d') print(date)
Running the code sample produces the following output.
0 2022-01-25 1 NaN 2 2023-01-01 Name: date_joined, dtype: object

pandas.to_datetime().errors argument to "coerce" so that invalid parsing gets
set as NaT..dt attribute before calling strftime().date = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d')
The DataFrame has an invalid date (2022-02-31), so a NaN value gets
returned.
If you meant to overwrite the specific date column, use bracket notation.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d') # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaN # 2 Carl 190.3 2023-01-01 print(df)

The code sample converts the values in the date_joined column to datetime
objects.
You will also get the error if you try to use the
DataFrame.apply()
method to call a function for each row/column or use a
list comprehension to
iterate over the values in the column and then call pandas.to_datetime().
Therefore, make sure to only call the pandas.to_datetime() method directly
with the DataFrame column that stores dates without iterating over the column.
The Pandas "DateParseError: day is out of range for month" error occurs for 2 main reasons:
DataFrame.apply() before calling pandas.to_datetime().Here is an example of how the error occurs.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) # ⛔️ pandas._libs.tslibs.parsing.DateParseError: day is out of range for month: 2022-02-31, at position 0 df['date_joined'] = df['date_joined'].apply( lambda x: pd.to_datetime(x).strftime('%Y-%m-%d'))

The error in the example occurred because we used the DataFrame.apply() method
instead of using pandas.to_datetime() directly with the date column.
Here is how we'd resolve the issue.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d') # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaN # 2 Carl 190.3 2023-01-01 print(df)

dayfirst to TrueIf your date format strings start with the day (e.g. DD-MM-YYYY), set the
dayfirst argument to True when calling pandas.to_datetime().
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['25-01-2022', '31-02-2022', '01-01-2023'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce', dayfirst=True ).dt.strftime('%Y-%m-%d') # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaN # 2 Carl 190.3 2023-01-01 print(df)

The boolean dayfirst argument defaults to False.
The argument specifies the date parsing order.
If it is set to True, the date is parsed with the day first, e.g. 20/02/2023
is parsed as 2023-02-20.
The errors argument is set to "coerce" so that values that cannot be parsed
get set as NaT.
You can view the other possible values in this section of the docs.
format argument to the pandas.to_datetime() methodNote that we can also pass a format argument to the pandas.to_datetime()
method instead of calling .dt.strftime().
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['25-01-2022', '31-02-2022', '01-01-2023'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce', format='%d-%m-%Y', dayfirst=True ) # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaT # 2 Carl 190.3 2023-01-01 print(df)

The format argument is a string that is used to specify the parsing format.
You can view the available directives in this section of the docs.
You can learn more about the related topics by checking out the following tutorials: