【Python】datetime与pd.to_datetime输出的时间戳不一样

为什么输出时间戳的值不一样,一个是1447344000,一个是1447372800,怎么让他们输出一样的值。

from datetime import datetime
import pandas as pd
tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
stmp2 = pd.to_datetime(tm)
print(stmp1.timestamp())
print(stmp2.timestamp())
## output
## 1447344000
## 1447372800

已解决

1、原因

当时间字符串不包含时区信息时,
Python中的datetime模块默认使用本地时区,因为它是基于系统的时间设置来创建和处理日期和时间对象的Pandas中的时间序列默认使用UTC时区,因为它是一个国际标准,可以避免夏令时和其他地区性的问题如果你想在Pandas中转换时区,你可以使用tz_localize和tz_convert方法。

2、时间戳转回日期时间

在线计算转换时间戳
可以看到datetime 默认使用本地时区,1447344000对应的是北京时间2015-11-13 00:00:00;pd.to_datetime默认使用UTC时区,1447372800对应的是UTC时间2015-11-13 00:00:00
在这里插入图片描述
在这里插入图片描述

3 解决方法,指定时区

3.1 使用带时区的时间字符串

from datetime import datetime
import pandas as pd
tm = '2015-11-13 00:00:00+08:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S%z")
stmp2 = pd.to_datetime(tm)
print(stmp1.timestamp())  # 输出:1447344000.0
print(stmp2.timestamp())     # 输出:1447344000.0

3.2 指定或修改datetime的时区

3.2.1 分析datetime的时间戳

from datetime import datetime
from pytz import timezone
tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
print(stmp1.timestamp())  # 输出:1447344000.0
# 指定时区,修改datetime的tzinfo属性
# 指定UTC时区
utc_dt = stmp1.replace(tzinfo=timezone("UTC"))
print(utc_dt.timestamp())  # 输出:1447372800.0
# 指定北京时区
bj_dt = stmp1.replace(tzinfo=timezone("Asia/Shanghai"))
print(bj_dt.timestamp())  # 输出:1447343640.0
# 转换时区为UTC时区
utc_dt_c = stmp1.astimezone(timezone("UTC"))
print(utc_dt_c.timestamp())  # 输出:1447344000.0
# 转换时区为北京时区
bj_dt_c = stmp1.astimezone(timezone("Asia/Shanghai"))
print(bj_dt_c.timestamp())  # 输出:1447344000.0

可以看到,replace(tzinfo=timezone(“UTC”)) 和 .astimezone(timezone) 的区别是:
replace(tzinfo=timezone(“UTC”)) 只是修改 datetime 对象的 tzinfo 属性,不会修改日期和时间的值。这样做可能会导致不正确的时间戳或时区转换。
astimezone(timezone) 会根据时区的规则,调整日期和时间的值,使得时间戳保持不变。这样做可以正确地转换时区。
所以,建议使用 astimezone(timezone) 来指定或转换时区。

3.2.2 注意

如果原始stmp1的tzinfo是(“Asia/Shanghai”),为什么bj_dt = stmp1.replace(tzinfo=timezone(“Asia/Shanghai”)),bj_dt和stmp1的时间戳不一致

这是因为 replace() 方法不会转换时区,只会修改 tzinfo 属性。如果原始 stmp1 的 tzinfo 是 (“Asia/Shanghai”),那么它的时间戳是根据北京时间计算的。如果你用 replace() 方法创建一个新的 datetime 对象 bj_dt,指定时区也是 (“Asia/Shanghai”),那么它的时间戳是根据 UTC 时间计算的,然后加上时区的偏移量。所以,两个对象的时间戳不一致。
如果你想让两个对象的时间戳一致,你可以用 astimezone() 方法来转换时区,或者用 replace() 方法来移除时区。

3.2.3 修改datetime的时间戳

from datetime import datetime
import pandas as pd
tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
stmp2 = pd.to_datetime(tm)

stmp1_pd = pd.Timestamp(stmp1, tz='UTC')
print(stmp1_pd.timestamp())  # 输出:1447372800.0
print(stmp2.timestamp())     # 输出:1447372800.0

3.3 指定pandas的时区为Asia/Shanghai时间

使用pd.Series.dt.tz_localize方法将日期时间数据本地化为目标时区。使用pd.Series.dt.tz_convert方法将日期时间数据从一种时区转换为另一种时区。

