简体   繁体   English

查找两个日期之间的天差(不包括周末)

[英]Find day difference between two dates (excluding weekend days)

Hi i am using jquery-ui datepicker to select date and date.js to find difference between 2 dates.嗨,我正在使用 jquery-ui datepicker来选择日期和date.js来查找 2 个日期之间的差异。

Right now the problem is I want to exclude weekend days from calculation (saturday and sunday).现在的问题是我想从计算中排除周末(周六和周日)。 How should i do that?我该怎么做?

For example the user select start date (13/8/2010) and end date (16/8/2010).例如,用户选择开始日期 (13/8/2010) 和结束日期 (16/8/2010)。 Since 14/8/2010 and 15/8/2010 is in week days, instead of 4 days total, i want it to be only 2 days.由于 14/8/2010 和 15/8/2010 是工作日,而不是总共 4 天,我希望它只有 2 天。

This is the code im using right now:这是我现在使用的代码:

<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>

Maybe someone else can help you converting this function into JQuery's framework...也许其他人可以帮助您将此功能转换为 JQuery 的框架...

I found this function here .我在这里找到了这个功能。

 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) { //Equal to makes it reduce 5 days 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 } var date1 = new Date("August 11, 2010 11:13:00"); var date2 = new Date("August 16, 2010 11:13:00"); alert(calcBusinessDays(date1, date2));

## EDITED ## ##已编辑##

If you want to use it with your that format just:如果您想将它与您的格式一起使用:

Your code will look like:您的代码将如下所示:

 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) { //Equal to makes it reduce 5 days 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 } $("#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 = new Date(d1); var enddate1 = new Date(d2); 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 src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <label>Start Date <input type="date" id="startdate" value="2019-03-03"/> </label> <label>End Date <input type="date" id="enddate" value="2019-03-06"/> </label> <label>N. of days <output id="noofdays"/> </label>

To do this, you should NOT search all days between these dates !为此,您不应搜索这些日期之间的所有日子!

It's not complicated, look some evident assumptions:并不复杂,看一些明显的假设:

  1. All full-week has 7-days.所有整周都有 7 天。

  2. Which 2 are weekend-days.其中 2 天是周末。

  3. And which 5 are business-day.其中 5 个是工作日。

Evident conclusions:明显的结论:

  1. Look all days is loss of time.看所有的日子都是在浪费时间。

  2. Check what day is weekend to all week is loss of time.检查哪一天是周末到整个星期都在浪费时间。


Without tedious explanation.. let me show the code:没有繁琐的解释..让我展示代码:

 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); } function calc() { let start = document.querySelector('#startDate').value, end = document.querySelector('#endDate').value, result = getBusinessDateCount(new Date(start), new Date(end)); document.querySelector('#result').value = result; }
 Start date: <input type="date" id="startDate" value="2020-01-04"><br> End date: <input type="date" id="endDate" value="2020-01-06"><br> <input type="button" onclick="calc()" value="Get business days"><br> Business days: <input id="result" readonly>

You can test it yourself with any dates.您可以使用任何日期自行测试。

I just want to notice that this code ONLY consumed 0.43 sec between dates from 2000 to 2015... It is much more fast than some other codes.我只是想注意到这段代码在 2000 年到 2015 年的日期之间只消耗了 0.43 秒......它比其他一些代码快得多。

Hope it helps...希望能帮助到你...

Nice coding !!不错的编码!!

This is how I would do it这就是我要做的

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"));

EDIT编辑
To clarify my comment to @keenebec...为了澄清我对@keenebec 的评论...
That solution will work for small date differences quite nicely and is easy to understand.该解决方案将很好地适用于较小的日期差异,并且易于理解。 But take something as "short" as a 6 year span and you can see a remarkable difference in speed.但是将一些“短”的东西作为 6 年的跨度,您会看到速度的显着差异。

http://jsfiddle.net/aSvxv/ http://jsfiddle.net/aSvxv/

