计算两个日期时间之间的差异?
Calculating the difference between two datetimes?
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
是原生日期时间
使用total_seconds
方法:
print(f'{delta.total_seconds()} seconds')
输出:337.525332 seconds
直接保存在文件名中的date/time需要设置正确的时区,不要先设置成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
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
是原生日期时间
使用total_seconds
方法:
print(f'{delta.total_seconds()} seconds')
输出:337.525332 seconds
直接保存在文件名中的date/time需要设置正确的时区,不要先设置成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