Calculate Business Days

Ken Pruitt
Tera Contributor

Hello Community,

I need to calculate 10 business days in the future from any given date. I'm using the script below but it is not counting business days, it is just counting 10 days out which is incorrect. How do I calculate the date 10 business days out?

getbusinessdays : function getbusinessdays(date, numberOfDays) {
		var schedule = "968d3fbe1b35b3408ed610ad2d4bcbd";
		
		var glideSchedule = new GlideSchedule();
		glideSchedule.load(schedule);
		
		var start = new GlideDateTime();
		start.setDisplayValue(date);
		
		var actualNumberOfDays = 0;
		
		if(glideSchedule.isInSchedule(start)){
			for(var x = 0; x < numberOfDays; x++){
				start.addDays(1);
				
				if(glideSchedule.isInSchedule(start)){
					actualNumberOfDays++;
				}
				else{
					if(start.getDayOfWeek() == 6){
						start.addDays(2);
						actualNumberOfDays++;
					}
					else if(start.getDayOfWeek() == 7){
						start.addDays(1);
						actualNumberOfDays++;
					}
				}
			}
			return start;
		}
		else{
			if(start.getDayOfWeek() == 6){
				start.addDays(2);
				actualNumberOfDays++;
			}
			else if(start.getDayOfWeek() == 7){
				start.addDays(1);
				actualNumberOfDays++;
			}
			if(glideSchedule.isInSchedule(start)){
				for(var y = 0; y < numberOfDays; y++){
					start.addDays(1);

					if(glideSchedule.isInSchedule(start)){
						actualNumberOfDays++;
					}
					else{
						if(start.getDayOfWeek() == 6){
							start.addDays(2);
							actualNumberOfDays++;
						}
						else if(start.getDayOfWeek() == 7){
							start.addDays(1);
							actualNumberOfDays++;
						}
					}
				}
			}
			return start;
		}
    },
31 REPLIES 31

@Hitoshi Ozawa thank you for that input, it is very helpful. I got consistent results in the correct timezone. One thing that stands out to me. In the client script, the number of days is set to 1. This works fine when the duration is 10 days. If I change the duration to 5 days, it does not behave the same. What is the equivalent value for 5 days? .5?

My bad. Forgot to fix it back after testing. "numberOfDays" is suppose to be numbers of days to set. To be 5 days after, set "numberOfDays" to 5 in the client script.

The reason the calculation doesn't work sometimes in different time zone seems to be caused by deviation cause by rounding in internal floating point calculation. When converting GlideDate doesn't have a time so when it's converted to GlideDateTime, it sets the time to "00:00:00". The calculation sometimes pushes back the time by few millisecond. So, setting the time to be few milliseconds after midnight resolves the problem.

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    var numberOfDays = 10;  // number of business days
    try {
        var startDate = getDateFromFormat(newValue, g_user_date_format);
        startDate = new Date(startDate);
        startDate = startDate.getFullYear() + '-' + padZero(startDate.getMonth() + 1) + '-' + padZero(startDate.getDate());
        var ajax = new GlideAjax('ScheduleUtil');
        ajax.addParam('sysparm_name', 'getBusinessDate');
        ajax.addParam('sysparm_start_date', startDate);
        ajax.addParam('sysparm_days', numberOfDays);
        ajax.getXMLAnswer(function(answer) {
            if (answer.length > 0) {
                g_form.setValue('end_date', answer);
            }
        });
    } catch (e) {
        alert(e.message);
    }

    function padZero(str) {
        return ('00' + str).slice(-2);
    }
}

Script Include:

var ScheduleUtil = Class.create();
ScheduleUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    getBusinessDate: function() {
        try {
            var startDate = this.getParameter('sysparm_start_date');
            var numberOfDays = this.getParameter('sysparm_days');
			startDate += ' 00:00:10';

            gdtStartDate = new GlideDateTime();
			gdtStartDate.setDisplayValue(startDate);
            var dur = new GlideDuration(60 * 60 * 24 * 1000 * numberOfDays);
            var sched = new GlideSchedule('b4560c4597d1011086d3b4b3f153afc1');
			
            var gdtEndDate = sched.add(gdtStartDate, dur);
			return gdtEndDate.getLocalDate();
        } catch (e) {
            return e.message;
        }
    },
    type: 'ScheduleUtil'
});

Hitoshi,

Thank you for the input. I have it working now but i'm trying to understand why it's returning me weekend days in the result. For example, if I choose April 2nd, it's returning me April 9th (5 business days). This should be validating against weekdays only. Could this be a calendar configuration problem?

find_real_file.png 

Ken Pruitt
Tera Contributor

This works for a specific timezone so far but i'm seeing strange behavior for users without a timezone populated on their User[sys_user] profile. I am forcing the 'US/Pacific' timezone in the script but it's still recognizing Monday as day 7 via .getDayOfWeek() method on the date being returned. In line with this, When I select any Monday as a start date, it returns a Saturday as the end date which is not in the schedule.

 

Has anyone experienced this weird behavior where the system is recognizing the days of week incorrectly? Monday should be day 2 or day 1 by configuration, not day 7. 

 @Ken Pruitt 

Did you ever get this figured out?

I'm using the first example from @Gunjan Kiratkar and am seeing the 'short a day' results as well, but I think it's due to the offset from UTC?