Расчет периодов и дат, логическая задача
Здравствуйте.
Мне поручили сделать frontend фичу, а специалист по client-side в отпуске. Прошу вашей помощи. Есть вот такая фитча, сделана на jquery ui: slider. ![]() Задача: динамически менять даты в поле выбора даты при изменении слайдера и наоборот, динамически менять положение слайдера при выборе даты. Все бы просто, но как можно заметить периоды неравномерны, т.е. шаг разный. Неделя - один шаг, неделя-месяц другой шаг. Вся полоска - это период от 0 до 1000. Я разбил её на несколько периодов с разным шагом. Собственно вопрос, как лучше такое сделать/посчитать ? Задача именно как вычислять положение слайдера на соостветсвие дате, вычислять дату соотвествующую положению слайдера. Т.е. как менять даты и пложение полоски (технические вопросы) я знаю. |
Задача решена, вот код
SliderFilterEvents = { intervalValueMinusMonth: 1, intervalValueMinusWeek: 227, intervalValueToDay: 380, intervalPlusWeek: 530, intervalPlusMonth: 775, intervalPlusHalfYear: 1000, /** * Callback функция вызываемая при перемещении слайдера ( выбор дат ) * @param object event * @param object ui **/ callbackSlideSlider: function(event, ui){ var slidePoint1 = $("#slider").slider("values",0); var slidePoint2 = $("#slider").slider("values",1); var date = new Date(); var daysInMonth = date.getDaysInMonth(); SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalPlusMonth, SliderFilterEvents.intervalPlusHalfYear, (180-daysInMonth), daysInMonth-1); SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalPlusWeek, SliderFilterEvents.intervalPlusMonth, (daysInMonth-7), 7); SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalValueToDay, SliderFilterEvents.intervalPlusWeek, 7, 0); SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalValueMinusWeek, SliderFilterEvents.intervalValueToDay, 7, -7); SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalValueMinusMonth, SliderFilterEvents.intervalValueMinusWeek, daysInMonth-7, (-daysInMonth)); }, /** * Считает соотвествие расположения слайдера к дате и устанавливает дату * @param minPeriod минимальный период * @param maxPeriod максимальный период * @param days количество дней составляющих период * @param offset смещение в днях */ calculationAndSetNumberDay: function(minPeriod, maxPeriod, days, offset){ var period = maxPeriod-minPeriod; var oneDayPeriod = (period/days).toFixed(0); var offsetSeconds = offset*86400; var slidePoint1 = $("#slider").slider("values",0); var slidePoint2 = $("#slider").slider("values",1); if(slidePoint1 >= minPeriod && slidePoint1 <= maxPeriod){ //550-slidePoint1(410)=190-140=50/27=1,8=ceil(1,8)=2 var offsetInDays = ((period-(maxPeriod-slidePoint1))/oneDayPeriod).toFixed(0); var value = JSHelper.timestamp()+offsetSeconds+(86400*offsetInDays); //console.log(value, offsetSeconds, offsetInDays, (86400*offsetInDays), JSHelper.timestamp(), JSHelper.date('d.m.Y', value)); $( "#date_start" ).val(JSHelper.date('d.m.Y', value)); } if(slidePoint2 >= minPeriod && slidePoint2 <= maxPeriod){ //550-slidePoint1(410)=190-140=50/27=1,8=ceil(1,8)=2 var offsetInDays = ((period-(maxPeriod-slidePoint2))/oneDayPeriod).toFixed(0); $( "#date_end" ).val(JSHelper.date('d.m.Y', JSHelper.timestamp()+offsetSeconds+(86400*offsetInDays))); } }, /** * Выбрана дата, смещаем слайдер * @param string dateType [date_start, date_end] тип измененной даты **/ callbackChangeDatе: function(dateType){ /** * Посчитать сколько прошло дней от текущей даты до указанной * @param string data дата в формате d.m.Y **/ function calculateDiffInDays(date){ var intervalInDate = Math.floor((JSHelper.createTimestampByDate(date)-JSHelper.timestamp())/86400)+1; return intervalInDate; } /** * Переместить слайдер на нужное количество дней от текущей даты * @param integer slideIndex индекс слайдера * @param string days на какое количество дней смещать **/ function slideMove(slideIndex, days){ var date = new Date(); var daysInMonth = date.getDaysInMonth(); if(days <= 180 && days >= daysInMonth) { var newDays = (days-daysInMonth)+1; var position = calculateMoveInterval(SliderFilterEvents.intervalPlusHalfYear, SliderFilterEvents.intervalPlusMonth, 180-daysInMonth, newDays); } else if(days <= daysInMonth && days > 7) { var newDays = days-7; var position = calculateMoveInterval(SliderFilterEvents.intervalPlusMonth, SliderFilterEvents.intervalPlusWeek, daysInMonth-7, newDays); } else if(days <= 7 && days >= 1) { var position = calculateMoveInterval(SliderFilterEvents.intervalPlusWeek, SliderFilterEvents.intervalValueToDay, 7, days); } else if(days >= -7 && days < 1) { var position = calculateMoveInterval(SliderFilterEvents.intervalValueToDay, SliderFilterEvents.intervalValueMinusWeek, 7, days); } else if(days >= -daysInMonth) { //посчитать количество дней - 7 var newDays = days+7; //var positionWeekly = calculateMoveInterval(SliderFilterEvents.intervalValueMinusWeek, SliderFilterEvents.intervalValueToDay, 7, 7) //сместить слайдер на оставшееся время var positionMonth = calculateMoveInterval(SliderFilterEvents.intervalValueMinusWeek, SliderFilterEvents.intervalValueMinusMonth, daysInMonth-7, newDays); var position = positionMonth; } SliderFilterEvents.updateSlidePosition(position, slideIndex) } /** * Вычислить новую позицию слайдера, исходя из переданных параметров * @param integer max_period максимальный период * @param integer min_period минимальный период * @param integer period количество дней, которое составляет указанный период * @param days количество дней на которое смещать * @return integer новая позиция слайдера **/ function calculateMoveInterval(max_period, min_period, period, days){ var interval = max_period-min_period; var oneDayPeriod = (interval/period).toFixed(0); var movePeriod = oneDayPeriod*days; return days > 0 ? min_period+movePeriod : max_period+movePeriod; } if(dateType == 'date_start') { var days = calculateDiffInDays($('#date_start').val()); slideMove(0, days); } else if(dateType == 'date_end') { var days = calculateDiffInDays($('#date_end').val()); slideMove(1, days); } }, /* other methods */ } |
Часовой пояс GMT +3, время: 12:24. |