from datetime import datetime
import pandas as pd
tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
# 生成当前时间的时间戳,不指定时区
stmp2  = pd.Timestamp(tm, tz='Asia/Shanghai')
print(stmp1.timestamp())  # 输出:1447344000.0
print(stmp2.timestamp())     # 输出:1447344000.0

或者

from datetime import datetime
import pandas as pd
tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
# 生成当前时间的时间戳,不指定时区
stmp2  = pd.to_datetime(tm).tz_localize('Asia/Shanghai')
print(stmp1.timestamp())  # 输出:1447344000.0
print(stmp2.timestamp())     # 输出:1447344000.0

3.4 整列时间戳转换为北京时间

    df['tmt']= pd.to_datetime(df['stamp'], unit='s', origin=pd.Timestamp('1970-01-01')).dt.tz_localize('Asia/Shanghai')
    df['tm'] = df['tmt'].dt.strftime('%Y-%m-%d %H:%M:%S')

时间格式转换:可以使用pd.to_datetime()函数将字符串或数字转换为时间格式,例如pd.to_datetime(‘2022-01-01’)。如果需要指定时间格式,可以使用format参数,例如pd.to_datetime(‘2022-01-01’, format=‘%Y-%m-%d’)。

时区转换:可以使用tz_localize()函数将时间列本地化为某个时区,例如df[‘time’].dt.tz_localize(‘UTC’)。然后使用tz_convert()函数将其转换为另一个时区,例如df[‘time’].dt.tz_convert(‘Asia/Shanghai’)。

时间差计算:可以使用pd.Timedelta()函数计算两个时间之间的差值,例如pd.Timedelta(days=1)表示一天的时间差。也可以使用pd.DateOffset()函数进行更灵活的时间偏移计算,例如pd.DateOffset(months=3)表示三个月后的时间。

时间序列操作:pandas提供了丰富的时间序列操作函数,例如resample()函数对时间序列进行重采样,rolling()函数进行滚动窗口计算等。需要注意的是,这些函数默认使用的是本地时区的时间,如果需要在不同时区之间进行操作,需要先进行时区转换。

附录

各种AI斗志斗勇,基本无助于问题解决,以下仅供记录,参考价值有限~

文心一言

在Python中,datetime.datetime.strptime()和pd.to_datetime()都是用于将字符串转换为日期时间对象的函数,但是它们的工作方式略有不同。

datetime.datetime.strptime()函数将字符串解析为datetime.datetime对象,并根据指定的格式字符串将其转换为日期时间格式。在您的代码中,tm是一个表示日期时间的字符串,格式为"%Y-%m-%d %H:%M:%S"。stmp1是通过将tm解析为日期时间对象而创建的。

pd.to_datetime()函数是pandas库中的一个函数,用于将不同类型的日期时间输入转换为pandas.Timestamp对象。在您的代码中,tm是一个表示日期时间的字符串,stmp2是通过将tm转换为pandas.Timestamp对象而创建的。

在转换日期时间对象为时间戳时,两种方法的输出可能会不同。stmp1.timestamp()将返回基于Unix时间戳的浮点数,表示从1970年1月1日开始的秒数。而stmp2.timestamp()将返回基于pandas库内部时间戳的整数,表示从pandas库的版本开始的时间戳。

因此,根据使用的库和日期时间对象的表示方式,输出可能会不同。请注意,在使用这两种方法时,应该确保使用相同的时间戳表示方式,以便进行比较和计算。

要让datetime.datetime.strptime()和pd.to_datetime()输出的时间戳一致,可以使用pd.to_datetime()函数将datetime.datetime对象转换为pandas.Timestamp对象,并指定参数unit=‘unix’,这将把时间戳转换为Unix时间戳。

以下是示例代码:

import datetime  
import pandas as pd  
  
tm = '2015-11-13 00:00:00'  
stmp1 = datetime.datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")  
stmp2 = pd.to_datetime(stmp1, unit='unix')  
  
print(stmp1.timestamp())  
print(stmp2.timestamp())

输出将会一致,都为Unix时间戳:

1447438800.0
1447438800
注意,在这段代码中,我们首先使用datetime.datetime.strptime()将字符串转换为datetime.datetime对象,然后使用pd.to_datetime()将datetime.datetime对象转换为pandas.Timestamp对象,并将其作为参数传递给unit=‘unix’。这样可以将时间戳转换为Unix时间戳,从而实现输出的一致性。

笔者注:报错了
在这里插入图片描述

星火

这是因为pd.to_datetime()函数的utc=True参数会将时间字符串转换为UTC时间,而strptime()函数则不会。如果您想要得到相同的时间戳,可以使用以下代码:

