datetime与pandas如何控制时区timezone

同一个时间,发现使用datetime包和pandas的to_datetime转换得到的timestamp不一样,

import pandas as pd
import datetime
import pytz

df = pd.DataFrame({'time':['2024-6-1 08:00:00']})
dt = datetime.datetime.strptime(df.iloc[0]['time'], '%Y-%m-%d %H:%M:%S')
print('使用datetime:', dt.timestamp())
df['time'] = pd.to_datetime(df['time'])
print('使用pandas:', df.iloc[0]['time'].timestamp())
使用datetime: 1717200000.0
使用pandas: 1717228800.0

差距8个小时,明显是因为时区不一致导致的,进行如下试验:

一、pandas

定义一个dataframe如下:

df = pd.DataFrame({'id':[1,2], 'time':['2024-06-01 08:00:00','2024-06-01 00:00:00']})
df['time'] = pd.to_datetime(df['time'])

在这里插入图片描述

dt = df.iloc[0]['time']
print(dt)
print(dt.tzname(), dt.timestamp())
df['time'] = df['time'].dt.tz_localize(tz='Asia/Shanghai')
dt = df.iloc[0]['time']
print(dt)
print(dt.tzname(), dt.timestamp())
df['time'] = df['time'].dt.tz_convert(tz='Asia/Tokyo')
dt = df.iloc[0]['time']
print(dt)
print(dt.tzname(), dt.timestamp())
2024-06-01 08:00:00
None 1717228800.0
2024-06-01 08:00:00+08:00
CST 1717200000.0
2024-06-01 09:00:00+09:00
JST 1717200000.0

由pandas的to_datetime生成时间,若不设置时区,时间属性是timezone-naive,但默认对应到UTC时区,即UTC的’2024-6-1 08:00:00’;
使用tz_localize设置为北京时间后,从tz-naive变为tz-aware,变为北京时间UTC+8的‘2024-06-01 08:00:00’,timestamp变更;
使用tz_convert更改时区,更改时区不会改变timestamp,且只能convert tz-aware时间。
另外,dataframe输出到文件时,Excel不支持tz-aware时间,csv可以。

二、datetime

date_time_str = '2024-6-1 08:00:00'
dt = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
print(dt)
print(dt.tzname(), dt.timestamp())
dt = dt.astimezone(pytz.timezone('Asia/Tokyo'))
print(dt)
print(dt.tzname(), dt.timestamp())
dt = dt.astimezone(pytz.timezone('Asia/Shanghai'))
print(dt)
print(dt.tzname(), dt.timestamp())
2024-06-01 08:00:00
None 1717200000.0
2024-06-01 09:00:00+09:00
JST 1717200000.0
2024-06-01 08:00:00+08:00
CST 1717200000.0

由datetime的strptime生成时间,时间也是timezone-naive,但默认对应到当地时间,这里是北京时间的’2024-6-1 08:00:00’,即UTC的’2024-6-1 00:00:00’;
astimezone可以更改时区但不会改变timestamp,对于tz-naive时间也保留其timestamp。

date_time_str = '2024-6-1 08:00:00'
dt = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
print(dt)
print(dt.tzname(), dt.timestamp())
dt = pytz.timezone('Asia/Tokyo').localize(dt)
print(dt)
print(dt.tzname(), dt.timestamp())
dt = dt.astimezone(pytz.timezone('Asia/Shanghai'))
print(dt)
print(dt.tzname(), dt.timestamp())
2024-06-01 08:00:00
None 1717200000.0
2024-06-01 08:00:00+09:00
JST 1717196400.0
2024-06-01 07:00:00+08:00
CST 1717196400.0

pytz.timezone().localize用来设置时区,会更改timestamp。

总结

pandas的to_datetime生成时间,默认对应到UTC时区;而由datetime.strptime生成的时间,默认对应到当地时间。
pandas的tz_localize与pytz.timezone().localize作用一致,用来设置时区,将tz-naive时间变为tz-aware,会更改timestamp,且只能设置一次。
pandas的tz_convert与datetime.astimezone()作用一致,用来更改时区,更改时区不会改变timestamp,区别是tz_convert只能作用于tz-aware时间,astimezone可以用于tz-naive和tz-aware,且astimezone处理过的时间本身也是tz-aware。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值