I included all 3 answers and the original answer is indeed the fastest, but not by much and the trade off for a few microseconds of execution is somewhat trivial to me in favor of readability.我包含了所有 3 个答案,原始答案确实是最快的,但速度并不快,而且为了提高可读性,几微秒的执行权衡对我来说有些微不足道。

 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"/>

That looks like too much work to me.对我来说,这看起来工作量太大了。 I'd rather let the computer do the heavy lifting- //我宁愿让电脑做繁重的工作- //

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))

To understand way.,理解方式。,


  1. Actual days = 14实际天数 = 14
  2. weeks for Actual days = 14/7=2实际天数的周数 = 14/7=2
  3. Weekends per week=2每周周末=2
  4. Total weekends=2*weeks for days周末总数=2*周数

So apply this ,所以应用这个,

 $('#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("");
}

Thank you !谢谢 !

Important: Most answers here don't actually work if the start date (or sometimes the end date) is a saturday or sunday.重要提示:如果开始日期(或有时是结束日期)是星期六或星期日,则此处的大多数答案实际上不起作用。 I took the accepted response and modified it so that this issue is resolved now:我接受了接受的回复并对其进行了修改,以便现在解决此问题:

    var dateDiff;
    if (dateTo < dateFrom) return -1; // error code if dates transposed
    var dateFromDayOrig = dateFrom.getDay(); // day of week
    var dateToDayOrig = dateTo.getDay();
    var dateFromDay = (dateFromDayOrig == 0) ? 7 : dateFromDayOrig; // change Sunday from 0 to 7
    var dateToDay = (dateToDayOrig == 0) ? 7 : dateToDayOrig;
    dateFromDay = (dateFromDay > 5) ? 5 : dateFromDay; // only count weekdays
    dateToDay = (dateToDay > 5) ? 5 : dateToDay;

    // calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
    var weekDifference = Math.floor((dateTo.getTime() - dateFrom.getTime()) / 604800000);

    if (dateFromDay <= dateToDay) {
        dateDiff = (weekDifference * 5) + (dateToDay - dateFromDay);
    } else {
        dateDiff = ((weekDifference + 1) * 5) - (dateFromDay - dateToDay);
    }

    // fix: remove one day if it's saturday or sunday
    if (dateFromDayOrig >= 6 || dateFromDayOrig == 0) {
    dateDiff--;
    }

    return (dateDiff + 1); // add 1 because dates are inclusive

There seems to be few issues with the response that has been marked as solution.被标记为解决方案的响应似乎没有什么问题。

  • The statement setFullYear() is returning incorrect value if I choose start date as 06/11/2015.如果我选择开始日期为 06/11/2015,语句 setFullYear() 将返回不正确的值。 So instead, the startDate1 and endDate1 can be directly passed to the function.因此,可以将 startDate1 和 endDate1 直接传递给函数。

  • If the start date is Saturday or Sunday, still the code is counting it(iWeekday1) as 5 days如果开始日期是星期六或星期日,代码仍然将其(iWeekday1)计为 5 天

  • If the end date is Saturday or Sunday, still the code is counting it(iWeekday2) as 5 days.如果结束日期是星期六或星期日,代码仍然将其(iWeekday2)计为 5 天。 But these 5 days already get counted in the iweeks calculation.但是这 5 天已经被计入 iweeks 计算中。
    So instead of所以代替
    iWeekday1 = (iWeekday1 > 5) ? iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; 5 : iWeekday1; // only count weekdays // 只计算工作日
    iWeekday2 = (iWeekday2 > 5) ? iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2; 5 : iWeekday2;
    it should be它应该是
    iWeekday1 = (iWeekday1 > 5) ? iWeekday1 = (iWeekday1 > 5) ? 0 : iWeekday1; 0 : iWeekday1; // only count weekdays // 只计算工作日
    iWeekday2 = (iWeekday2 > 5) ? iWeekday2 = (iWeekday2 > 5) ? 0 : iWeekday2; 0 : iWeekday2;

  • The last IF condition should be executed when start and end date day is same like both are on same day, the date could be different当开始和结束日期相同时,应该执行最后一个 IF 条件,例如两者都在同一天,日期可能不同
    if (iWeekday1 < = iWeekday2)如果 (iWeekday1 < = iWeekday2)

  • The condition that adjusts if both days are weekends can be removed可以去掉如果两天都是周末调整的条件
    iDateDiff -= iAdjust iDateDiff -= iAdjust

  • Lastly, the +1 should be done only if start and end date falls on weekdays.最后,仅当开始和结束日期在工作日时才应执行 +1。 Currently, it is adding in both the cases.目前,它正在添加这两种情况。
    return (iDateDiff + 1);返回 (iDateDiff + 1); //Add condition to apply only if both days are weekdays //添加仅当这两天都是工作日时才应用的条件

