74 python date date-range
我有两个日期范围,其中每个范围由开始和结束日期(显然,datetime.date()实例)确定.这两个范围可以重叠或不重叠.我需要重叠的天数.当然,我可以预先填充两个集合,所有日期都在两个范围内,并且执行一个集合交集,但这可能是低效的...除了使用覆盖所有情况的长if-elif部分的另一个解决方案之外,还有更好的方法吗?
Ray*_*ger 158
这是一个示例计算:
>>> from datetime import datetime
>>> from collections import namedtuple
>>> Range = namedtuple('Range', ['start', 'end'])
>>> r1 = Range(start=datetime(2012, 1, 15), end=datetime(2012, 5, 10))
>>> r2 = Range(start=datetime(2012, 3, 20), end=datetime(2012, 9, 15))
>>> latest_start = max(r1.start, r2.start)
>>> earliest_end = min(r1.end, r2.end)
>>> delta = (earliest_end - latest_start).days + 1
>>> overlap = max(0, delta)
>>> overlap
52
Run Code Online (Sandbox Code Playgroud)
函数调用比算术运算更昂贵.
这样做的最快方法是2次减法和1分钟():
min(r1.end - r2.start, r2.end - r1.start).days + 1
Run Code Online (Sandbox Code Playgroud)
与下一个需要1减法,1分钟()和最大()的最佳相比:
(min(r1.end, r2.end) - max(r1.start, r2.start)).days + 1
Run Code Online (Sandbox Code Playgroud)
当然,对于这两个表达式,您仍需要检查正面重叠.
小智 6
我实现了一个TimeRange类,如下所示。
get_overlapped_range首先通过简单的条件取反所有非重叠选项,然后通过考虑所有可能的选项来计算重叠范围。
要获得天数,您需要获取从get_overlapped_range返回的TimeRange值,然后将持续时间除以60 * 60 * 24。
class TimeRange(object):
def __init__(self, start, end):
self.start = start
self.end = end
self.duration = self.end - self.start
def is_overlapped(self, time_range):
if max(self.start, time_range.start) < min(self.end, time_range.end):
return True
else:
return False
def get_overlapped_range(self, time_range):
if not self.is_overlapped(time_range):
return
if time_range.start >= self.start:
if self.end >= time_range.end:
return TimeRange(time_range.start, time_range.end)
else:
return TimeRange(time_range.start, self.end)
elif time_range.start < self.start:
if time_range.end >= self.end:
return TimeRange(self.start, self.end)
else:
return TimeRange(self.start, time_range.end)
def __repr__(self):
return '{0} ------> {1}'.format(*[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(d))
for d in [self.start, self.end]])
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以使用 datetimerange 包:https : //pypi.org/project/DateTimeRange/
from datetimerange import DateTimeRange
time_range1 = DateTimeRange("2015-01-01T00:00:00+0900", "2015-01-04T00:20:00+0900")
time_range2 = DateTimeRange("2015-01-01T00:00:10+0900", "2015-01-04T00:20:00+0900")
tem3 = time_range1.intersection(time_range2)
if tem3.NOT_A_TIME_STR == 'NaT': # No overlap
S_Time = 0
else: # Output the overlap seconds
S_Time = tem3.timedelta.total_seconds()
Run Code Online (Sandbox Code Playgroud)
DateTimeRange() 中的 "2015-01-01T00:00:00+0900" 也可以是日期时间格式,例如 Timestamp('2017-08-30 20:36:25')。
归档时间: |
|
查看次数: |
27397 次 |
最近记录: |