2017-01-17 1 views
0
20.01.2017 
23.01.2017 
24.01.2017 
25.01.2017 
26.01.2017 
27.01.2017 
31.01.2017 
01.02.2017 

Допустим, у меня есть эти даты. Все эти даты - рабочие дни. Вывод должен бытьКак группировать массив дат в периоды startdate-enddate? Если один день недели отсутствует между датами, новый период начинается с Javascript

20.01.2017-27.01.2017 
and 
31.01.2017-01.02.2017 

С 30 января в рабочий день и поэтому первый период не continiuing и начинается новый период.

Каков наилучший способ приблизиться к этому.

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

+1

Ключ к решению: [Date.parse()] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) Вы можете получить дату в миллисекундах и сортировать – Smiranin

+0

Это не имеет никакого смысла. Как это поможет с моей проблемой? –

+0

[Date.getDay()] (http://www.w3schools.com/jsref/jsref_getday.asp) возвращает вам день недели для заданной даты. Может быть, это может помочь вам ... –

ответ

0

Получите свое первое свидание (я уверяю вас, что вы их заказали, как в ваших данных примера) и сохраните его на переменной для даты начала.

Сохраните то же значение и в другой переменной для даты окончания.

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

0

Это был бы мой подход, хотя и не самый короткий или, возможно, лучший способ справиться с этим. Просто это как идея

var array = [ 
    "20.01.2017", 
    "23.01.2017", 
    "24.01.2017", 
    "25.01.2017", 
    "26.01.2017", 
    "27.01.2017", 
    "31.01.2017", 
    "01.02.2017" 
]; 

var isNextDay = function(day, nextDay) { 
    var day1 = new Date(day.slice(3, 6) + day.slice(0, 3) + day.slice(6)); //had to format the date this way to make a valid date 
    day1.setDate(day1.getDate() + 1); //sets the next day, nextday of 30 or 31(last day of month) is 1 
    var day2 = new Date(nextDay.slice(3, 6) + nextDay.slice(0, 3) + nextDay.slice(6)); 
    if (day1.getTime() === day2.getTime()) { 
     return true; 
    } else { 
     return false; 
    } 
} 

var dateGroup = function(dateStrings) { 
    var res = []; 
    var aux = dateStrings[0] + "-"; 
    for (var i = 1; i < dateStrings.length; i++) { 
     if (!isNextDay(dateStrings[i - 1], dateStrings[i])) { 
      aux += dateStrings[i - 1]; 
      res.push(aux); 
      aux = dateStrings[i] + "-"; 
     } 
    } 
    aux += dateStrings[dateStrings.length - 1]; 
    res.push(aux); //this is because the last one never gets pushed 
    return res; 
} 

var output = dateGroup(array); 
+0

Вы не можете полагаться на 'new Date (nextDay.slice (3, 6) + nextDay.slice (0, 3) + nextDay.slice (6))'. Разбор случайных строк с конструктором Date (и Date.parse), как известно, непоследователен во всех реализациях. – RobG

+0

, конечно же, это реализация, которая строго нуждается в двух вещах, форматах даты и том, что нужно отсортировать, я просто должен был ее использовать, потому что мои узлы будут понимать mm.dd.yyyy с этим форматом даты – Leandro

+0

Не уверен, что «* бы *» должно быть «* не будет *». Но в любом случае подчеркивается, что вы не должны использовать конструктор * Date * или * Date.parse * для синтаксического анализа.После того, как вы проанализировали строку в токенах, вам гораздо лучше использовать эти значения непосредственно с конструктором, чем создавать новую строку и возвращаться к «новой дате (строке)» или эквиваленту * Date.parse *. – RobG

0

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

Вы можете использовать библиотеку для разбора и форматирования дат, но простые функции для выполнения задания - это всего лишь несколько строк, например.

var dates = ['20.01.2017','23.01.2017','24.01.2017', 
 
      '25.01.2017','26.01.2017','27.01.2017', 
 
      '31.01.2017','01.02.2017']; 
 

 
/* Parse date in format D/M/YYYY 
 
** @param {string} s - date to parse lke 23.1.2017 
 
** @returns {Date} 
 
*/ 
 
function parseDMY(s) { 
 
    var b = s.split(/\D/); 
 
    return new Date(b[2], b[1]-1, b[0]); 
 
} 
 

 
/* Format a date in DD/MM/YYYY with supplied separator 
 
** @param {Date} date - date to format 
 
** @param {string} s - separator, default is/
 
** @returns {string} date formatted as DD/MM/YYYY with supplied separator 
 
*/ 
 
function formatDMY(date, s) { 
 
    s = s || '/'; 
 
    function z(n){return (n<10?'0':'')+n} 
 
    return [z(date.getDate()),z(date.getMonth()+1), 
 
      date.getFullYear()].join(s); 
 
} 
 

 
/* Create array of date ranges in DD.MM.YYYY-DD.MM.YYYY format 
 
** @param {Array} data - array of date strings in DD.MM.YYYY format 
 
** @returns {Array} array of range strings in DD.MM.YYYY-DD.MM.YYYY format 
 
*/ 
 
function createRanges(data) { 
 
    var result = []; 
 
    var previous; 
 
    data.forEach(function(s, i) { 
 
    var previous, previousNext, current, range; 
 
    // If on first loop, create a range using first value 
 
    if (i == 0) { 
 
     result.push(s + '-' + s); 
 
     
 
    // Otherwise, get end date of last range and add one day 
 
    } else { 
 
     previous = result[result.length-1].split('-')[1]; 
 
     previousNext = parseDMY(previous); 
 
     previousNext.setDate(previousNext.getDate() + 1); 
 
     previousNext = formatDMY(previousNext,'.'); 
 
     
 
     // If current date is same as previousNext, update range. 
 
     // Otherwise, start a new range 
 
     if (s == previousNext) { 
 
     range = result[result.length-1]; 
 
     result[result.length-1] = range.split('-')[0] + '-' + s; 
 

 
     } else { 
 
     result.push(s + '-' + s); 
 
     } 
 
    } 
 
    }); 
 
    // Remove zero day ranges. Could do this by checking last range 
 
    // when creating a new one but seems simpler to do it here 
 
    result = result.filter(s=>!(s.split('-')[0] == s.split('-')[1])); 
 
    return result; 
 
} 
 

 
console.log(createRanges(dates));

Однако библиотека как moment.js поможет разборе, форматирование и арифметике.

+0

Да, но как насчет выходных. –

+0

OP сказал «* игнорирование выходных дней», поэтому я и сделал. ;-) Нетрудно будет остановить диапазон по пятницам и начать снова по понедельникам. Что такое «выходные»? Не каждый использует субботу и воскресенье. – RobG

Смежные вопросы