gpt4 book ai didi

python - 简化处理当前使用 datetime 和 isodate 的时间和持续时间的代码?

转载 作者:行者123 更新时间:2023-12-01 09:02:48 27 4
gpt4 key购买 nike

下面的代码应该是:

  • 将输入字符串解析为某种持续时间
  • 验证持续时间不为空、不为负、不超过 10 年

输入字符串的示例是:

duration_string = "P10W"
duration_string = "P1Y"

这是代码

    duration = isodate.parse_duration(duration_string)

if isinstance(duration, datetime.timedelta):
if not duration > datetime.timedelta(0):
raise Exception('duration invalid')
if duration > datetime.timedelta(3660):
raise Exception('duration cannot be longer than 10 years')
elif isinstance(duration, isodate.Duration):
if not duration > 0:
raise Exception('duration invalid')
if duration > isodate.duration.Duration(0, 0, 0, years=10, months=0):
log.debug("duration %s isodate %s" % (duration, isodate.duration.Duration(0, 0, 0, years=10, months=0)))
raise Exception('duration cannot be longer than 10 years')

还有比我制作的怪物更简单的方法吗?

除了需要简化之外,行duration > isodate.duration.Duration(0, 0, 0,years=10,months=0)不起作用。

我使用的是Python 2.7

最佳答案

好的,如果您绝对必须使用 isodate 持续时间解析,请保留 isodate 库。不过,我要提一下,isodate 库并不完整,有许多糟糕的设计决策,而且总体来说很糟糕。

但是,如果您必须使用他们的解析工具,这可能是一个好方法。

import isodate
import functools

@functools.total_ordering # if we implement < ==, will implement <=, >, >=
class Duration(isodate.Duration):
# inherit from isodate.Duration -- gives us ==

# constants
seconds_in_day = 60**2 * 24
approx_days_in_month = 30
approx_days_in_year = 365

def approx_total_seconds(self):
"""approx total seconds in duration"""
# self.months and self.years are stored as `Decimal`s for some reason...
return self.tdelta.total_seconds() \
+ float(self.months) * self.approx_days_in_month * self.seconds_in_day \
+ float(self.years) * self.approx_days_in_year * self.seconds_in_day

def __lt__(self, other):
"""defines self < other"""
if not isinstance(other, Duration):
return NotImplemented
return self.approx_total_seconds() < other.approx_total_seconds()

@classmethod
def parse_duration(cls, datestring):
"""a version of isodate.parse_duration that returns out class"""

iso_dur = isodate.parse_duration(datestring)

# iso_date.parse_duration can return either a Duration or a timedelta...
if isinstance(iso_dur, isodate.Duration):
return cls(seconds=iso_dur.tdelta.total_seconds(),
months=iso_dur.months, years=iso_dur.years)
else:
return cls(seconds=iso_dur.total_seconds())


ten_weeks = Duration.parse_duration('P10W')
one_year = Duration.parse_duration('P1Y')

print(ten_weeks.approx_total_seconds())
print(one_year.approx_total_seconds())

print(ten_weeks < one_year)
print(ten_weeks > one_year)

输出

6048000.0
31536000.0
True
False
<小时/>

如果您不需要 isodate 解析(我怀疑您不需要),您可以这样做

@functools.TotalOrdering
class ApproxTimeDelta:

approx_days_in_week = 7
approx_days_in_month = 30
approx_days_in_year = 365

def __init__(self, days, weeks, months, years):
self.days = days + \
weeks * self.approx_days_in_week + \
months * self.approx_days_in_month + \
years * self.approx_days_in_year

def __eq__(self, other):
return self.days == other.days

def __lt__(self, other):
return self.days < other.days

并将年/月/周/日作为整数传递并像以前一样进行比较。

关于python - 简化处理当前使用 datetime 和 isodate 的时间和持续时间的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52333190/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com