我有一个javascript函数,它计算两个日期之间的工作日,它可以工作,但问题是它不考虑假期。如何修改此函数,例如在异常数组中添加假日?
在互联网上搜索了这个问题,但没有找到关于假期的例外情况。
例如假日数组:
var holidays = ['2016-05-03','2016-05-05'];
我有计算这个的功能:
function workingDaysBetweenDates(d0, d1) {
var startDate = parseDate(d0);
var endDate = parseDate(d1);
// Validate input
if (endDate < startDate)
return 0;
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0,0,0,1); // Start just after midnight
endDate.setHours(23,59,59,999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days = days - (weeks * 2);
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1)
days = days - 2;
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6)
days = days - 1
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0)
days = days - 1
return days;
}
function parseDate(input) {
// Transform date from text to date
var parts = input.match(/(\d+)/g);
// new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}
在jsfiddle中做了一个例子:
也许还有一些其他功能可以在Jquery中轻松使用?
答案 0 :(得分:5)
实现目标的最简单方法是在开始和结束日期之间寻找这些天。
$(document).ready(function(){
$('#calc').click(function(){
var d1 = $('#d1').val();
var d2 = $('#d2').val();
$('#dif').text(workingDaysBetweenDates(d1,d2));
});
});
function workingDaysBetweenDates(d0, d1) {
var holidays = ['2016-05-03','2016-05-05'];
var startDate = parseDate(d0);
var endDate = parseDate(d1);
// Validate input
if (endDate < startDate) {
return 0;
}
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0,0,0,1); // Start just after midnight
endDate.setHours(23,59,59,999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days -= weeks * 2;
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1) {
days -= 2;
}
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6) {
days--;
}
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0) {
days--;
}
/* Here is the code */
for (var i in holidays) {
if ((holidays[i] >= d0) && (holidays[i] <= d1)) {
days--;
}
}
return days;
}
function parseDate(input) {
// Transform date from text to date
var parts = input.match(/(\d+)/g);
// new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="d1" value="2016-05-02"><br>
<input type="text" id="d2" value="2016-05-08">
<p>Working days count: <span id="dif"></span></p>
<button id="calc">Calc</button>
<p>
Now it shows 5 days, but I need for example add holidays
3 and 5 May (2016-05-03 and 2016-05-05) so the result will be 3 working days
</p>
答案 1 :(得分:3)
尝试:
var startDate = new Date('05/03/2016');
var endDate = new Date('05/10/2016');
var numOfDates = getBusinessDatesCount(startDate,endDate);
function getBusinessDatesCount(startDate, endDate) {
var count = 0;
var curDate = startDate;
while (curDate <= endDate) {
var dayOfWeek = curDate.getDay();
if(!((dayOfWeek == 6) || (dayOfWeek == 0)))
count++;
curDate.setDate(curDate.getDate() + 1);
}
alert(count)
return count;
}
答案 2 :(得分:1)
最高答案实际上是有效的,但有缺陷。
当斋月在星期六或星期日时,它仍会减少一天。
将此添加到现有代码中:
.... /* Here is the code */
for (var i in holidays) {
if ((holidays[i] >= d0) && (holidays[i] <= d1)) {
// Check if specific holyday is Saturday or Sunday
var yourDate = new Date(holidays[i]);
if(yourDate.getDay() === 6 || yourDate.getDay() === 0){
// If it is.. do nothing
} else {
// if it is not, reduce a day..
days--;
}
}
}
答案 3 :(得分:0)
简单地从你得到的值(在你的小提琴中)减少数组的长度
.force
您还需要从假日过滤掉周末
var numberofdayswithoutHolidays= 5;
var holidays = ['2016-05-03','2016-05-05'];
alert( numberofdayswithoutHolidays - holidays.length );
答案 4 :(得分:0)
您也可以尝试以下代码:
const moment = require('moment-business-days');
/**
*
* @param {String} date - iso Date
* @returns {Number} difference between now and @param date
*/
const calculateDaysLeft = date => {
try {
return moment(date).businessDiff(moment(new Date()))
} catch (err) {
throw new Error(err)
}
}
答案 5 :(得分:0)
由于我的JS生锈,所以我采取了与@OscarGarcia类似的方法,主要是作为锻炼。
虽然看起来很相似,但要注意的是,如果假日恰好在周六或周日,则每天不减两次。这样,您可以预加载一个重复日期列表(例如12月25日,1月1日,7月4日,该日期可能在或可能不在其他工作日-周一至周五-)
$(document).ready(function(){
$('#calc').click(function(){
var d1 = $('#d1').val();
var d2 = $('#d2').val();
$('#dif').text(workingDaysBetweenDates(d1,d2));
});
});
function workingDaysBetweenDates(d0, d1) {
var startDate = parseDate(d0);
var endDate = parseDate(d1);
// populate the holidays array with all required dates without first taking care of what day of the week they happen
var holidays = ['2018-12-09', '2018-12-10', '2018-12-24', '2018-12-31'];
// Validate input
if (endDate < startDate)
return 0;
var z = 0; // number of days to substract at the very end
for (i = 0; i < holidays.length; i++)
{
var cand = parseDate(holidays[i]);
var candDay = cand.getDay();
if (cand >= startDate && cand <= endDate && candDay != 0 && candDay != 6)
{
// we'll only substract the date if it is between the start or end dates AND it isn't already a saturday or sunday
z++;
}
}
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0,0,0,1); // Start just after midnight
endDate.setHours(23,59,59,999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days = days - (weeks * 2);
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1)
days = days - 2;
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6)
days = days - 1
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0)
days = days - 1
// substract the holiday dates from the original calculation and return to the DOM
return days - z;
}
function parseDate(input) {
// Transform date from text to date
var parts = input.match(/(\d+)/g);
// new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}
2018-12-09是星期天...使用此代码,它将只减去一次(因为是星期日),而不是两次(就像我们只检查是否是国定假日一样)>
答案 6 :(得分:0)
$(document).ready(() => {
$('#calc').click(() => {
var d1 = $('#d1').val();
var d2 = $('#d2').val();
$('#dif').text(workingDaysBetweenDates(d1,d2));
});
});
let workingDaysBetweenDates = (d0, d1) => {
/* Two working days and an sunday (not working day) */
var holidays = ['2016-05-03', '2016-05-05', '2016-05-07'];
var startDate = parseDate(d0);
var endDate = parseDate(d1);
// Validate input
if (endDate < startDate) {
return 0;
}
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0, 0, 0, 1); // Start just after midnight
endDate.setHours(23, 59, 59, 999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days -= weeks * 2;
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1) {
days -= 2;
}
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6) {
days--;
}
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0) {
days--;
}
/* Here is the code */
holidays.forEach(day => {
if ((day >= d0) && (day <= d1)) {
/* If it is not saturday (6) or sunday (0), substract it */
if ((parseDate(day).getDay() % 6) != 0) {
days--;
}
}
});
return days;
}
function parseDate(input) {
// Transform date from text to date
var parts = input.match(/(\d+)/g);
// new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="d1" value="2016-05-02"><br>
<input type="text" id="d2" value="2016-05-08">
<p>Working days count: <span id="dif"></span></p>
<button id="calc">Calc</button>
<p>
Now it shows 5 days, but I need for example add holidays
3 and 5 May (2016-05-03 and 2016-05-05) so the result will be 3 working days
</p>
答案 7 :(得分:0)
我认为这种解决方案要简单得多
const numberOfDaysInclusive = (d0, d1) => {
return 1 + Math.round((d1.getTime()-d0.getTime())/(24*3600*1000));
}
const numberOfWeekends = (d0, d1) => {
const days = numberOfDaysInclusive(d0, d1); // total number of days
const sundays = Math.floor((days + (d0.getDay() + 6) % 7) / 7); // number of sundays
return 2*sundays + (d1.getDay()==6) - (d0.getDay()==0); // multiply sundays by 2 to get both sat and sun, +1 if d1 is saturday, -1 if d0 is sunday
}
const numberOfWeekdays = (d0, d1) => {
return numberOfDaysInclusive(d0, d1) - numberOfWeekends(d0, d1);
}
答案 8 :(得分:0)
获取两个日期之间的所有工作日:
private getCorrectWeekDays(StartDate,EndDate){
let _weekdays = [0,1,2,3,4];
var wdArr= [];
var currentDate = StartDate;
while (currentDate <= EndDate) {
if ( _weekdays.includes(currentDate.getDay())){
wdArr.push(currentDate);
//if you want to format it to yyyy-mm-dd
//wdArr.push(currentDate.toISOString().split('T')[0]);
}
currentDate.setDate(currentDate.getDate() +1);
}
return wdArr;
}