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

PyArrow无法解析带时区的Timestamp?问题排查与解决

问题:带时区偏移的JSON时间戳无法转换为PyArrow的timestamp('s')类型

我有一个包含如下字段的JSON文件:

"BirthDate":"2022-09-05T08:08:46.000+00:00"

我希望基于该文件创建Parquet文件,已为PyArrow准备固定Schema,将BirthDate定义为pa.timestamp('s')。但转换时出现如下错误:

ERROR:root:Failed of conversion of JSON to timestamp[s], couldn't parse:2022-09-05T08:08:46.000+00:00

使用的PyArrow代码如下:

parquet_file = pyarrow_json.read_json(json_file, parse_options=pyarrow_json.ParseOptions(
                explicit_schema=prepared_schema,
                unexpected_field_behavior='ignore'))

另外,部分不含"+"的时间戳文件可正常转换,请问该问题的原因是什么?如何解决?


原因分析

PyArrow的pa.timestamp('s')默认是无时区的timestamp类型,而你的时间戳字符串包含+00:00时区偏移标识。PyArrow默认解析逻辑无法将带时区的字符串直接映射到无时区的timestamp类型,因此抛出解析失败错误;不含"+"的时间戳属于标准无时区ISO格式,能与Schema定义匹配,所以可正常解析。


解决方法

方案1:将Schema修改为带时区的timestamp类型

直接调整Schema,把BirthDate定义为带UTC时区的timestamp类型,让PyArrow直接解析带时区偏移的字符串:

import pyarrow as pa

prepared_schema = pa.schema([
    # 其他字段按需添加
    ('BirthDate', pa.timestamp('s', tz='UTC'))
])

# 后续读取代码不变
parquet_file = pyarrow_json.read_json(json_file, parse_options=pyarrow_json.ParseOptions(
                explicit_schema=prepared_schema,
                unexpected_field_behavior='ignore'))

方案2:指定时间字符串解析格式(保留无时区Schema)

如果必须使用无时区的timestamp('s'),可通过ParseOptions的timestamp_parsers参数指定包含时区的格式字符串:

import pyarrow as pa
import pyarrow.json as pyarrow_json

prepared_schema = pa.schema([
    ('BirthDate', pa.timestamp('s'))
])

parse_options = pyarrow_json.ParseOptions(
    explicit_schema=prepared_schema,
    unexpected_field_behavior='ignore',
    # 指定匹配带时区偏移的时间格式
    timestamp_parsers=['%Y-%m-%dT%H:%M:%S.%f%z']
)

parquet_file = pyarrow_json.read_json(json_file, parse_options=parse_options)

这种方式下,PyArrow会自动将带时区的时间转换为UTC时间后,存储为无时区的timestamp类型,保证数据准确性。

方案3:自定义时间解析函数(灵活处理特殊格式)

如果需要更灵活的处理逻辑(比如截断毫秒、适配多时区偏移),可以自定义解析函数:

import pyarrow as pa
import pyarrow.json as pyarrow_json
from datetime import datetime

def parse_tz_timestamp(s):
    # 解析带时区的时间字符串
    dt = datetime.fromisoformat(s)
    # 转换为UTC时间(可根据需求调整)
    dt_utc = dt.astimezone(datetime.timezone.utc)
    # 返回无时区datetime,匹配Schema的timestamp('s')
    return dt_utc.replace(tzinfo=None)

prepared_schema = pa.schema([
    ('BirthDate', pa.timestamp('s'))
])

parse_options = pyarrow_json.ParseOptions(
    explicit_schema=prepared_schema,
    unexpected_field_behavior='ignore',
    timestamp_parsers=[parse_tz_timestamp]
)

parquet_file = pyarrow_json.read_json(json_file, parse_options=parse_options)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:25:26