Перекрытие диапазона дат с датами Nullable

Я ищу расширенный ответ на вопрос, который задают здесь:

Определите, накладываются ли два диапазона даты

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

(StartA == NULL || StartA <= EndB) &&
(EndA == NULL || EndA >= StartB) &&
(StartB == NULL || StartB <= EndA) &&
(EndB == NULL || EndB >= StartA)

Принятие:

Диапазоны DateTime StartA к EndA и StartB к EndB

Править: Извините я быстро бросил вышеупомянутую логику вместе, которая, кажется, перестала работать, когда запуск любого диапазона и даты окончания является ПУСТЫМ. Посмотрите решение David ниже для лучшего и хорошо объясненного подхода.

5
задан Community 23 May 2017 в 12:25
поделиться

3 ответа

С этим случаем можно справиться с помощью небольшого обобщения отличного ответа Чарльза Бретана на этот вопрос.

Пусть CondA Mean DateRange A полностью после DateRange B (True if StartA > EndB) Let CondB Mean DateRange A Completely Before DateRange B (True if EndA < StartB)

В этом случае, если вы хотите, чтобы нулевая дата представляла "отсутствие начальной/конечной границы", условия изменяются. Для CondA, например, чтобы диапазон дат A был полностью после диапазона дат B, диапазон дат A должен иметь определенное время начала, диапазон дат B должен иметь определенное время окончания, и время начала A должно быть после времени окончания B:

CondA := (StartA != null) && (EndB != null) && (StartA > EndB)

CondB - то же самое, только A и B поменяны местами:

CondB := (StartB != null) && (EndA != null) && (StartB > EndA)

Продолжаем,

Тогда перекрытие существует, если ни A, ни B не истинны

Overlap := !(CondA || CondB)

и

Теперь закон деМоргана, я думаю, говорит, что

Not (A Or B) <=> Not A And Not B

Overlap == !CondA && !CondB
        == ![(StartA != null) && (EndB != null) && (StartA > EndB)] &&
           ![(StartB != null) && (EndA != null) && (StartB > EndA)]
        == [(StartA == null) || (EndB == null) || (StartA <= EndB)] &&
           [(StartB == null) || (EndA == null) || (StartB <= EndA)]

Я думаю, что это на самом деле немного более надежно, чем решение, которое вы разработали, потому что если EndB == NULL, но StartA не является нулевым, ваше первое условие будет сравнивать StartA <= NULL. В большинстве языков, с которыми я знаком, это условие является ошибкой.

12
ответ дан 18 December 2019 в 16:35
поделиться

Это, вероятно, настолько "просто", насколько это возможно, хотя я не доказал этого.

Возможно, не стоит упрощать дальше, поскольку этот блок в худшем случае делает около 8 операций (в среднем 4 благодаря оценке короткого замыкания).

0
ответ дан 18 December 2019 в 16:35
поделиться

Все ответы основаны на том, что условие истинно. Я хотел бы добавить здесь несколько замечаний.

1- Тип переменной DateTime является структурой, и вы не можете установить его в null, если только вы не используете nullable тип, такой как "DateTime?".

2- Чтобы найти диапазон перекрытия, выполните следующие действия

DateTime? StartOverLap = null,EndOverLap = null;
            if (StartA != null && StartB != null)
            {
                StartOverLap = StartA > StartB ? StartA : StartB;
            }
            else if (StartA == null && StartB != null)
            {
                StartOverLap = StartB;
            }
            else if (StartA != null && StartB == null)
            {
                StartOverLap = StartA;
            }
            if (EndA != null && EndB != null)
            {
                EndOverLap = EndA < EndB ? EndA : EndB;
            }
            else if (EndA == null && EndB != null)
            {
                EndOverLap = EndB;
            }
            else if (EndA != null && EndB == null)
            {
                EndOverLap = EndA;
            }
            if (StartOverLap != null && EndOverLap == null)
            {
                if (EndOverLap < StartOverLap)
                {
                    StartOverLap = null;
                    EndOverLap = null;
                }
            }
-1
ответ дан 18 December 2019 в 16:35
поделиться
Другие вопросы по тегам:

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