我试图使用django.utils.dateparse
模块的parse_duration()
功能,分别代表一年或一个月的ISO 8601持续时间P1Y
或P1M
。返回的值是None
。该函数的文档显示它支持ISO 8601持续时间。但是看来它支持标准没有数年或几个月,因为我可以成功解析持续时间P2DT12H60M33S
,从而导致2天和46833秒的timedelta
对象。这是一个错误,一个功能还是我做错了什么?
来自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>dd):' r'(?P<seconds>dd)' r'(?:.(?P<microseconds>d{1,6}))?' r')?$' )
第一个正则表达式用于解析ISO 8601持续时间。正如上面的iso8601_duration_re
所述,仅支持timedelta
接受的ISO 8601持续时间的部分。其中timedelta
仅支持几周,天,小时,分钟,秒,毫秒和 microseconds 。在postgres_interval_re
上方的评论中也清楚地说明了这一点:
年度和混合间隔不能转换为时间码,因此不接受。
不支持数年或几个月的事实,也可以通过检查源代码来证明。例如,iso8601_duration_re
正则表达式的代码仅在天,小时,分钟和秒的情况下进行解析。几年或几个月没有指示。
我认为,由于持续时间模棱两可,因此有一个不支持数月和数年的原因。一个月可以是 28,29,30 或 31 天,一年可以是 365 或 366 天。在ISO 8601中允许这种歧义,但在timedelta
对象中不允许使用这种歧义(请参阅此答案(。这是因为它在内部将持续时间存储在天中,秒和 microsconds (请参阅此处(,因此, 1年的timedelta
,例如可以是 365天,0秒和 0微秒或 366天,0秒和 0 microseconds <<。/p>