我正在尝试使用P1Y
模块的P1M
函数分析ISO 8601持续时间parse_duration()
或django.utils.dateparse
,分别代表一年或一个月。但返回的值为None
。该函数的文档说它支持ISO 8601持续时间。但似乎它支持标准而没有数年或数月,因为我可以成功解析持续时间P2DT12H60M33S
,导致timedelta
对象为2天和46833秒。这是一个错误,一个功能还是我做错了什么?
答案 0 :(得分:0)
来自dateparse.py模块的源代码:
# Support the sections of ISO 8601 date representation that are accepted by # timedelta iso8601_duration_re = re.compile( r'^(?P<sign>[-+]?)' r'P' r'(?:(?P<days>\d+(.\d+)?)D)?' r'(?:T' r'(?:(?P<hours>\d+(.\d+)?)H)?' r'(?:(?P<minutes>\d+(.\d+)?)M)?' r'(?:(?P<seconds>\d+(.\d+)?)S)?' r')?' r'$' ) # Support PostgreSQL's day-time interval format, e.g. "3 days 04:05:06". The # year-month and mixed intervals cannot be converted to a timedelta and thus # aren't accepted. postgres_interval_re = re.compile( r'^' r'(?:(?P<days>-?\d+) (days? ?))?' r'(?:(?P<sign>[-+])?' r'(?P<hours>\d+):' r'(?P<minutes>\d\d):' r'(?P<seconds>\d\d)' r'(?:\.(?P<microseconds>\d{1,6}))?' r')?$' )
第一个正则表达式用于解析ISO 8601持续时间。正如iso8601_duration_re
上面的评论所述,仅支持timedelta
接受的ISO 8601持续时间部分。 timedelta
仅支持周,日,小时,分钟,秒,毫秒和微秒的位置。 postgres_interval_re
:
年 - 月和混合间隔不能转换为timedelta,因此不被接受。
通过检查源代码也可以证明不支持数年或数月的事实。例如,iso8601_duration_re
正则表达式的代码仅包含天,小时,分钟和秒的解析说明。几年或几个月都没有说明。
我认为有理由不支持数月和数年,因为它们的持续时间不明确。一个月可以是 28,29,30 或 31 天,一年可以是 365 或 366 天。 ISO 8601允许这种歧义,但timedelta
对象中不允许这种歧义(参见this answer)。这是因为在内部它会将持续时间存储在天,秒和微秒(请参阅here),因此<{1>} 1年例如,可以是 365天,0秒和 0微秒或 366天,0秒和 0微秒。