Найдите разницу в день между двумя датами (за исключением выходных дней)
Привет, я использую jquery-ui datepicker для выбора даты и date.js, чтобы найти разницу между двумя датами.
Сейчас проблема заключается в том, что я хочу исключить выходные дни из расчета (суббота и воскресенье). Как мне это сделать?
Например, пользователь выбирает дату начала (13/8/2010) и дату окончания (16/8/2010). С 14/8/2010 и 15/8/2010 в будние дни, а не 4 дня, я хочу, чтобы это было всего 2 дня.
Это код im, использующий прямо сейчас:
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = 1 + Math.round((enddate1 - startdate1)/day);
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
Ответы
Ответ 1
Возможно, кто-то еще может помочь вам преобразовать эту функцию в среду JQuery...
В необработанном javascript я буду использовать:
Live Demo
<script>
function calcBusinessDays(dDate1, dDate2) { // input given as Date objects
var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) return -1; // error code if dates transposed
var iWeekday1 = dDate1.getDay(); // day of week
var iWeekday2 = dDate2.getDay();
iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000)
if (iWeekday1 <= iWeekday2) {
iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust // take into account both days on weekend
return (iDateDiff + 1); // add 1 because dates are inclusive
}
</script>
найдено здесь
и вызвать эту функцию, например, что-то вроде:
<script>
alert(calcBusinessDays(new Date("August 11, 2010 11:13:00"),new Date("August 16, 2010 11:13:00")));
</script>
## EDITED ##
Если вы хотите использовать его только в этом формате:
Ваш код будет выглядеть так:
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var newstartdate=new Date();
newstartdate.setFullYear(startdate1.getYear(),startdate1.getMonth(),startdate1.getDay());
var newenddate=new Date();
newenddate.setFullYear(enddate1.getYear(),enddate1.getMonth(),enddate1.getDay());
var days = calcBusinessDays(newstartdate,newenddate);
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
Ответ 2
Вот как я это сделаю
function getDays(d1, d2) {
var one_day=1000*60*60*24;
var d1_days = parseInt(d1.getTime()/one_day) - 1;
var d2_days = parseInt(d2.getTime()/one_day);
var days = (d2_days - d1_days);
var weeks = (d2_days - d1_days) / 7;
var day1 = d1.getDay();
var day2 = d2.getDay();
if (day1 == 0) {
days--;
} else if (day1 == 6) {
days-=2;
}
if (day2 == 0) {
days-=2;
} else if (day2 == 6) {
days--;
}
days -= parseInt(weeks) * 2;
alert(days);
}
getDays(new Date("June 8, 2004"),new Date("February 6, 2010"));
ИЗМЕНИТЬ
Чтобы прояснить мой комментарий к @keenebec...
Это решение будет работать для небольших различий даты довольно хорошо и легко понять. Но возьмите что-то как "короткое" как 6-летний период, и вы увидите замечательную разницу в скорости.
http://jsfiddle.net/aSvxv/
Я включил все 3 ответа, и исходный ответ действительно самый быстрый, но не намного, и компромисс в течение нескольких микросекунд исполнения для меня несколько тривиален в пользу удобочитаемости.
Ответ 3
Чтобы сделать это, вы НЕ должны искать все дни между этими датами!
Это не сложно, посмотрите некоторые очевидные предположения:
Очевидные выводы:
-
Смотреть все дни - это потеря времени.
-
Проверьте, что день недели на всю неделю - это потеря времени.
Без утомительного объяснения.. позвольте мне показать код:
function getBusinessDateCount (startDate, endDate) {
var elapsed, daysBeforeFirstSaturday, daysAfterLastSunday;
var ifThen = function (a, b, c) {
return a == b ? c : a;
};
elapsed = endDate - startDate;
elapsed /= 86400000;
daysBeforeFirstSunday = (7 - startDate.getDay()) % 7;
daysAfterLastSunday = endDate.getDay();
elapsed -= (daysBeforeFirstSunday + daysAfterLastSunday);
elapsed = (elapsed / 7) * 5;
elapsed += ifThen(daysBeforeFirstSunday - 1, -1, 0) + ifThen(daysAfterLastSunday, 6, 5);
return Math.ceil(elapsed);
}
var date1 = new Date(1999, 12, 31);
var date2 = new Date(); // now
print( getBusinessDateCount(date1, date2) );
Вы можете проверить его сами с любыми датами.
Я просто хочу заметить, что этот код ТОЛЬКО потреблял 0,43 секунды между датами с 2000 по 2015 год... Это намного быстрее, чем некоторые другие коды.
Надеюсь, что это поможет...
Хорошее кодирование!
Ответ 4
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf())
date.setDate(date.getDate() + days);
return date;
}
function getBusinessDatesCount(startDate, endDate) {
var count = 0;
var curDate = startDate;
while (curDate <= endDate) {
var dayOfWeek = curDate.getDay();
var isWeekend = (dayOfWeek == 6) || (dayOfWeek == 0);
if(!isWeekend)
count++;
curDate = curDate.addDays(1);
}
return count;
}
//Usage
var startDate = new Date('7/16/2015');
var endDate = new Date('7/20/2015');
var numOfDays = getBusinessDatesCount(startDate,endDate);
jQuery('div#result').text(numOfDays);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"/>
Ответ 5
Это выглядит слишком много для меня. Я бы предпочел, чтобы компьютер сделал тяжелый подъем -
//
Date.bizdays= function(d1, d2){
var bd= 0, dd, incr=d1.getDate();
while(d1<d2){
d1.setDate(++incr);
dd= d1.getDay();
if(dd%6)++bd;
}
return bd;
}
//test
var day1= new Date(2010, 7, 11), day2= new Date(2010, 7, 31);
alert(Date.bizdays(day1, day2))
Ответ 6
Чтобы понять способ.,
- Фактические дни = 14
- недели для фактических дней = 14/7 = 2
- Выходные дни в неделю = 2
- Всего выходных дней = 2 * недели в течение дней
Итак, примените это,
$('#EndDate').on('change', function () {
var start = $('#StartDate').datepicker('getDate');
var end = $('#EndDate').datepicker('getDate');
if (start < end) {
var days = (end - start) / 1000 / 60 / 60 / 24;
var Weeks=Math.round(days)/7;
var totalWeekends=Math.round(Weeks)*2;
var puredays=Math.round(days)-totalWeekends;
$('#days').text(Math.round(puredays) + "Working Days");
}
else {
alert("");
}
Спасибо!
Ответ 7
Я работаю с этим кодом. Обратите внимание, что функция от date.js и businessday js (спасибо Гарису Суэро). Дата начала 11-08-2010 Дата окончания 16-08-2010 приведет к 4 дням отпуска.
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
Ответ 8
Что я сделал
function calcbusinessdays()
{
for(var c=0,e=0,d=new Date($("#startdate").val()),a=(new Date($("#enddate").val())-d)/864E5;0<=a;a--)
{
var b=new Date(d);
b.setDate(b.getDate()+a);
1==Math.ceil(b.getDay()%6/6)?c++:e++
}
$("#noofdays").html(c)
};
c
- будние дни, e
- выходные дни
Ответ 9
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
var currentDate;
selectFlixbleDates = [];
var monToSatDateFilter=[];
currentDate=new Date(date);
while(currentDate){
console.log("currentDate"+currentDate);
if(new Date(currentDate).getDay()!=0){
selectFlixbleDates.push(currentDate)
}
if(selectFlixbleDates.length==$scope.numberOfDatePick)
{
break;
}
currentDate=addDays(currentDate,1);
}
for (var i = 0; i < selectFlixbleDates.length; i++) {
// console.log(between[i]);
monToSatDateFilter.push((selectFlixbleDates[i].getMonth() + 1) + '/' + selectFlixbleDates[i].getDate() + '/' + selectFlixbleDates[i].getFullYear());
}
var endDate=monToSatDateFilter.slice(-1).pop();
var space =monToSatDateFilter.join(', ');
var sdfs= document.getElementById("maxPicks").value =space;
$scope.$apply(function() {
$scope.orderEndDate=monToSatDateFilter.slice(-1).pop()
$scope.orderStartDate=monToSatDateFilter[0];
});
document.getElementById("startDateEndDate").innerHTML =$scope.orderStartDate+ ' TO ' +$scope.orderEndDate
}