Polars Python:CSV时间戳指定JST时区并转CET遇异常求助
解决Polars中JST时间戳转CET时区的问题
问题背景
CSV中时间戳格式为2022-01-03 17:59:16.254,明确属于JST(日本标准时间)。用现有代码解析后指定JST时区,结果时间数值莫名变化,转换CET时区也完全失效,输出示例:
WithTZ |WithCastTZ |timestamp 2022-01-04 02:59:16.213 JST|2022-01-04 02:59:16.213 CET|2022-01-03T17:59:16.213000000
问题原因
str.strptime解析出的是无时区的datetime(naive datetime),直接调用dt.with_time_zone("Asia/Tokyo")时,Polars会默认把这个naive datetime当作UTC时间,再转换为JST时区(UTC+9)。所以原本的UTC 17:59加上9小时,就变成了JST次日02:59,这就是时间数值变化的原因;后续转换CET时,错误的时间基础自然导致结果无效。
解决方法
核心是给原始时间戳正确标记JST时区,而非把它当作UTC转换。有两种可靠实现方式:
方式1:解析后附加时区信息
用dt.replace_time_zone直接给naive datetime加上JST时区标记,不修改时间数值:
new = pl.scan_csv('test.csv').with_columns( # 先解析为无时区datetime,再附加JST时区 pl.col("timestamp").str.strptime(pl.Datetime, "%Y-%m-%d %H:%M:%S.%f", strict=True) .dt.replace_time_zone("Asia/Tokyo") ).select( pl.col("timestamp").cast(pl.Date).alias("Date"), pl.col("timestamp").alias("WithTZ"), # 此时已是正确的JST时间 pl.col("timestamp").dt.cast_time_zone("Europe/Berlin").alias("WithCastTZ"), # 转换为CET pl.all() ) new.fetch(10).write_csv("testOut.csv")
方式2:解析时直接指定时区(Polars 0.18+支持)
在str.strptime中通过time_zone参数直接指定解析后的时区,一步到位:
new = pl.scan_csv('test.csv').with_columns( pl.col("timestamp").str.strptime( pl.Datetime, "%Y-%m-%d %H:%M:%S.%f", strict=True, time_zone="Asia/Tokyo" # 解析时直接绑定JST时区 ) ).select( pl.col("timestamp").cast(pl.Date).alias("Date"), pl.col("timestamp").alias("WithTZ"), pl.col("timestamp").dt.cast_time_zone("Europe/Berlin").alias("WithCastTZ"), pl.all() ) new.fetch(10).write_csv("testOut.csv")
预期正确输出
修改后会得到符合预期的结果:
WithTZ |WithCastTZ |timestamp 2022-01-03 17:59:16.213 JST|2022-01-03 09:59:16.213 CET|2022-01-03T17:59:16.213000000+09:00
(JST比CET快8小时,17:59 JST减去8小时即为09:59 CET)
内容的提问来源于stack exchange,提问作者Kocas
相关产品推荐
相关产品推荐

