如何将Pandas时区感知的时间戳转换为UNIX时间戳?

3 投票
1 回答
1074 浏览
提问于 2025-04-18 01:43

我需要把一个带时区的日期范围(时间戳)转换成UNIX时间戳,以便在一个外部的JavaScript库中使用。

我的方法是:

# Create localized test data for one day
rng = pd.date_range('1.1.2014', freq='H', periods=24, tz="Europe/Berlin")
val = np.random.randn(24)
df = pd.DataFrame(data=val, index=rng, columns=['values'])

# Reset index as df column
df = df.reset_index()

# Convert the index column to the desired UNIX epoch format
df['index'] = df['index'].apply(lambda x: x.value // 10**6 )

df['index']里面的UNIX时间戳值是符合预期的,但它们存储的是UTC时间(协调世界时)!

我想这可能是因为pandas在内部使用的是numpy的UTC datetime64格式来存储时间戳。

有没有什么聪明的方法可以得到在指定时区下的“正确”时间戳值呢?

这个提议在夏令时下不适用

1 个回答

1
In [17]: df
Out[17]: 
                             values
2014-01-01 00:00:00+01:00  1.027799
2014-01-01 01:00:00+01:00  1.579586
2014-01-01 02:00:00+01:00  0.202947
2014-01-01 03:00:00+01:00 -0.214921
2014-01-01 04:00:00+01:00  0.021499
2014-01-01 05:00:00+01:00 -1.368302
2014-01-01 06:00:00+01:00 -0.261738

2014-01-01 22:00:00+01:00  0.808506
2014-01-01 23:00:00+01:00  0.459895

[24 rows x 1 columns]

使用索引方法 asi8 来转换为 int64(这个数据已经是从纪元开始的 ns 了)这些时间是 UTC 时间!

In [18]: df.index.asi8//10**6
Out[18]: 
array([1388530800000, 1388534400000, 1388538000000, 1388541600000,
       1388545200000, 1388548800000, 1388552400000, 1388556000000,
       1388559600000, 1388563200000, 1388566800000, 1388570400000,
       1388574000000, 1388577600000, 1388581200000, 1388584800000,
       1388588400000, 1388592000000, 1388595600000, 1388599200000,
       1388602800000, 1388606400000, 1388610000000, 1388613600000])

这些是从纪元开始的本地时区时间。注意,这通常不是一个公开的方法,我一般会交换 UTC 数据(如果需要的话,还会处理时区)。

In [7]: df.index._local_timestamps()//10**6
Out[7]: 
array([1388534400000, 1388538000000, 1388541600000, 1388545200000,
       1388548800000, 1388552400000, 1388556000000, 1388559600000,
       1388563200000, 1388566800000, 1388570400000, 1388574000000,
       1388577600000, 1388581200000, 1388584800000, 1388588400000,
       1388592000000, 1388595600000, 1388599200000, 1388602800000,
       1388606400000, 1388610000000, 1388613600000, 1388617200000])

撰写回答