исключить выходные дни в расчете даты javascript
у меня есть два набора кодов, которые работают. Нужна помощь, чтобы объединить их в одно целое.
этот код дает мне разницу между двумя датами. отлично работает:
function test(){
var date1 = new Date(txtbox_1.value);
var date2 = new Date(txtbox_2.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
txtbox_3.value = days + "." + hrs; }
источник для вышеуказанного кода
код ниже @cyberfly, похоже, имеет ответ на исключение sat и sun, который мне нужен. источник. Однако его в jquery и вышеуказанный код находятся в JS. Поэтому нужна была помощь, так как мне не хватало этих знаний :(
<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>
редактировать Сделал попытку комбинирования кодов. вот мой образец. получение объект ожидаемая ошибка.
function test(){
var date1 = new Date(startdate.value);
var date2 = new Date(enddate.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
var startdate1 = getDateFromFormat(startdate, "dd/mm/yyyy hh:mm");
var enddate1 = getDateFromFormat(enddate, "dd/mm/yyyy hh:mm");
days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
noofdays.value = days + "." + hrs; }
start: <input type="text" id="startdate" name="startdate" value="02/03/2015 00:00">
end: <input type="text" id="enddate" name="enddate" value="02/03/2015 00:01">
<input type="text" id="noofdays" name="noofdays" value="">
4 ответов
при определении количества дней между двумя датами необходимо принять множество решений о том, что такое День. Например, период с 1 февраля по 2 февраля обычно составляет один день, поэтому с 1 февраля по 1 февраля-ноль дней.
при добавлении сложности подсчета только рабочих дней, все становится намного сложнее. Например. С понедельника 2 февраля 2015 по пятницу 6 февраля-4 прошедших дня (с понедельника по вторник-1, с понедельника по среду-2 и т. д.), однако выражение "с понедельника по пятницу" вообще рассматриваемый как 5 рабочих дней, а продолжительность Пн 2 февраля по сб 7 февраля также должна быть 4 рабочих дня, но с воскресенья по субботу должно быть 5.
вот мой алгоритм:
- получить общее количество целых дней между двумя датами
- разделить на 7, чтобы получить количество целых недель
- умножить количество недель на два, чтобы получить количество выходных дней
- вычесть количество выходных дней из целого, чтобы получить бизнес дни
- если общее количество дней не является четным числом недель, добавьте число недель * 7 к дате начала, чтобы получить временную дату
- пока дата temp чем дата конца:
- если дата temp не суббота или воскресенье, добавьте один рабочих дней
- добавить один в дату temp
- вот и все.
шагающая часть в конце, вероятно, может быть заменена каким-то другим алгоритмом, но она никогда не будет петлять более 6 дней, поэтому это простое и разумно эффективное решение проблемы неравномерных недель.
некоторые последствия вышеизложенного:
- С понедельника по пятницу-4 рабочих дня
- любой день в тот же день в другой неделе четное количество недель и, следовательно, четный mutiple 5, например, понедельник 2 февраля в понедельник 9 февраля и воскресенье 1 февраля в воскресенье 8 февраля 5 рабочих дней
- пятница 6 февраля до воскресенья 7 февраля-ноль рабочие дни
- пятница 6 февраля до понедельника 9 февраля-один рабочий день
- воскресенье 8 февраля: воскресенье 15 февраля, СБ 14 февраля и пт 13 февраля все 5 рабочих дней
вот код:
// Expects start date to be before end date
// start and end are Date objects
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(+start);
var e = new Date(+end);
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
}
}
return days;
}
Не знаю, как он сравнивается с ответом jfriend00 или кодом, на который вы ссылались, если вы хотите, чтобы период был включительным, просто добавьте его, если дата начала или окончания-рабочий день.
вот простая функция для вычисления количества рабочих дней между двумя объектами. Как и планировалось, он не учитывает начальный день, но считает конечный день, поэтому, если вы дадите ему дату во вторник одной недели и вторник следующей недели, он вернет 5 рабочих дней. Это не учитывает праздники, но работает должным образом во всех изменениях летнего времени.
function calcBusinessDays(start, end) {
// This makes no effort to account for holidays
// Counts end day, does not count start day
// make copies we can normalize without changing passed in objects
var start = new Date(start);
var end = new Date(end);
// initial total
var totalBusinessDays = 0;
// normalize both start and end to beginning of the day
start.setHours(0,0,0,0);
end.setHours(0,0,0,0);
var current = new Date(start);
current.setDate(current.getDate() + 1);
var day;
// loop through each day, checking
while (current <= end) {
day = current.getDay();
if (day >= 1 && day <= 5) {
++totalBusinessDays;
}
current.setDate(current.getDate() + 1);
}
return totalBusinessDays;
}
и, код jQuery + jQueryUI для демо:
// make both input fields into date pickers
$("#startDate, #endDate").datepicker();
// process click to calculate the difference between the two days
$("#calc").click(function(e) {
var diff = calcBusinessDays(
$("#startDate").datepicker("getDate"),
$("#endDate").datepicker("getDate")
);
$("#diff").html(diff);
});
и вот простой демо построен с выбора даты в jQueryUI: http://jsfiddle.net/jfriend00/z1txs10d/
@RobG дал отличный алгоритм для отделения рабочих дней от выходных. Я думаю, что единственная проблема заключается в том, что если начальные дни-выходные, суббота или воскресенье, то нет рабочих дней/выходных будет одним меньше.
исправленный код ниже.
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(start);
var e = new Date(end);
var addOneMoreDay = 0;
if( s.getDay() == 0 || s.getDay() == 6 ) {
addOneMoreDay = 1;
}
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
//s.setDate(s.getDate() + 1);
}
}
var weekEndDays = totalDays - days + addOneMoreDay;
return weekEndDays;
}
ссылка JSFiddle-этоhttps://jsfiddle.net/ykxj4k09/2/
сначала получить количество дней в месяц
totalDays(month, year) {
return new Date(year, month, 0).getDate();
}
тогда не получите рабочих дней в месяц, удалив субботу и воскресенье
totalWorkdays() {
var d = new Date(); // to know present date
var m = d.getMonth() + 1; // to know present month
var y = d.getFullYear(); // to knoow present year
var td = this.totalDays(m, y);// to get no of days in a month
for (var i = 1; i <= td; i++) {
var s = new Date(y, m - 1, i);
if (s.getDay() != 0 && s.getDay() != 6) {
this.workDays.push(s.getDate());// working days
}else {
this.totalWeekDays.push(s.getDate());//week days
}
}
this.totalWorkingDays = this.workDays.length;
}