How can I subtract time from a date? The Schedule class ignores negative durations.

gflewis
Kilo Expert

I am trying to use the Schedule class (Packages.com.glide.schedules.Schedule) to compute a catalog task due date. I already have the requested item due date, and I am trying to subtract a certain number of business days from it to compute the task due date. For example: the requested item due date was supplied by the requestor and a particular task is due 2 business before this date. When using the GlideDateTime class, you can simpy add a negative number of seconds and it works as expected. However, this does not take into account the business calendar. The Schedule class takes into account the business calendar, but it only works when adding a positive duration. If you pass in a negative duration it treats it as zero.

Does anyone know a way to subtract a duration from a date within the confines of a Schedule?

3 REPLIES 3

Not applicable

Unfortunately it doesn't currently support subtracting time.


sdarity1
Tera Contributor

Hi,



I also ran into the same issue when I needed to calculate a date that was days prior to another date using only the Business Hours that are available in the "8-5 weekdays excluding holidays" Schedule.   Adding Time to a date to calculate a future date or due date using a Schedule is easy.   However, subtracting time from a date to calculate a previous date using a Schedule posed a challenge.   I quickly found out that the add time method does not work with negative numbers when calculating a date using a Schedule.



I created the following 'ScheduleUtils' Class that utilizes the DurationCalculator() Class with Two(2) Methods addDaysInSchedule(scheduleName,   startDate, daysForward) and subDaysInSchedule(scheduleName,   startDate, daysBack) that have the ability to create a date by adding or subtracting time in a schedule.



var ScheduleUtils = Class.create();
ScheduleUtils.prototype = {



// Init
initialize: function() {
  //Control Constants
  this.limitDaysBack = 100;
},



/*
  * This function goes days forward in a schedule.
  *
  * Parameters:
  *   scheduleName: String, Name of the Schedule
  *   startdate: GlideDateTime, Start Date
  *   daysForward: Int, Days to go forward
  *
  * Return value:
  *   GlideDateTime, Date in the Schedule with daysForward
  */



addDaysInSchedule:   function(scheduleName,   startDate, daysForward){
  //Get a schedule by name to calculate the check
  var schedRec = new GlideRecord("cmn_schedule");
  schedRec.get("name", scheduleName);
  //Get date/time in correct format for duration calculation
  var startDateBeg = new GlideDateTime();
  startDateBeg.setValue(startDate);
  startDateBeg = startDateBeg.getDate();
 
  var dc = new DurationCalculator();
  dc.setSchedule(schedRec.sys_id);
 
  dc.setStartDateTime(startDateBeg);
  dc.calcDuration(daysForward*9*3600);
 
  return dc.getEndDateTime().getDate();
},



/*
  * This function goes days back in a schedule.
  *
  * ATTENTION:
  *       This function works with a looping approach.
  *       It goes back day by day and calculates the duration in a schedule.
  *       Accuracy is on day basis
  *       If the duration is large enough, it returns the date/time.
  *       The max Days could be limited, to avoid infinite loops.
  *
  * Parameters:
  *   scheduleName: String, Name of the Schedule
  *   startdate: GlideDateTime, Start Date
  *   daysBack: Int, Days to go back
  *
  * Return value:
  *   GlideDateTime, Date in the Schedule with daysBack
  */



subDaysInSchedule:   function(scheduleName,   startDate, daysBack){
  //Get a schedule by name to calculate the check
  var schedRec = new GlideRecord("cmn_schedule");
  schedRec.get("name", scheduleName);
  //Get date/time in correct format for duration calculation
  var endDate = new GlideDateTime();
  var startDateBeg = new GlideDateTime();
  startDateBeg.setValue(startDate);
  startDateBeg = startDateBeg.getDate();
  endDate.setValue(startDateBeg);
 
  var dc = new DurationCalculator();
  dc.setSchedule(schedRec.sys_id);
 
  // Max 100 Days, just if loop does not find a slot in the schedule
  var limitHoursBack = this.limitDaysBack*9; // 9-Hours = 1-Business Day
  for (var i=0; i<limitHoursBack; i++){
    //Substract hour by hour
    endDate.addSeconds(-3600); //1hour = 60sec * 60min
   
    //Calculate Duration
    var duration = dc.calcScheduleDuration(endDate, startDateBeg);
   
    //If we went enough hours back, quit
    if (duration/32400 >= daysBack){ // 32400 Seconds = 9-Hours = 1-Business Day
      break;
  }
}



return endDate.getDate();
},


type: 'ScheduleUtils'
};




Here is the 'Subtract' Days Sample Code that uses the 'ScheduleUtils" Class that you can run in Scripts - Background Window To Try It Out.



executeSample();


function executeSample(){


    var su = new ScheduleUtils();


    var myDate = su.subDaysInSchedule("8-5 weekdays excluding holidays", "2017-04-09 23:59:00", 5);


    gs.print("MyDate = " + myDate);


}



Output Result: *** Script: MyDate = 2017-04-03



Here is the 'Add' Days Sample Code that uses the 'ScheduleUtils" Class that you can run in Scripts - Background Window To Try It Out.




executeSample();


function executeSample(){


    var su = new ScheduleUtils();


    var myDate = su.addDaysInSchedule("8-5 weekdays excluding holidays", "2017-04-09 23:59:00", 5);


    gs.print("MyDate = " + myDate);


}




Output Result: *** Script: MyDate = 2017-04-14


Dominique3
Mega Contributor

Hi gflewis,

 

I was able to do that, converting the date on the condition to a string. I used an script include to test if it is a business day or not, and called it back on my schedule script. It works perfectly!

You can check it here: How to get 2 business day before a selected date?

 

Best regards,