import pandas as pd
from datetime import datetime

tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
stmp2 = pd.to_datetime(tm, format="%Y-%m-%d %H:%M:%S").replace(tzinfo=None)
print(stmp1.timestamp())
print(stmp2.timestamp())

笔者注:我这边输出为还是不一致

## output
## 1447344000.0
## 1447372800.0

bing

这个问题可能是由于时区设置不同导致的。pandas.to_datetime() 函数在默认情况下不会强制输入转换为 UTC,时区不明确的输入将保持不明确,而时区明确的输入将保留其时间偏移量1。您可以尝试在调用 pd.to_datetime() 时设置 utc=True 参数,以便始终返回带有时区的 UTC 本地化的时间戳。

您可以尝试以下代码:

import pandas as pd
tm = '2015-11-13 00:00:00'
stmp1 = pd.to_datetime(tm, utc=True)
stmp2 = pd.to_datetime(tm, utc=True)
print(stmp1.timestamp())
print(stmp2.timestamp())

如果您希望 datetime 库输出的结果与 pandas 库输出的结果一致,您可以尝试在调用 datetime.datetime.strptime() 时指定时区信息。例如,您可以使用以下代码:

from datetime import datetime, timezone
import pandas as pd

tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
stmp2 = pd.to_datetime(tm, utc=True)

print(stmp1.timestamp())
print(stmp2.timestamp())

笔者注:直接给我替换了

## output
## 1447344000.0
## 1447372800.0

通义千问

因为datetime.datetime.strptime方法接受一个字符串作为参数,而pandas.to_datetime方法可以将任何时间格式的字符串转换为datetime对象,因此如果两个时间戳字符串的格式不同,它们转换为datetime对象后,它们的timestamp值也不会相同。
要让两个datetime对象输出相同的timestamp值,需要将它们转换为相同的格式,例如使用datetime.datetime.strptime方法将两个字符串都转换为datetime.strptime方法支持的格式。然后,再使用datetime.timestamp方法将它们转换为timestamp值。
以下是一个示例代码,演示如何将两个datetime对象转换为相同的格式,并使它们输出相同的timestamp值:

from datetime import datetime, timedelta

### 创建两个datetime对象
tm = '2015-11-13 00:00:00'
stmp1 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")
stmp2 = datetime.strptime(tm, "%Y-%m-%d %H:%M:%S %H:%M:%S")

###  将它们转换为相同的格式
stmp1 = stmp1.replace(microsecond=0)
stmp2 = stmp2.replace(microsecond=0)

###  将它们转换为timestamp值
timestamp1 = stmp1.timestamp()
timestamp2 = stmp2.timestamp()

### 输出结果
print("strptime结果:", timestamp1)
print("strptime结果:", timestamp2)
输出结果为:

strptime结果: 2016-11-11 16:23:11
strptime结果: 2016-11-11 16:23:11

可以看到,两个datetime对象经过转换后,它们的timestamp值相同。注意,在使用datetime.strptime方法将日期时间字符串转换为datetime对象时,如果指定了日期时间格式,则要使用相同的格式进行转换,否则可能会导致timestamp值不同。

ChatGLM

这是因为 datetime.datetime.strptime() 和 pd.to_datetime() 两个函数对时间字符串的解析方式不同所导致的。
datetime.datetime.strptime() 函数是 Python 标准库中的日期时间函数,它将时间字符串解析为 Python 内置的 datetime 对象。该函数的参数中,时间格式字符串需要按照 %Y-%m-%d %H:%M:%S 的格式进行传递。
而 pd.to_datetime() 函数是 Pandas 库中的日期时间函数,它将时间字符串解析为 Pandas 的 Timestamp 对象。该函数的参数中,时间格式字符串需要按照 %Y-%m-%d %H:%M:%S 的格式进行传递,并且需要先使用 pandas.to_datetime() 函数将时间字符串转换为 datetime64 类型。
因此,如果要让这两个函数输出相同的时间戳值,需要将时间字符串按照相同的格式进行传递,并且使用 pandas.to_datetime() 函数将时间字符串转换为 datetime64 类型。如下所示:

tm = '2015-11-13 00:00:00'  
stmp1 = datetime.datetime.strptime(tm, "%Y-%m-%d %H:%M:%S")  
stmp2 = pandas.to_datetime(tm)
print(stmp1.timestamp())  
print(stmp2.timestamp())  
输出结果:
1447344000.0  
1447344000.0  

猜你喜欢

转载自blog.csdn.net/qq_25262697/article/details/131465120