Я пытаюсь сравнить даты в массиве для перекрытия, но с проблемой. Пользователь может добавить столько дат, сколько захочет, и мне нужно проверить их, чтобы они не перекрывались.
Даты Массив (даты начала и окончания в сочетании с (-) между ними:
dates (4) ["02/07/2018-02/07/2018", "02/05/2018-02/07/2018", "02/06/2018-02/06/2018", "02/08/2018-02/08/2018"]
Мой код:
function CheckOverlappingDates(dates) {
var startDate = [];
var endDate = [];
var isOverlap;
for (var i = 0; i < dates.length; i++) {
var split = dates[i].split('-'); // just split once
startDate.push(new Date(split[0]).toLocaleDateString());
endDate.push(new Date(split[1]).toLocaleDateString());
for (var x = 0; x < startDate.length; x++) {
if (startDate[x] >= startDate[x + 1] && startDate[x + 1] <= endDate[x + 1]) {
isOverlap = true;
} else {
isOverlap = false;
}
}
}
}
Я разделил их на начало и закончил, как показано ниже.
но моя функция не сравнивает несколько диапазонов дат.
При сравнении строк даты вы можете преобразовать их в объекты Date или сохранить их как строки и использовать localeCompare. Не используйте встроенный анализатор даты, поскольку он ненадежен. Функция 2 строки может форматировать как строки или преобразование на дату, строки могут быть более эффективными, но сравнение в качестве дат меньше кода.
Чтобы увидеть, имеет ли массив диапазонов перекрытие, каждый диапазон нужно сравнивать с теми, которые находятся после него в массиве. Там нет необходимости проверять с ними раньше, чем это уже было сделано.
Неясно, что делать с перекрывающимися диапазонами, поэтому эта функция просто возвращает массив строк с "диапазоном A перекрытий диапазона B". Он также предполагает, что диапазоны включены, поэтому 02/05/2018-02/07/2018 перекрывается 02/07/2018-02/08/2018.
например
var dates = ["02/07/2018-02/07/2018", "02/05/2018-02/07/2018", "02/06/2018-02/06/2018", "02/08/2018-02/08/2018"];
// Assume array of ranges in format mm/dd/yyyy-mm/dd/yyyy
// Return array of overlapping ranges
function inRange(dates) {
// Parse date string to Date
function fn(s) {
var b = s.split(/\D/);
return new Date(b[2], b[0]-1, b[1]);
}
// Return true if range a overlaps range b
// where range is string in format mm/dd/yyyy-mm/dd/yyyy
// Overlaps if start or end of b are inside a, or
// a is wholly inside b
function overlaps(a, b) {
a = a.split('-').map(fn);
b = b.split('-').map(fn);
return (b[0] >= a[0] && b[0] <= a[1]) || // b start in a
(b[1] >= a[0] && b[1] <= a[1]) || // b end in a
(b[0] <= a[0] && b[1] >= a[1]); // b encloses a
}
// Array for overlapping ranges
var overlappers = [];
var max = dates.length - 1;
dates.forEach(function(date, i) {
// Don't test last as already tested
if (i < max) {
// Only test from this element to end of array
for (var j = i+1; j <= max; j++) {
// If overlaps, add to overlappers array
if (overlaps(date, dates[j])) {
overlappers.push(date + ' overlaps ' + dates[j]);
}
}
}
});
return overlappers;
}
console.log(inRange(dates));
Простой парсер ожидает, что даты будут действительны. Если они должны быть проверены, в синтаксическом анализаторе требуется дополнительная строка кода, а в основной функции должны быть указаны недействительные даты.
Вы можете использовать for
цикла, чтобы проверить.
var dates = ["02/07/2018-02/07/2018", "02/05/2018-02/07/2018", "02/06/2018-02/06/2018", "02/08/2018-02/08/2018"];
var overlaps = checkOverlaps(dates);
console.log("overlaps", overlaps);
var dates1 = ["02/07/2018-02/07/2018", "02/08/2018-02/10/2018", "02/19/2018-02/20/2018", "02/21/2018-02/21/2018"];
var nonoverlaps = checkOverlaps(dates1);
console.log("nonoverlaps", nonoverlaps);
var dates2 = ["02/07/2018-02/07/2018", "02/07/2018-02/10/2018"]; /* 2nd range starts on the end of the first range */
var overlaps2 = checkOverlaps(dates2);
console.log("overlaps", overlaps2);
function checkOverlaps(dates) {
var o = false;
for (var key1 in dates) {
var cDateArr = dates[key1].split("-");
var d1 = new Date(cDateArr[0]);
var d2 = new Date(cDateArr[1]);
for (var key2 in dates) {
//make sure not comparing to own self
if (key1 != key2) {
var cDateArrB = dates[key2].split("-");
var dB1 = new Date(cDateArrB[0]);
var dB2 = new Date(cDateArrB[1]);
if (
(d1 < dB1 && d2 > dB1) ||
(d1 < dB2 && d2 > dB2) ||
cDateArr[0] == cDateArrB[0] ||
cDateArr[0] == cDateArrB[1] ||
cDateArr[1] == cDateArrB[0] ||
cDateArr[1] == cDateArrB[1]
) {
o = true;
}
}
}
}
return o;
}
new Date(split[0]).toLocaleDateString()
последующим сравнением результирующих строк с использованиемstartDate[x] >= startDate[x + 1]
- не очень хорошая идея. Разбор исходной строки зависит от реализации, так как является результатом toLocaleString , нет никаких оснований полагать, что результаты будут правильными или надежными, и многие считают, что они этого не сделают.