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

咨询如何转换日期以解决‘Cannot compare tz-naive and tz-aware timestamps’错误

咨询如何转换日期以解决‘Cannot compare tz-naive and tz-aware timestamps’错误

嘿,这个问题我之前也踩过坑!其实原因特别明确——你的代码里同时存在两种类型的日期对象:一种是带时区信息的(tz-aware),另一种是完全不带时区的(tz-naive),Pandas和Python都不允许直接把这两类日期放在一起比较,所以才会抛出这个错误。

咱们看看你的代码哪里出了问题:

  • 你定义的start和end是用datetime()直接创建的,没有指定时区,属于tz-naive;
  • 用pd.date_range()生成的date_range序列,自然也继承了这个属性,不带时区;
  • 但你把df['OpenDate']和df['CloseDate']都通过utc=True转成了带UTC时区的tz-aware日期。

这样循环里的row['OpenDate'] < current_date就变成了“带时区的日期”和“不带时区的日期”比大小,肯定会报错啦!

给你两种解决方案,优先推荐第一种:

方案1:让所有日期都带上UTC时区(推荐)

把初始的start和end加上UTC时区,这样后续生成的date_range也会是带时区的,就能和DataFrame里的日期正常比较了。修改后的代码如下:

from datetime import datetime, timedelta
import pytz
import pandas as pd  # 注意你原代码里漏了导入pandas,这里补上

# 给初始日期添加UTC时区信息
start = datetime(2024, 6, 1, tzinfo=pytz.UTC)
end = datetime(2024, 12, 10, tzinfo=pytz.UTC)
current_date = start
valid_dates = []

while current_date <= end:
    valid_dates.append(current_date.strftime('%Y-%m-%d'))
    current_date += timedelta(days=1)

df['OpenDate'] = pd.to_datetime(df['OpenDate'], utc=True)
df['CloseDate'] = pd.to_datetime(df['CloseDate'], errors='coerce', utc=True)

# 现在生成的date_range也是带UTC时区的tz-aware序列
date_range = pd.date_range(start=start, end=end)

results = []

for index, row in df.iterrows():
    for current_date in date_range:
        # 两边都是带时区的日期,比较不再报错
        if row['OpenDate'] < current_date and (pd.isnull(row['CloseDate']) or 
row['CloseDate'] > current_date) and row['CloseType'] in [0, 1, 3, 7, 8]:
            result_row = {
                'CurrentDate': current_date,
                'User_Id': row['User_Id'],
                'OpenDate': row['OpenDate'],
                'CloseDate': row['CloseDate'],
                'CloseType': row['CloseType']
            }
            results.append(result_row)

或者你也可以不用修改start和end,直接在生成date_range时指定utc=True,效果是一样的:

date_range = pd.date_range(start=start, end=end, utc=True)

方案2:移除DataFrame中日期的时区信息(不推荐)

如果你确定所有日期都属于同一个时区,且不需要保留时区信息,可以把DataFrame里的日期转成tz-naive:

df['OpenDate'] = pd.to_datetime(df['OpenDate'], utc=True).dt.tz_localize(None)
df['CloseDate'] = pd.to_datetime(df['CloseDate'], errors='coerce', utc=True).dt.tz_localize(None)

⚠️ 注意:这个方案可能会导致日期计算错误,尤其是涉及跨时区的数据时,尽量不要用!

备注:内容来源于stack exchange,提问作者lpca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 18:09:33