Skip to main content

Python Pandas: How to Fix "OutOfBoundsDatetime: Out of bounds nanosecond timestamp"

When working with date and time data in Pandas, particularly when converting strings to datetime objects using pd.to_datetime(), you might encounter an OutOfBoundsDatetime error. The full message often looks like: pandas._libs.tslibs.np_datetime.OutOfBoundsDatetime: Out of bounds nanosecond timestamp: YYYY-MM-DD HH:MM:SS, at position X. This error indicates that one or more of your date strings represent a date or time that falls outside the range representable by Pandas' default datetime64[ns] (nanosecond precision) data type.

This guide explains why this error occurs and provides common solutions, such as using errors='coerce' or alternative parsing methods.

Understanding the Error: Pandas Timestamp Limits

Pandas uses NumPy's datetime64[ns] data type by default to store timestamps. This data type uses a 64-bit integer to represent time with nanosecond precision, anchored around a specific epoch (typically the Unix epoch, 1970-01-01). Due to this fixed-size representation with high precision, there's a limit to the span of time that can be represented.

The OutOfBoundsDatetime error means that at least one date string you're trying to convert falls either before the minimum representable date or after the maximum representable date for datetime64[ns].

Common Cause: Dates Outside the Representable Range

The Problem

The most common cause is simply having date strings in your data that are too far in the past or too far in the future.

In this example, the year 2500 and 0050 are likely outside the supported range.

import pandas as pd
from datetime import datetime

data = {
'Event': ['Historical Event A', 'Current Event', 'Future Event X', 'Ancient Event'],
'DateString': ['1500-01-01', '2023-10-27', '2500-06-15', '0050-12-25'] # '2500' and '0050' are likely out of bounds
}
df = pd.DataFrame(data)
print("Original DataFrame:")
print(df)
print()

try:
# Attempting to convert 'DateString' column to datetime using pandas
# ⛔️ pandas._libs.tslibs.np_datetime.OutOfBoundsDatetime:
# Out of bounds nanosecond timestamp: 2500-06-15 00:00:00, at position 2
df['ParsedDate'] = pd.to_datetime(df['DateString'], format="%Y-%m-%d")
print("DataFrame after to_datetime (if successful):")
print(df)
except pd.errors.OutOfBoundsDatetime as e:
print(f"Caught OutOfBoundsDatetime: {e}")

Output:

Original DataFrame:
Event DateString
0 Historical Event A 1500-01-01
1 Current Event 2023-10-27
2 Future Event X 2500-06-15
3 Ancient Event 0050-12-25

Caught OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 1500-01-01, at position 0. You might want to try:
- passing `format` if your strings have a consistent format;
- passing `format='ISO8601'` if your strings are all ISO8601 but not necessarily in exactly the same format;
- passing `format='mixed'`, and the format will be inferred for each element individually. You might want to use `dayfirst` alongside this.

Identifying Pandas Timestamp Limits (pd.Timestamp.min, pd.Timestamp.max)

You can check the representable range for Pandas datetime64[ns] objects:

import pandas as pd

print(f"Pandas Timestamp Minimum: {pd.Timestamp.min}")
print(f"Pandas Timestamp Maximum: {pd.Timestamp.max}")

Output:

Pandas Timestamp Minimum: 1677-09-21 00:12:43.145224193
Pandas Timestamp Maximum: 2262-04-11 23:47:16.854775807
note

Any date string falling outside this range (approximately 1677 to 2262) will cause the OutOfBoundsDatetime error if pd.to_datetime() tries to convert it to the default datetime64[ns] type and the errors parameter is set to 'raise' (the default).

The pd.to_datetime() function has an errors parameter. Setting errors='coerce' tells Pandas to convert any date strings that cannot be parsed (including out-of-bounds dates) into NaT (Not a Time), which is Pandas' equivalent of NaN for datetime objects. This allows you to process the valid dates while marking invalid ones.

import pandas as pd

data = {
'Event': ['Historical Event A', 'Current Event', 'Future Event X', 'Ancient Event'],
'DateString': ['1700-01-01', '2023-10-27', '2500-06-15', '0050-12-25']
}
df = pd.DataFrame(data)

# ✅ Use errors='coerce'
# Out-of-bounds dates ('2500-06-15', '0050-12-25') will become NaT
df['ParsedDate_Coerced'] = pd.to_datetime(df['DateString'], errors='coerce')

print("DataFrame with out-of-bounds dates coerced to NaT:")
print(df)
print()

print("Dtypes of ParsedDate_Coerced:")
print(df['ParsedDate_Coerced'].dtype) # Will be datetime64[ns]

Output:

DataFrame with out-of-bounds dates coerced to NaT:
Event DateString ParsedDate_Coerced
0 Historical Event A 1700-01-01 1700-01-01
1 Current Event 2023-10-27 2023-10-27
2 Future Event X 2500-06-15 NaT
3 Ancient Event 0050-12-25 NaT

Dtypes of ParsedDate_Coerced:
datetime64[ns]
note

This is often the most practical solution as it preserves valid dates and clearly marks problematic ones for further investigation or filtering.

Solution 2: Ignoring Out-of-Bounds Dates (errors='ignore')

Setting errors='ignore' tells Pandas to return the original input if a date string cannot be parsed (including out-of-bounds dates). The resulting column will typically have an object dtype because it will contain a mix of datetime objects and the original unparsable strings.

