鉴于ISO 8601持续时间字符串,如何将其转换为datetime.timedelta
?
这没有用:
timedelta("PT1H5M26S", "T%H%M%S")
答案 0 :(得分:24)
我发现isodate库正是我想做的
<?php
class DB
{
public static function connect()
{
$hostname = 'localhost';
$username = 'user';
$password = 'password';
$dbName = 'dbname';
$connection = new mysqli($hostname, $username, $password, $dbName);
if ($connection->connect_error) {
die('Failed to connect');
}
return $connection;
}
}
答案 1 :(得分:1)
这是一个没有新软件包的解决方案,但仅在您要处理以天为单位的最大持续时间时才有效。不过,这种限制是有道理的,因为正如其他人指出的那样(1):
鉴于timedelta具有超过“一个月”的天数, 您会使用ISO8601持续时间符号来描述它吗 引用特定时间点?相反,以您的示例为例, “ P3Y6M4DT12H30M5S”,如何将其转换为时间增量 不知道这段持续时间指的是确切的年月。 Timedelta对象是非常精确的野兽,几乎可以肯定 为什么他们不支持“年”和“月”参数 构造函数。
import datetime
def get_isosplit(s, split):
if split in s:
n, s = s.split(split)
else:
n = 0
return n, s
def parse_isoduration(s):
# Remove prefix
s = s.split('P')[-1]
# Step through letter dividers
days, s = get_isosplit(s, 'D')
_, s = get_isosplit(s, 'T')
hours, s = get_isosplit(s, 'H')
minutes, s = get_isosplit(s, 'M')
seconds, s = get_isosplit(s, 'S')
# Convert all to seconds
dt = datetime.timedelta(days=int(days), hours=int(hours), minutes=int(minutes), seconds=int(seconds))
return int(dt.total_seconds())
> parse_isoduration("PT1H5M26S")
3926
答案 2 :(得分:0)
好问题,显然“正确”的解决方案取决于您对输入的期望(更可靠的数据源不需要那么多输入验证)。
我解析 ISO8601 持续时间时间戳的方法仅检查“PT”前缀是否存在,并且不会假设任何单位的整数值:
from datetime import timedelta
def parse_isoduration(isostring, as_dict=False):
"""
Parse the ISO8601 duration string as hours, minutes, seconds
"""
separators = {
"PT": None,
"W": "weeks",
"D": "days",
"H": "hours",
"M": "minutes",
"S": "seconds",
}
duration_vals = {}
for sep, unit in separators.items():
partitioned = isostring.partition(sep)
if partitioned[1] == sep:
# Matched this unit
isostring = partitioned[2]
if sep == "PT":
continue # Successful prefix match
dur_str = partitioned[0]
dur_val = float(dur_str) if "." in dur_str else int(dur_str)
duration_vals.update({unit: dur_val})
else:
if sep == "PT":
raise ValueError("Missing PT prefix")
else:
# No match for this unit: it's absent
duration_vals.update({unit: 0})
if as_dict:
return duration_vals
else:
return tuple(duration_vals.values())
dur_isostr = "PT3H2M59.989333S"
dur_tuple = parse_isoduration(dur_isostr)
dur_dict = parse_isoduration(dur_isostr, as_dict=True)
td = timedelta(**dur_dict)
s = td.total_seconds()
⇣
>>> dur_tuple
(0, 0, 3, 2, 59.989333)
>>> dur_dict
{'weeks': 0, 'days': 0, 'hours': 3, 'minutes': 2, 'seconds': 59.989333}
>>> td
datetime.timedelta(seconds=10979, microseconds=989333)
>>> s
10979.989333
答案 3 :(得分:0)
基于@r3robertson 一个更完整但不完美的版本
int