Функции для интервалов значений

В настоящее время я имею дело со многими, возможно, неопределенными диапазонами дат, т.е.

StartDate     EndDate
---------     ---------
01JAN1921     31DEC2009
10OCT1955     null
...

где другой конец интервала может быть неизвестен или не определен. Я работал над небольшими функциями для обнаружения перекрытия, определения того, является ли интервал подинтервалом другого, вычисления разрыва между двумя интервалами и т. д.

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

        S       E            S and E are the start and end of the interval
        |       |            we're comparing to. Here both are known, but
s1------+---e1  |            either could be null. The small s:s and e:s 
        |       |  s2....e2  define the intervals we're comparing to and
        |s3--e3 |            again we'd like to allow for open intervals.
        |   s4--+----e4
  s5..e5|       |
    s6--+-------+--s7
        |       |

На основе вопросов, связанных с обнаружением перекрытия с четко определенными интервалами, вам необходимо проверить

    Coalesce(S,Coalesce(e-1,0))<Coalesce(e,Coalesce(S+1,1))
AND Coalesce(E,Coalesce(s+1,0))>Coalesce(s,Coalesce(E-1,1))

Я полагаю, что это настолько распространенная вещь (относительно не только дат или временных интервалов), что многие люди сталкивались с этим. Я ищу существующие реализации, предпочтительно просто функции, основанные на базовых операциях сравнения.


person Ville Koskinen    schedule 28.01.2010    source источник


Ответы (2)


Интервальная арифметика — обширная и сложная тема. В C++/Boost есть библиотека. для работы с ним. Python и, думаю, многие другие языки. Это то, о чем вы спрашиваете, или это слишком общее?

Что касается временных интервалов, есть этот SO вопрос и, возможно, другие, которые вы можете найти в «Похожая» боковая панель.

person Eli Bendersky    schedule 28.01.2010
comment
Спасибо, +1 за ссылки. Мне нужно посмотреть, поддерживает ли библиотека Boost такие интервалы, как [1, бесконечность). - person Ville Koskinen; 29.01.2010

Есть три распространенных способа представления дат в программах.

  • В григорианском календаре с годами, месяцами, днями, часами, минутами, секундами. Он очень надежен, но с ним трудно проводить математические расчеты (високосный год каждый четвертый год, но не в веках, если только год не кратен 400... вы помните это?)
  • Как количество секунд с определенного времени, хотя это создает проблемы, поскольку вам нужно выбрать, считать ли дополнительные секунды (поищите «високосные секунды» в Интернете, и вы поймете, почему)
  • В юлианском календаре - количество дней, прошедших с определенной даты, и количество секунд, прошедших с начала этого дня.

Что касается реализаций для использования в качестве эталона,

  • Java — пример того, чего делать не следует (люди, не создавайте изменяемые типы даты и времени)
  • Python также беспорядок (нет простого способа разобрать даты)
  • PostgreSQL очень хорошо работает с датами и временем. См. http://www.postgresql.org/docs/7.4/interactive/datatype-datetime.html, а также вы можете просмотреть исходный код. Внутри используется юлианский календарь.
  • Стандартная библиотека времени Haskell также хороша и имеет неограниченный диапазон и точность — это верно, они используют bigints для даты по юлианскому календарю и соотношение bigints для времени. Библиотека включает в себя множество полезных функций даты, в том числе одну для расчета даты, на которую приходится Пасха. См. http://hackage.haskell.org/package/time.
person Dietrich Epp    schedule 28.01.2010