如何在Polars中为datetime对象动态处理UTC偏移量?
Polars中处理带动态UTC偏移(夏令时)的Datetime对象
我需要在Polars中为datetime对象添加/扣除动态UTC偏移量(受夏令时影响,比如美国东部时区EST/EDT分别对应-5/-4小时偏移),但没找到直接可行的方法。
from datetime import datetime, date import pytz import polars as pl # 生成覆盖夏令时段的UTC时间序列DataFrame df = pl.DataFrame( pl.date_range(low=date(2022,1,3), high=date(2022,9,30), interval="5m", time_unit="ns", time_zone="UTC") .alias("timestamp") ) # 将时区转换为涵盖EST和EDT的"America/New_York" us_df = df.with_column( pl.col("timestamp") .dt .cast_time_zone(tz="America/New_York") .alias("datetime") )
查看us_df输出,Polars显示的美国时间未包含UTC偏移(在0.14.22版本前会显示带偏移的时间,比如23:45:00 UTC应显示为19:45:00 EDT,现在显示为15:45:00 EDT):
┌─────────────────────────┬────────────────────────────────┐ │ timestamp ┆ datetime │ │ --- ┆ --- │ │ datetime[ns, UTC] ┆ datetime[ns, America/New_York] │ ╞═════════════════════════╪════════════════════════════════╡ │ 2022-01-03 00:00:00 UTC ┆ 2022-01-02 14:00:00 EST │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-01-03 00:05:00 UTC ┆ 2022-01-02 14:05:00 EST │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-01-03 00:10:00 UTC ┆ 2022-01-02 14:10:00 EST │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-01-03 00:15:00 UTC ┆ 2022-01-02 14:15:00 EST │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ ... ┆ ... │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-09-29 23:45:00 UTC ┆ 2022-09-29 15:45:00 EDT │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-09-29 23:50:00 UTC ┆ 2022-09-29 15:50:00 EDT │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-09-29 23:55:00 UTC ┆ 2022-09-29 15:55:00 EDT │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ 2022-09-30 00:00:00 UTC ┆ 2022-09-29 16:00:00 EDT │ └─────────────────────────┴────────────────────────────────┘
将数据转换为pandas后,可以看到底层datetime对象实际包含UTC偏移(数据同时覆盖了-5小时的EST时段和-4小时的EDT时段):
# 转换为pandas us_pd = us_df.to_pandas() us_pd
输出:
timestamp datetime 0 2022-01-03 00:00:00+00:00 2022-01-02 14:00:00-05:00 1 2022-01-03 00:05:00+00:00 2022-01-02 14:05:00-05:00 2 2022-01-03 00:10:00+00:00 2022-01-02 14:10:00-05:00 3 2022-01-03 00:15:00+00:00 2022-01-02 14:15:00-05:00 4 2022-01-03 00:20:00+00:00 2022-01-02 14:20:00-05:00 ... ... ... 77756 2022-09-29 23:40:00+00:00 2022-09-29 15:40:00-04:00 77757 2022-09-29 23:45:00+00:00 2022-09-29 15:45:00-04:00 77758 2022-09-29 23:50:00+00:00 2022-09-29 15:50:00-04:00 77759 2022-09-29 23:55:00+00:00 2022-09-29 15:55:00-04:00 77760 2022-09-30 00:00:00+00:00 2022-09-29 16:00:00-04:00
我需要把UTC偏移量直接整合到实际时间值中,这样就能自然地进行时间过滤。比如23:00 UTC对应19:00 EDT,我希望能直接用19:00作为过滤条件。由于夏令时会导致偏移量动态变化,无法在过滤时临时手动加减偏移。
Python原生datetime对象有utcoffset()方法可以处理单个对象,但这需要先把Polars数据转换为pandas,我想知道如何直接在Polars内部实现这个操作。
另外我发现一个差异:
# 取pandas最后一行的datetime转换为原生对象 us_pd.datetime[us_pd.shape[0]-1].to_pydatetime() # 结果与Polars和pandas中的数据一致 # 输出:datetime.datetime(2022, 9, 29, 16, 0, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>) # 手动创建UTC时间并转换为纽约时区 datetime(2022, 9, 30, 22, 45, 0,0, pytz.utc).astimezone(pytz.timezone("America/New_York")) # 此处显示的是正确的纽约时间(已应用偏移) # 输出:datetime.datetime(2022, 9, 30, 18, 45, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
内容的提问来源于stack exchange,提问作者stucash
相关产品推荐
相关产品推荐

