Я создал плагин, который может генерировать эффект предварительного просмотра в IE 7+ благодаря интернету, но имеет мало ограничений. Я помещал его в github page , чтобы его было легче получить
$(function () {
$("input[name=file1]").previewimage({
div: ".preview",
imgwidth: 180,
imgheight: 120
});
$("input[name=file2]").previewimage({
div: ".preview2",
imgwidth: 90,
imgheight: 90
});
});
.preview > div {
display: inline-block;
text-align:center;
}
.preview2 > div {
display: inline-block;
text-align:center;
}
Preview
Preview2
(StartA < = EndB) и (EndA> = StartB)
Доказательство:
ConditionA, которому Позволяют, Средний, что DateRange Полностью После DateRange B
_ |---- DateRange A ------|
|---Date Range B -----| _
(Верный, если StartA > EndB
)
ConditionB, которому Позволяют, Средний, что DateRange A Полностью Перед DateRange B
|---- DateRange A -----| _
_ |---Date Range B ----|
(Верный, если EndA < StartB
)
Тогда, Перекрытие существует, если Ни A, Ни B не верны -
(Если один диапазон ни полностью после другого,
, ни полностью перед другим, то они должны наложиться.)
Теперь один из [1 127] законы De Morgan говорит что:
Not (A Or B)
< => Not A And Not B
, Который переводит в: (StartA <= EndB) and (EndA >= StartB)
ПРИМЕЧАНИЕ: Это включает условия, где края накладываются точно. Если Вы хотите исключить, это,
изменяется эти >=
операторы к >
, и <=
к [1 110]
NOTE2. Благодаря @Baodad см. этот блог , фактическое перекрытие является наименьшим количеством:
{endA-startA
, endA - startB
, endB-startA
, endB - startB
}
(StartA <= EndB) and (EndA >= StartB)
(StartA <= EndB) and (StartB <= EndA)
NOTE3. Благодаря @tomosius читает более короткая версия:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
Это - на самом деле синтаксический ярлык для того, что является более длительной реализацией, которая включает дополнительные проверки, чтобы проверить, что даты начала идут или перед endDates. Получение этого сверху:
, Если запускаются и даты окончания не могут работать, т.е. если возможно, что startA > endA
или startB > endB
, тогда также необходимо проверить, что они в порядке, так, чтобы средства Вы добавили два дополнительных правила законности:
(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)
или:
(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)
или,
(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))
или:
(Max(StartA, StartB) <= Min(EndA, EndB)
, Но реализовать Min()
и Max()
, необходимо кодировать, (использующий C троичный для краткости):
(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)
Я полагаю, что достаточно сказать, что два диапазона накладываются если:
(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)
Для обоснования о временных отношениях (или любых других отношениях интервала, приезжайте в тот), рассмотрите Интервальная алгебра Allen . Это описывает 13 возможных отношений, которые два интервала могут иметь друг относительно друга. Можно найти, что другие ссылки — "Интервал Allen", кажется, действующий критерий поиска. Можно также найти информацию об этих операциях в Snodgrass Разрабатывающие Ориентированные на время Приложения в SQL (PDF доступный онлайн в URL), и на Дате, Дарвене и Lorentzos Временные Данные и Реляционная модель (2002) или Время и Реляционная Теория: Временные Базы данных в Реляционной модели и SQL (2014; эффективно второй выпуск TD& RM).
<час> короткое (выход) ответ: учитывая два интервала даты A
и B
с компонентами .start
и .end
и ограничение .start <= .end
, тогда два интервала накладываются если:
A.end >= B.start AND A.start <= B.end
можно настроить использование >=
по сравнению с >
и <=
по сравнению с [1 110] для соответствия требованиям для степени перекрытия.
комментарии ErikE:
можно только добраться 13 при подсчете вещей забавными... Я могу получить "15 возможных отношений, которые могут иметь два интервала", когда я схожу с ума с ним. Разумным подсчетом я получаю только шесть, и если Вы выводите заботу или A, или B на первом месте, я добираюсь, только три (не пересекаются, частично пересекаются, один полностью в другом). 15 идет как это: [before:before, запустите, в, конец, после], [start:start, в, конец, после], [within:within, конец, после], [end:end, после], [after:after].
я думаю, что Вы не можете считать эти две записи 'before:before' и 'after:after'. Я видел 7 записей, если Вы приравниваете некоторые отношения с их инверсиями (см. схему в URL Википедии, на который ссылаются; это имеет 7 записей, 6 из которых имеют различную инверсию, с, равняется не наличию отличной инверсии). И ли три разумно, зависит от Ваших требований.
----------------------|-------A-------|----------------------
|----B1----|
|----B2----|
|----B3----|
|----------B4----------|
|----------------B5----------------|
|----B6----|
----------------------|-------A-------|----------------------
|------B7-------|
|----------B8-----------|
|----B9----|
|----B10-----|
|--------B11--------|
|----B12----|
|----B13----|
----------------------|-------A-------|----------------------
Я сделал бы
StartDate1.IsBetween(StartDate2, EndDate2) || EndDate1.IsBetween(StartDate2, EndDate2)
, Где IsBetween
что-то как
public static bool IsBetween(this DateTime value, DateTime left, DateTime right) {
return (value > left && value < right) || (value < left && value > right);
}
Самый легкий способ сделать это, по-моему, состоял бы в том, чтобы выдержать сравнение, если любой, который EndDate1 перед StartDate2 и EndDate2, перед StartDate1.
, Что, конечно, если Вы рассматриваете интервалы, где StartDate всегда перед EndDate.
Вот универсальный метод, который может быть полезен локально.
// Takes a list and returns all records that have overlapping time ranges.
public static IEnumerable<T> GetOverlappedTimes<T>(IEnumerable<T> list, Func<T, bool> filter, Func<T,DateTime> start, Func<T, DateTime> end)
{
// Selects all records that match filter() on left side and returns all records on right side that overlap.
var overlap = from t1 in list
where filter(t1)
from t2 in list
where !object.Equals(t1, t2) // Don't match the same record on right side.
let in1 = start(t1)
let out1 = end(t1)
let in2 = start(t2)
let out2 = end(t2)
where in1 <= out2 && out1 >= in2
let totover = GetMins(in1, out1, in2, out2)
select t2;
return overlap;
}
public static void TestOverlap()
{
var tl1 = new TempTimeEntry() { ID = 1, Name = "Bill", In = "1/1/08 1:00pm".ToDate(), Out = "1/1/08 4:00pm".ToDate() };
var tl2 = new TempTimeEntry() { ID = 2, Name = "John", In = "1/1/08 5:00pm".ToDate(), Out = "1/1/08 6:00pm".ToDate() };
var tl3 = new TempTimeEntry() { ID = 3, Name = "Lisa", In = "1/1/08 7:00pm".ToDate(), Out = "1/1/08 9:00pm".ToDate() };
var tl4 = new TempTimeEntry() { ID = 4, Name = "Joe", In = "1/1/08 3:00pm".ToDate(), Out = "1/1/08 8:00pm".ToDate() };
var tl5 = new TempTimeEntry() { ID = 1, Name = "Bill", In = "1/1/08 8:01pm".ToDate(), Out = "1/1/08 8:00pm".ToDate() };
var list = new List<TempTimeEntry>() { tl1, tl2, tl3, tl4, tl5 };
var overlap = GetOverlappedTimes(list, (TempTimeEntry t1)=>t1.ID==1, (TempTimeEntry tIn) => tIn.In, (TempTimeEntry tOut) => tOut.Out);
Console.WriteLine("\nRecords overlap:");
foreach (var tl in overlap)
Console.WriteLine("Name:{0} T1In:{1} T1Out:{2}", tl.Name, tl.In, tl.Out);
Console.WriteLine("Done");
/* Output:
Records overlap:
Name:Joe T1In:1/1/2008 3:00:00 PM T1Out:1/1/2008 8:00:00 PM
Name:Lisa T1In:1/1/2008 7:00:00 PM T1Out:1/1/2008 9:00:00 PM
Done
*/
}
Все решения, которые проверяют множество условий в зависимости от того, где находятся диапазоны по отношению друг к другу, можно значительно упростить, просто убедившись, что конкретный диапазон начинается раньше! Вы гарантируете, что первый диапазон начинается раньше (или в то же время), поменяв диапазоны, если необходимо, впереди.
Затем вы можете обнаружить перекрытие, если начало другого диапазона меньше или равно первому концу диапазона (если диапазоны включены, содержат время начала и окончания) или меньше (если диапазоны включают начало и исключающее конца).
Предполагая включение на обоих концах, есть только четыре возможности, одна из которых является неперекрывающейся:
|----------------------| range 1
|---> range 2 overlap
|---> range 2 overlap
|---> range 2 overlap
|---> range 2 no overlap
Конечная точка диапазона 2 не входит в него. Итак, в псевдокоде:
def doesOverlap (r1, r2):
if r1.s > r2.s:
swap r1, r2
if r2.s > r1.e:
return false
return true
Это можно упростить еще больше:
def doesOverlap (r1, r2):
if r1.s > r2.s:
swap r1, r2
return r2.s <= r1.e
Если диапазоны включают в себя в начале и исключают в конце, вам просто нужно заменить >
на ]> =
во втором операторе if
(для первого сегмента кода: во втором сегменте кода вы должны использовать <
, а не <=
]):
|----------------------| range 1
|---> range 2 overlap
|---> range 2 overlap
|---> range 2 no overlap
|---> range 2 no overlap
Вы значительно ограничиваете количество проверок, которые вам нужно выполнить, потому что вы удаляете половину проблемного пространства раньше, гарантируя, что диапазон 1 никогда не начинается после диапазона 2.