временное перекрытие диапазона между начальным и конечным временем [дубликат]

попробуйте с помощью

  & lt; aim-filter android: priority = "0" & ​​gt;  & lt; действие android: name = "android.intent.action.VIEW" / & gt;  & lt; category android: name = "android.intent.category.DEFAULT" / & gt;  & lt; категория android: name = "android.intent.category.BROWSABLE" / & gt;  & lt; data android: scheme = "geo" / & gt;  & Lt; / Намерение фильтр & GT;   
50
задан Oz123 26 August 2013 в 10:45
поделиться

5 ответов

  • Определите последнюю из двух дат начала и самой ранней из двух дат окончания.
  • Вычислите timedelta, вычитая их.
  • Если дельта положительна, это число дней перекрытия.

Вот пример расчета:

>>> 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
115
ответ дан Raymond Hettinger 15 August 2018 в 22:19
поделиться
  • 1
    Отличный ответ – Andreas Jung 28 January 2012 в 12:15
  • 2
    +1 для создания Range с именем кортеж. :-) – GaretJax 28 January 2012 в 12:15
  • 3
    +1 для элегантного кода. Я просто взял эту процедуру и использовал ее в своем приложении PHP. – Eric 28 February 2012 в 03:07
  • 4
    +1 очень приятное решение. Хотя, это не совсем работает на даты, которые полностью содержатся в другом. Для простоты в целых числах: Range (1,4) и Range (2,3) возвращает 1 – darkless 3 September 2013 в 06:19
  • 5
    @darkless Фактически, он возвращает 2, который правильный . Попробуйте эти входы r1 = Range(start=datetime(2012, 1, 1), end=datetime(2012, 1, 4)); r2 = Range(start=datetime(2012, 1, 2), end=datetime(2012, 1, 3)). Я думаю, вы пропустили +1 в вычислении перекрытия (необходимо, потому что интервал закрыт на обоих концах). – Raymond Hettinger 19 January 2015 в 21:31

Я реализовал класс TimeRange, как вы можете видеть ниже.

Сначала get_overlapped_range отрицает все неперекрывающиеся параметры простым условием, а затем вычисляет перекрываемый диапазон, рассматривая все возможные варианты.

, чтобы получить количество дней, которое вам потребуется, чтобы принять значение TimeRange, которое было возвращено из get_overlapped_range, и делить продолжительность на 60 * 60 * 24 (:

класс TimeRange (объект):

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]])
0
ответ дан Elad Sofer 15 August 2018 в 22:19
поделиться
  • 1
    Уже существует идеальное решение проблемы OP. – L. Guthardt 15 January 2018 в 15:52
  • 2
    @ L.Guthardt Согласовано, но это решение организовано и поставляется с большей функциональностью – Elad Sofer 17 April 2018 в 23:31
  • 3
    Хорошо ... это здорово, тем больше функциональности, но на самом деле на StackOverflow ответ должен соответствовать только определенным потребностям OP. Так что не больше и не меньше. :) – L. Guthardt 18 April 2018 в 06:18
def get_overlap(r1,r2):
    latest_start=max(r1[0],r2[0])
    earliest_end=min(r1[1],r2[1])
    delta=(earliest_end-latest_start).days
    if delta>0:
        return delta+1
    else:
        return 0
0
ответ дан grael 15 August 2018 в 22:19
поделиться

Вызов функций дороже, чем арифметические операции.

Самый быстрый способ сделать это включает в себя 2 вычитания и 1 мин ():

min(r1.end - r2.start, r2.end - r1.start).days + 1

по сравнению со следующим лучшим, что требуется 1 вычитание, 1 мин () и max ():

(min(r1.end, r2.end) - max(r1.start, r2.start)).days + 1

Конечно, с обоими выражениями вам все равно нужно проверить положительное перекрытие.

6
ответ дан John Machin 15 August 2018 в 22:19
поделиться
  • 1
    Этот метод не вернет правильный ответ. например Range = namedtuple('Range', ['start', 'end']) r1 = Range(start=datetime(2016, 6, 15), end=datetime(2016, 6, 15)) r2 = Range(start=datetime(2016, 6, 11), end=datetime(2016, 6, 18)) print min(r1.end - r2.start, r2.end - r1.start).days + 1 будет печатать 4, где предполагается напечатать 1 – tkyass 16 June 2016 в 16:52

Псевдокод:

 1 + max( -1, min( a.dateEnd, b.dateEnd) - max( a.dateStart, b.dateStart) )
3
ответ дан ypercubeᵀᴹ 15 August 2018 в 22:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: