Skip to content

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

Learn how to resolve the OutOfBoundsDatetime error in Pandas when converting dates outside the supported range (1677–2262) using pd.to_datetime(), with solutions like errors='coerce' or alternative parsing methods.

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:
    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

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)

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]

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)

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

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

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'>

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.

Navigation