You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas解析0001-11-29 13:00:00 BC类日期报year 0超出范围如何解决

问题根因

Python 标准库 datetime 以及 pandas 默认使用的 numpy datetime64 类型均不支持公元前(BC)日期,也不存在公元0年的定义,因此解析 0001-11-29 13:00:00 BC 这类格式的日期时会触发范围错误。

解决方案

方案1:关闭自动日期解析,手动处理字符串

先读取字段为字符串格式,再自行解析BC日期,有两种实现可选:

无第三方依赖版本

自行实现解析逻辑,注意处理「无公元0年」的规则:

import pandas as pd
from datetime import datetime, timedelta

session = ah.get_boto_session()
db = get_connection() ### 自定义方法

pd.set_option('display.max_rows', None)
# 去掉parse_dates参数,先以字符串格式读取日期字段
query = "SELECT customer_date FROM customer"
df = pd.read_sql(query, db)

def custom_parse_bc(date_str):
    is_bc = date_str.endswith('BC')
    # 提取日期主体部分,移除BC标识
    date_main = date_str.removesuffix('BC').strip()
    # 先解析公元部分的日期
    dt = pd.to_datetime(date_main)
    if is_bc:
        # 公元前年份计算:例如0001 BC = 公元前1年 = 年份-1,0002 BC = 年份-2,以此类推
        dt = dt.replace(year = -(dt.year - 1))
    return dt

# 应用解析函数到日期列
df['customer_date'] = df['customer_date'].apply(custom_parse_bc)

print(df.head())
db.dispose()

第三方库版本

如果需要更完善的历史日期运算支持,可以使用专门兼容公元前日期的 pendulum 库完成解析:

  1. 安装依赖
pip install pendulum
  1. 修改代码中的解析逻辑
import pendulum

def parse_bc_date(date_str):
    # 自动识别BC/AD标识,支持直接解析目标格式的日期
    return pendulum.parse(date_str, strict=False)

df['customer_date'] = df['customer_date'].apply(parse_bc_date)

方案2:SQL端预处理日期

如果不需要在Python侧保留完整日期对象,可直接在查询时将日期转为可直接处理的格式,避免解析错误:

SELECT 
    -- 拆分返回日期各维度字段,无需Python端解析
    CASE WHEN customer_date LIKE '%BC' THEN -1 ELSE 1 END * EXTRACT(YEAR FROM customer_date) as year,
    EXTRACT(MONTH FROM customer_date) as month,
    EXTRACT(DAY FROM customer_date) as day,
    EXTRACT(HOUR FROM customer_date) as hour
FROM customer

方案3:仅需格式化展示无需日期运算

如果不需要对日期做计算,直接保留字符串格式即可,只需去掉pd.read_sql方法中的parse_dates参数即可正常运行。

内容的提问来源于stack exchange,提问作者14578446

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 00:48:04