【问题标题】:Calculating the difference between two datetimes?计算两个日期时间之间的差异?
【发布时间】:2021-11-25 18:09:44
【问题描述】:
from datetime import datetime
import pytz

cur_time = datetime.now()
cur_time = pytz.utc.localize(cur_time)

rr_name = 'xx_20211005141746.txt'
rr_time =  re.search('_(.*).txt', rr_name).group(1)
rr_time =  datetime.strptime(rr_time, '%Y%m%d%H%M%S')

tzone = "Europe/London"
hb_time = pytz.utc.localize(rr_time).astimezone(pytz.timezone(tzone))
                    
diff = cur_time - hb_time

l_heared = round((diff.total_seconds() / 60), 2) 

cur_time 和 rr_time 之间的差异大约是 6 分钟,也就是 360 秒。 delta 怎么还给我77.65 秒...

请注意 cur_time 和 rr_name 是本地日期时间

【问题讨论】:

  • 你能澄清你在问什么吗?是的,区别是“大约 6 分钟”——即 5 分钟、37 秒、525332 微秒。你还期待什么?
  • 另外,编辑问题时要小心,在更改上下文时留下一些痕迹,因为现在我的答案看起来有点跑题了(原来的错误不同)
  • 什么是hb_time?
  • 请查看minimal reproducible example 页面。如果您不确定日期时间的计算,请忽略文件名并重新填写。如果您不确定文件名和内容,请忽略日期时间计算。不要依赖于“当前时间”,因为它是不可重现的。无论哪种方式,请确保示例最小但完整。
  • 对不起,编辑它(再次)

标签: python datetime timezone timedelta


【解决方案1】:

使用total_seconds 方法:

print(f'{delta.total_seconds()} seconds')

输出:337.525332 seconds

【讨论】:

  • 为什么?有什么区别?
  • delta不是字符串,而是timedelta对象,如果使用str(delta)会得到这个对象的字符串表示,也就是不是的总数秒数(但'0:05:37.525332')
  • 还是不行
  • 它怎么不起作用?它对我有用,所以要么你没有在相同的数据上运行它,要么你的 python/timedelta 版本可能有问题(它是最近的吗?虽然是最有可能的选项 #1)
  • @ManCity10 那么请提供这个数据,到目前为止它运行良好,你只是输入了错误的变量
【解决方案2】:

您必须为直接存储在文件名中的日期/时间设置正确的时区,不要先将其设置为 UTC,然后再转换:

import re
from datetime import datetime
from zoneinfo import ZoneInfo # Python 3.9+ ; there is backports.zoneinfo for older versions
# import pytz

now = datetime.now(ZoneInfo('UTC'))
# now = datetime.now(pytz.UTC)
print(now.astimezone(ZoneInfo('Europe/London')))
# 2021-10-05 14:58:43.957950+01:00

rr_name = 'xx_20211005141746.txt' # time zone Europe/London in filename ...
rr_time =  re.search('_(.*).txt', rr_name).group(1)
rr_time =  datetime.strptime(rr_time, '%Y%m%d%H%M%S').replace(tzinfo=ZoneInfo('Europe/London'))
# rr_time = pytz.timezone('Europe/London').localize(datetime.strptime(rr_time, '%Y%m%d%H%M%S'))
print(rr_time)
# 2021-10-05 14:17:46+01:00

l_heared = round(((now-rr_time).total_seconds() / 60), 2) 
print(l_heared, "minutes ago")
# 40.97 minutes ago

什么时候会失败

实际上,由于文件名的时间戳不提供 UTC 偏移量,因此对于 DST 转换夏季 -> 冬季时间 将失败,因为挂钟将在 两个小时内显示凌晨 1 点!例如:

from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

tz = ZoneInfo("Europe/London")
tzutc = ZoneInfo("UTC")

dt = [datetime(2021, 10, 30, 23, tzinfo=tzutc) + timedelta(hours=i) for i in range(4)]
dt = [d.astimezone(tz) for d in dt]

for d in dt: print(d)
# 2021-10-31 00:00:00+01:00
# 2021-10-31 01:00:00+01:00
# 2021-10-31 01:00:00+00:00 # DST change, 1 AM appears for two hours!
# 2021-10-31 02:00:00+00:00

t_ref = datetime(2021, 10, 31, 3, tzinfo=tzutc)
for t in dt: print(f"{t} -> age: {t_ref-t}")
# 2021-10-31 00:00:00+01:00 -> age: 4:00:00
# 2021-10-31 01:00:00+01:00 -> age: 3:00:00
# 2021-10-31 01:00:00+00:00 -> age: 2:00:00 # only correct because input is aware datetime with correct UTC offset
# 2021-10-31 02:00:00+00:00 -> age: 1:00:00

# ---------- DST winter -> summer works fine though: ----------

dt = [datetime(2021, 3, 28, tzinfo=tzutc) + timedelta(hours=i) for i in range(4)]
dt = [d.astimezone(tz) for d in dt]

for d in dt: print(d)
# 2021-03-28 00:00:00+00:00
# 2021-03-28 02:00:00+01:00 # DST change, 1 AM is skipped
# 2021-03-28 03:00:00+01:00
# 2021-03-28 04:00:00+01:00

t_ref = datetime(2021, 3, 28, 3, tzinfo=tzutc)
for t in dt: print(f"{t} -> age: {t_ref-t}")
# 2021-03-28 00:00:00+00:00 -> age: 3:00:00
# 2021-03-28 02:00:00+01:00 -> age: 2:00:00 # this time no ambiguity
# 2021-03-28 03:00:00+01:00 -> age: 1:00:00
# 2021-03-28 04:00:00+01:00 -> age: 0:00:00

【讨论】:

  • 我的本地时间是UTC+2,文件中使用的日期时间是UTC+1。我有1小时的间隔。文件名中的时间实际上应该有 +1 小时....但我不能更改文件名,因为它是一个不断变化的变量
  • 我有python 3.7.7版
  • @ManCity10 我已经包含了 pytz 选项。在 Python 3.7.7 中,您仍然可以使用 backports.zoneinfo 模块或 dateutil,它们遵循与 zoneinfo 相同的语义。
  • 我无法安装 zoneinfo。 ERROR: Could not install packages due to an EnvironmentError: [WinError 5] Access is denied: 'C:\\ProgramData\\Anaconda3\\Lib\\site-packages\\backports\\__init__.py' Consider using the --user` 选项或检查权限。`
  • 现在怎么比我的实际时间晚了两个小时?现在是 CEST 16:46
猜你喜欢
  • 2011-08-01
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多