Count days between two dates excluding weekends

守給你的承諾、 提交于 2019-12-11 04:50:00

问题


How can I find the difference between two dates in DB2 (excluding weekends)?

Are there any functions that will do this in DB2? Or do I need to write a query myself?


回答1:


There is AFAIK no such function. It is however easy to write a query that calculates this:

with cal(d) as ( 
    values date('2015-01-01') -- start_date 
    union all 
    select d + 1 day from cal 
    where d < '2015-01-15'    -- end_date 
) select count(case when dayofweek(d) between 2 and 6 then 1 end) 
  from cal;

If you do a lot of these kind of calculations you might want to create a calendar table, you can add attributes like national holiday etc to this table.




回答2:


This is the best way to implement difference between two dates excluding weekend means Saturday and Sunday and also excluding national holiday....

  /******
   * First, we'll extend the date object with some functionality.
   *   We'll add an  .each() function, as well as an .adjust() function.
   *   .each()  will give us the ability to loop between two dates, whether
   *     by 'day', 'week' or 'month'.
   *   .adjust() will allow us to move a given day by a given unit. This is used
   *     like so: currentDate.adjust('days', 1) to increment by one day.
   ******/
  Date.prototype.each = function(endDate, part, step, fn, bind){
  	var fromDate = new Date(this.getTime()),
  		toDate = new Date(endDate.getTime()),
  		pm = fromDate <= toDate? 1:-1,
  		i = 0;

  	while( (pm === 1 && fromDate <= toDate) || (pm === -1 && fromDate >= toDate) ){
  		if(fn.call(bind, fromDate, i, this) === false) break;
  		i += step;
  		fromDate.adjust(part, step*pm);
  	}
  	return this;
  };
  
  Date.prototype.adjust = function(part, amount){
	part = part.toLowerCase();
	
	var map = { 
				years: 'FullYear', months: 'Month', weeks: 'Hours', days: 'Hours', hours: 'Hours', 
				minutes: 'Minutes', seconds: 'Seconds', milliseconds: 'Milliseconds',
				utcyears: 'UTCFullYear', utcmonths: 'UTCMonth', weeks: 'UTCHours', utcdays: 'UTCHours', 
				utchours: 'UTCHours', utcminutes: 'UTCMinutes', utcseconds: 'UTCSeconds', utcmilliseconds: 'UTCMilliseconds'
			},
		mapPart = map[part];

	if(part == 'weeks' || part == 'utcweeks')
		amount *= 168;
	if(part == 'days' || part == 'utcdays')
		amount *= 24;
	
	this['set'+ mapPart]( this['get'+ mapPart]() + amount );

	return this;
}
  
  
/*******
 * An array of national holidays. This is used to test for the exclusion of given
 *   days. While this list is national days, you could tailor it to regional, state
 *   or given religious observances. Whatever.
 ******/
natDays = [
  {
    month: 1,
    date: 26,
    type: "national - us",
    name: "New Year's Day"
  },
  {
    month: 1,
    date: 21,
    type: "national - us",
    name: "Martin Luther King Day"
  },
  {
    month: 2,
    date: 18,
    type: "national - us",
    name: "President's Day (Washington's Birthday"
  },
  {
    month: 5,
    date: 27,
    type: "national - us",
    name: "Memorial Day"
  },
  {
    month: 7,
    date: 4,
    type: "national - us",
    name: "Independence Day"
  },
  {
    month: 9,
    date: 2,
    type: "national - us",
    name: "Labor Day"
  },
  
  {
    month: 10,
    date: 14,
    type: "national - us",
    name: "Columbus Day"
  },
  {
    month: 11,
    date: 11,
    type: "national - us",
    name: "Veteran's Day"
  },
  {
    month: 11,
    date: 29,
    type: "national - us",
    name: "Thanksgiving Day"
  },
  {
    month: 12,
    date: 25,
    type: "national - us",
    name: "Christmas Day"
  }
  
];

/******
 * This uses the national holidays array we just set, and checks a given day to see
 *   if it's in the list. If so, it returns true and the name of the holiday, if not
 *   it returns false.
 *****/
function nationalDay(date) {
    for (i = 0; i < natDays.length; i++) {
      if (date.getMonth() == (natDays[i].month-1)
          && date.getDate() == natDays[i].date) {
        return [true, natDays[i].name];
      }
    }
  return [false, null];
}

/******
 * This function takes two dates, as start and end date, and iterates through the
 *   dates between them. For each date, it checks if the current date is a week day.
 *   If it is, it then checks if it isn't a holiday. In this case, it increments
 *   the business day counter.
 ******/
function calcBusinessDays(startDate, endDate) {
  // input given as Date objects
  var iDateDiff=0, holidays = [];
    
  startDate.each(endDate, 'days', 1, function(currentDate, currentStep, thisDate){
      if(currentDate.getDay() != 0 && currentDate.getDay() != 6 ) {
        var isAHoliday = nationalDay(currentDate);
          if(!isAHoliday[0]){
            iDateDiff += 1;
          } else {
            holidays.push(isAHoliday[1]);
          }
      }
   });
   return {count: iDateDiff, holidays: holidays};

};

$(function(){
  var results, exclusions;

$( "#startDate" ).datepicker({
      defaultDate: "+1w",
      changeMonth: true,
      numberOfMonths: 3,
      onClose: function( selectedDate ) {
        $( "#endDate" ).datepicker( "option", "minDate", selectedDate );
      }
    });
    $( "#endDate" ).datepicker({
      defaultDate: "+1w",
      changeMonth: true,
      numberOfMonths: 3,
      onClose: function( selectedDate ) {
        $( "#startDate" ).datepicker( "option", "maxDate", selectedDate );
      }
    });
    $("#calculateMe").on("click", function(){
      var startDate = new Date($("#startDate").val()),
          endDate = new Date($("#endDate").val() );
      // Calculate the number of business days. This returns an object, with
      //  two members: count and holidays
      results = calcBusinessDays(startDate, endDate);
      exclusions = "Excluded weekends";
      if (results.holidays.length > 0) {
        // We have holidays, tell the user about them...
        exclusions += " and the following holidays: ";
        for(var i=0; i<results.holidays.length; i += 1){
          exclusions += results.holidays[i]+", ";
        }
      } else {
        // No holidays.
        exclusions += ".";
      }
      $("#result").text(results.count + " business days." ).append("<p>("+exclusions+")</p>");
    });
});
<div id="content">
    <input type="text" class="myDateClass" id="startDate"/>    
    <input type="text" class="myDateClass" id="endDate"/>
    <button id="calculateMe">How many business days?</button>
    <div id="result"></div>
</div>

Fiddle



来源:https://stackoverflow.com/questions/27731712/count-days-between-two-dates-excluding-weekends

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!