Сравните 2 временных диапазона, чтобы увидеть, есть ли конвергенция

Я собираю небольшую систему бронирования, где отображаются временные интервалы (каждые 30 минут).

Я хочу иметь возможность отмечать, когда в этот временной интервал попадает бронирование.

Итак, у меня есть DateTime ОТ и DateTime ДО для временного интервала.

Затем у меня есть бронирования DateTime ОТ и DateTime ТО для временного интервала.

Я не могу понять, как отметить временной интервал, что существует бронирование, которое (по крайней мере частично) занимает этот временной интервал.

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

Вероятно, есть лучший способ сделать это. Есть какие-нибудь указатели?

var checkbookings = bookings
   .Where(i => i.StartTime.TimeOfDay >= timeslot.StartTime.TimeOfDay)
   .Where(i => i.EndTime.TimeOfDay <= timeslot.EndTime.TimeOfDay)
   .FirstOrDefault();

Объект бронирования уже был пронумерован из базы данных с помощью ToList().

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

Maximilian Burszley 17.05.2024 15:00

Во-первых, вам не нужны два предложения Where, вы можете использовать одно с &&. More importantly though, calling TimeOnly` генерирует операцию преобразования, которая предотвращает использование любых индексов для StartTime и EndTime. Если вам важно время, используйте тип time в базе данных и TimeOnly в C#.

Panagiotis Kanavos 17.05.2024 15:01

Могут ли timeslot.StartTime и timeslot.EndTime находиться в разные дни?

Tim Schmelter 17.05.2024 15:03

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

Matthew Warr 17.05.2024 15:03

@MaximilianBurszley тип на стороне клиента не влияет на запрос. Однако тип базы данных имеет значение. Этот запрос LINQ генерирует cast(starttime as time)>=@t1, который предотвращает использование индексов.

Panagiotis Kanavos 17.05.2024 15:03

@TimSchmelter нет, будет в тот же день

Matthew Warr 17.05.2024 15:04

LINQ — это функция итераторов, а не баз данных @PanagiotisKanavos

Maximilian Burszley 17.05.2024 15:05

@PanagiotisKanavos Хорошо, если я сохраняю время только в специальном столбце базы данных для бронирования и использую TimeOnly в C# для временного интервала, как мне проверить совпадение?

Matthew Warr 17.05.2024 15:05

@MaximilianBurszley и EF Core, как и этот вопрос

Panagiotis Kanavos 17.05.2024 15:06

@MaximilianBurszley, спасибо, как мне сравнить два временных интервала, чтобы получить одинаковый результат?

Matthew Warr 17.05.2024 15:06

Вы должны построить временной интервал для временного интервала и проверить, содержится ли в нем начало/конец резервирования.

Maximilian Burszley 17.05.2024 15:07

@PanagiotisKanavos Вы делаете вывод о том, чего нет. Этот вопрос помечен только тегом С# и спрашивает только о сравнении дат и времени.

Maximilian Burszley 17.05.2024 15:07

@MaximilianBurszley, но TimeSpan - это просто время, верно? Итак, если бы временной интервал был с 15:30 до 16:00, как бы я выразил это как TimeSpan?

Matthew Warr 17.05.2024 15:11

@MaximilianBurszley нет, за эти годы я просто написал довольно много временных запросов до такой степени, что инстинктивно помню упрощенное условие. Вы говорите о timespan, как если бы это был период (в терминах временной БД). В C# TimeSpan — это продолжительность, и здесь он вообще не может помочь.

Panagiotis Kanavos 17.05.2024 15:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
14
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Логическое условие после небольшого логического упрощения и предположения, что поля равны time и TimeOnly:

.Where(i => timeslot.StartTime <= i.EndTime &&
            timeslot.EndTime   >= i.StartTime)

То, что вы спрашиваете, эквивалентно вопросу, перекрываются ли два линейных сегмента. Если вы нарисуете два временных отрезка на линии, они будут выглядеть так:

T-Start      T-End
|-------------|

    I-Start             I-End
       |------------------|

Независимо от того, какой сегмент первый или последний, начало одного из них предшествует концу другого.

Обновлять

Это условие обрабатывает заданное перекрытие. Если T-End и I-Start логически одинаковы, они все равно перекрываются. Однако в системе бронирования мы бы не сочли это совпадением. Хотя одним из вариантов является обеспечение того, чтобы время окончания было «непосредственно перед» фактическим завершением, более чистым решением было бы использовать <

.Where(i => timeslot.StartTime < i.EndTime &&
            timeslot.EndTime   > i.StartTime)
T-Start      T-End
|-------------|

           I-Start             I-End
              |------------------|

Часто мы включаем StartTime, но исключаем EndTime, в этом случае >= и <= следует заменить на > и <.

Dmitry Bychenko 17.05.2024 15:13

Вопрос в перекрытии. Если I-Start и T-End одинаковы, сегменты логически все равно перекрываются. Но да, возможно, это не то, что намеревается ФП.

Panagiotis Kanavos 17.05.2024 15:17

@DmitryByченко немного странно, что я вспомнил упрощенное условие раньше, чем вспомнил, почему оно работает.

Panagiotis Kanavos 17.05.2024 15:24

@PanagiotisKanavos Это было превосходно. Спасибо. Мне пришлось провести небольшой рефакторинг, и поскольку в .NET 7 (еще не переведенной на 8) пришлось добавить преобразователь типов данных, но теперь он дает желаемый эффект. Спасибо!

Matthew Warr 17.05.2024 16:42

@MatthewWarr в .NET 7 и более ранних версиях вы можете использовать TimeSpan вместо TimeOnly.

Panagiotis Kanavos 20.05.2024 09:30

Другие вопросы по теме