开发者

Finding Difference between Dates in Javascript ( Yui Calendar )

I have been working with Orang开发者_开发百科eHRM for a project. It uses the Yui Calendar. I have been working on the leave module. The Leave module lets the user choose a From and To Date - A time frame for which he wants to apply leave !

I want to show the number of Working Days once the user has chosen the dates . A Simple Subtract statement would not work because I want to exclude the Saturdays and Sundays from the equations since they don't count as working days !

function fillToDate(frmLeaveApp) {

    var fromdate = frmLeaveApp.elements['txtLeaveFromDate'];
        var todate = frmLeaveApp.elements['txtLeaveToDate'];
            var result = frmLeaveApp.elements['txtLeaveTotalDay'];

     if(!fromdate || !todate || !result) {
        return;
    }

        var a = fromdate.value;
        var b = todate.value;

        var c = a.split('-');
        var d = b.split('-');

        var ac = new Date();
        ac.setFullYear(c[2], c[1], c[0]);
        var bd = new Date();
        bd.setFullYear(d[2], d[1], d[0]);

        result.value = (bd.getTime() - ac.getTime()) / (60*60*24*1000);
}

How do I do it ? Thanks in advance !


Not super proud of this solution - must be more elegant ways, but it should work - does not handle national holidays yet

Demo here

function fillToDate(frmLeaveApp) {

    var fromdate = frmLeaveApp.elements['txtLeaveFromDate'];
    var todate = frmLeaveApp.elements['txtLeaveToDate'];
    var result = frmLeaveApp.elements['txtLeaveTotalDay'];

    if(!fromdate || !todate || !result) {
        return;
    }

    var from = new Date(fromdate.value.replace(/\-/g,"/"));
    var to = new Date(todate.value.replace(/\-/g,"/"));

    // brute force seems the quickest to find
    var res = 0;
    var aDay = 24*60*60*1000;
    for (var i = from.getTime(), n=to.getTime();i < n; i+=aDay) {
      var d = new Date(i).getDay();
      if (d!=0 && d !=6) res++;
    }
    result.value = res;
}


A simple solution not that great :)

In YUI calendar, selected date cell has 'selected' class.

Saturday cell has 'wd6' and Sunday has 'wd0' classes.

Get all the cells which has 'selected' class and filter and remove cells which have 'wd6' and 'w0' classes.

var cells = Y.one("#calContainer").all('.selected');
var res = 0;

for (var i = 0, i < cells.length; i++) {
      if (!cells[i].hasClass('.wd6') || !cells[i].hasClass('.wd0')) res++;
    }

return res;

I haven't tested this code.


There are a few things here. Firstly, to get the number of days between two dates far more efficiently than already offered:

/*
   Get the number of days between two dates - not inclusive.

   "between" does not include the start date, so days
   between Thursday and Friday is one, Thursday to Saturday
   is two, and so on. Between Friday and the following Friday is 7.

   e.g. getDaysBetweenDates( 22-Jul-2011, 29-jul-2011) => 7.

   If want inclusive dates (e.g. leave from 1/1/2011 to 30/1/2011),
   use date prior to start date (i.e. 31/12/2010 to 30/1/2011).

   Only calculates whole days.
*/
function getDaysBetweenDates(d0, d1) {

  var msPerDay = 8.64e7;

  // Copy dates so don't mess them up
  var x0 = new Date(d0);
  var x1 = new Date(d1);

  // Set to noon - avoid DST errors
  x0.setHours(12,0,0);
  x1.setHours(12,0,0);


  // Round to remove daylight saving errors
  return Math.round( (x1 - x0) / msPerDay );
}

To get the number of "business" days, work out the number of whole weeks, multiply by 5, then adjust for remainder days and weekends at the start and finish. If you want to include the start date (typical for leave), use a start date one day before the nominated date. e.g. a leave application from Mon 4-Jul-2011 to Fri 8-Jul-2011 is 5 days of leave.

On the other hand, 5 business days from Mon 4-Jul-2011 is usually the following Monday, 11-Jul-2011 but might be COB on Fri 8-Jul-2011. The rules for such things can be different depending on local custom, legal precedent, contract agreement, and so on.

Also, such simple algorithms are rarely sufficient anyway. Public holidays mess things up, as does different working weeks in different places. Some are Saturday to Wednesday - Thursday and Friday are "weekend" days. In other places, Saturday is a work day (6 day week). Also, public holidays may fall on weekends.

/* 
   Simple algorithm: each week has 5 business days: Monday
   to Friday inclusive. Saturday and Sunday are non-working
   days.
*/

function getBusinessDaysBetweenDates(d0, d1) {
  var days = getDaysBetweenDates(d0, d1);
  var bWeeks = (days/7)|0;
  var rDays = days%7;
  var startDay = d0.getDay();
  var endDay   = d1.getDay();

  // If not whole weeks, adjust for weekends
  if (rDays) {

    // Adjust for start on weekend, end any day
    if (startDay == 6) {
      rDays -= 1;
    } else if(startDay == 5) {
      rDays -= (rDays == 1)? 1 : 2;

    // Adjust for start on business day
    // and end on weekend
    } else if (endDay == 6) {
      rDays -= 1;

    // Adjust for going over whole weekend
    } else if (endDay < startDay) {
      rDays -= (rDays == 1)? 1 : 2;
    }
  }
  return bWeeks * 5 + rDays;
}

If you want to include public holidays that fall on days from Monday to Friday, you'll need another function that uses a calendar of public holidays and returns how many fall on business days between the subject dates. There might also be holidays for specific industries, professions, religions and so on.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