import pandas as pd

data = {
'Event': ['Historical Event A', 'Current Event', 'Future Event X', 'Ancient Event'],
'DateString': ['1700-01-01', '2023-10-27', '2500-06-15', '0050-12-25']
}
df = pd.DataFrame(data)

# ✅ Use errors='ignore'
df['ParsedDate_Ignored'] = pd.to_datetime(df['DateString'], errors='ignore')

print("DataFrame with out-of-bounds dates ignored (original strings kept):")
print(df)
print()

print("Dtypes of ParsedDate_Ignored:")
print(df['ParsedDate_Ignored'].dtype) # Will likely be 'object'

Output:

DataFrame with out-of-bounds dates ignored (original strings kept):
Event DateString ParsedDate_Ignored
0 Historical Event A 1700-01-01 1700-01-01
1 Current Event 2023-10-27 2023-10-27
2 Future Event X 2500-06-15 2500-06-15
3 Ancient Event 0050-12-25 0050-12-25

Dtypes of ParsedDate_Ignored:
object
warning

errors='ignore' is deprecated and will raise in a future version.

Use to_datetime without passing errors and catch exceptions explicitly instead

note

This approach might be useful if you need to keep the original string values for out-of-bounds dates, but it makes further date-based operations on that column more complex.

Solution 3: Using Python's datetime.strptime() for Broader Range (Stores as object dtype)

Python's native datetime.datetime objects have a much wider representable date range (year 1 to 9999). You can use datetime.strptime() to parse date strings into these objects. If you store these in a Pandas Series, the Series will have an object dtype because it contains Python datetime objects, not Pandas/NumPy datetime64[ns] objects.

import pandas as pd
from datetime import datetime as dt # Alias for clarity

data = {
'Event': ['Historical Event A', 'Current Event', 'Future Event X', 'Ancient Event'],
'DateString': ['1700-01-01', '2023-10-27', '2500-06-15', '0050-12-25']
}
df = pd.DataFrame(data)

def parse_with_strptime(date_str, date_format='%Y-%m-%d'):
"""Parses a date string using strptime, returns NaT on failure."""
if not isinstance(date_str, str):
return pd.NaT # Handle non-string inputs if any

try:
return dt.strptime(date_str, date_format)
except ValueError:
return pd.NaT # Return Pandas NaT for consistency if parsing fails

# ✅ Apply strptime to convert strings to Python datetime objects
df['PythonDatetime'] = df['DateString'].apply(parse_with_strptime)

print("DataFrame with dates parsed using Python's strptime:")
print(df)
print()

print("Dtypes and types of elements in 'PythonDatetime':")
print(df['PythonDatetime'].dtype)
if not df['PythonDatetime'].empty and df['PythonDatetime'].iloc[0] is not pd.NaT:
print(type(df['PythonDatetime'].iloc[0]))

Output:

DataFrame with dates parsed using Python's strptime:
Event DateString PythonDatetime
0 Historical Event A 1700-01-01 1700-01-01 00:00:00
1 Current Event 2023-10-27 2023-10-27 00:00:00
2 Future Event X 2500-06-15 2500-06-15 00:00:00
3 Ancient Event 0050-12-25 0050-12-25 00:00:00

Dtypes and types of elements in 'PythonDatetime':
object
<class 'datetime.datetime'>
note
  • dt.strptime(date_string, format_string): Parses a string into a Python datetime object.
  • The resulting column will have dtype=object. While this allows storing out-of-bounds dates, you lose some of the vectorized performance benefits of Pandas' datetime64[ns] type for date operations. You'd need to use .dt accessor methods carefully or convert back if possible for Pandas-specific time series functions.

Considerations and Choosing a Solution

  • errors='coerce' (with pd.to_datetime()): This is usually the most practical approach. It converts valid dates to Pandas' efficient datetime64[ns] type and clearly marks unparseable or out-of-bounds dates as NaT, allowing for easy filtering or identification of problematic data.
  • errors='ignore' (with pd.to_datetime()): Use if you must preserve the original string for out-of-bounds dates, but be aware that the column will become object dtype, potentially complicating further date operations.
  • Python datetime.strptime(): Use if you absolutely need to represent dates outside Pandas' datetime64[ns] range (e.g., year 0050 or 2500) as datetime objects and are willing to accept an object dtype column with Python datetime objects. This means you might lose some Pandas-specific datetime optimizations.
  • Data Cleaning: The best long-term solution is often to identify and correct or remove truly invalid or out-of-scope dates from your source data if they are errors.

Conclusion*

The Pandas OutOfBoundsDatetime error arises when pd.to_datetime() encounters date strings outside the representable range of its default datetime64[ns] type (approx. 1677-2262).

  • The recommended solution is often to use pd.to_datetime(your_series, errors='coerce'), which converts problematic dates to NaT (Not a Time), allowing your program to continue processing valid dates.
  • Alternatively, errors='ignore' keeps the original string for unparseable dates, resulting in an object dtype column.
  • For dates truly outside the Pandas datetime64[ns] range but within Python's datetime range (year 1-9999), you can parse them using datetime.strptime() and store them as Python datetime objects in an object dtype column, though this may forgo some Pandas-specific time series optimizations.

Understanding the limitations of datetime64[ns] and using the errors parameter in pd.to_datetime() appropriately are key to handling this error effectively.