Я ищу расширенный ответ на вопрос, который задают здесь:
Определите, накладываются ли два диапазона даты
где любая из дат в любом диапазоне дат может быть пустой. Я предложил следующее решение, но я не уверен, может ли оно быть упрощено далее.
(StartA == NULL || StartA <= EndB) &&
(EndA == NULL || EndA >= StartB) &&
(StartB == NULL || StartB <= EndA) &&
(EndB == NULL || EndB >= StartA)
Принятие:
Диапазоны DateTime StartA к EndA и StartB к EndB
Править: Извините я быстро бросил вышеупомянутую логику вместе, которая, кажется, перестала работать, когда запуск любого диапазона и даты окончания является ПУСТЫМ. Посмотрите решение David ниже для лучшего и хорошо объясненного подхода.
С этим случаем можно справиться с помощью небольшого обобщения отличного ответа Чарльза Бретана на этот вопрос.
Пусть 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
. В большинстве языков, с которыми я знаком, это условие является ошибкой.
Это, вероятно, настолько "просто", насколько это возможно, хотя я не доказал этого.
Возможно, не стоит упрощать дальше, поскольку этот блок в худшем случае делает около 8 операций (в среднем 4 благодаря оценке короткого замыкания).
Все ответы основаны на том, что условие истинно. Я хотел бы добавить здесь несколько замечаний.
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;
}
}