--can't comment on that answer as I do not have that reputation :) --不能评论那个答案,因为我没有那个名声:)

What I did我做了什么

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 is weekdays, e is weekends c是工作日, e是周末

I get it work with this code.我得到它与此代码的工作。 Note that the function is from date.js and businessday js (thanks to Garis Suero).请注意,该函数来自date.js和 businessday js(感谢 Garis Suero)。 Start Date 11-08-2010 End Date 16-08-2010 will result 4 days of leave.开始日期 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>
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
                        }  

I have used Angular framework and Moment.js library to implement the solution.我使用了 Angular 框架和 Moment.js 库来实现该解决方案。 My solution covers all the cases.我的解决方案涵盖了所有情况。

this.daysInBetween = this.endMoment.diff(this.startMoment, 'days') + 1;
this.weeksInBetween = this.endMoment.diff(this.startMoment, 'weeks');
this.weekDays = this.daysInBetween - (this.weeksInBetween * 2);

if ( (this.startMoment.day() === 0 && this.endMoment.day() === 6) ||
 (this.startMoment.day() > this.endMoment.day()) ) {
  // IF ONE WEEKEND WAS MISSED
  this.weekDays-=2;
} else if ( this.startMoment.day() <= this.endMoment.day() &&
( this.startMoment.day() === 0 || this.startMoment.day() === 6 ||
  this.endMoment.day() === 0 || this.endMoment.day() === 6) ) {
  // IF EITHER OF DAYS WAS A WEEKEND
  this.weekDays--;
}

Live Demo: Calculate number of weekdays现场演示: 计算工作日数

I am currently working on a blog to write about my approach to this specific problem.我目前正在写一个博客来写我解决这个特定问题的方法。 I will post the link to the blog on the comment.我将在评论中发布指向该博客的链接。

Important: Most answers here don't actually work if the start date (or sometimes the end date) is a saturday or sunday.重要提示:如果开始日期(或有时是结束日期)是星期六或星期日,这里的大多数答案实际上都不起作用。 For example: if your start and end date are例如:如果您的开始日期和结束日期是

  • Saturday to Sunday or vice versa周六至周日,反之亦然
  • or Saturday to Saturday周六至周六
  • or Sunday to Sunday周日至周日

So, here is the modified answer from the accepted answer所以,这是接受的答案的修改后的答案

function calculateBusinessDays(dDate1, dDate2) {

var iWeeks, iDateDiff, iAdjust = 0;
if (dDate2 < dDate1) {
    return -1;
}

var iWeekday1 = dDate1.getDay();
var iWeekday2 = dDate2.getDay();

iWeekday1 = (iWeekday1 === 0) ? 7 : iWeekday1;
iWeekday2 = (iWeekday2 === 0) ? 7 : iWeekday2;

if (iWeekday1 > 5 && iWeekday2 <= 6) {
    iWeekday1 = 0;
    iAdjust = 1;
}
iWeekday2 = (iWeekday1 === 0 && iWeekday2 === 6) ? 0 : iWeekday2;

if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1;

iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1;
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000);

if (iWeeks===0 && iWeekday1===0 && iWeekday2===0 
    && (dDate2.getTime() !== dDate1.getTime()) ) {
    iWeeks = 1;
}

if (iWeekday1 <= iWeekday2) {
    iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1)
} else {
    iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2)
}
iDateDiff -= iAdjust
return (iDateDiff + 1);

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM