Compare date fields in a business rule

It is possible to compare two date fields or two date and time fields in a business rule, and abort a record insert or update if they are not correct.

For example, you may want a start date to be before an end date. The following is an example script:

if ((!current.u_date1.nil()) && (!current.u_date2.nil())) { 
  var start = current.u_date1.getGlideObject().getNumericValue(); 
  var end = current.u_date2.getGlideObject().getNumericValue(); 
  if (start > end) {
    gs.addInfoMessage('start must be before end');
    current.u_date1.setError('start must be before end') ;
 } }

This example has been tested in global scripts, and may need changes to work in scoped scripts. In addition to possibly needing API changes, security is more strict in scoped scripts.

As a good practice, make the business rule a before rule for insert and update actions. In the example script:
  • u_date1 and u_date2 are the names of the two date fields. Replace these names with your own field names.
  • The first line checks that both fields actually have a value.
  • The next two lines create variables that have the dates' numerical values.
  • The next two lines create different alert messages for the end user: one at the top of the form and one by the u_date1 field in the form.
  • The last line aborts the insert or update if the date fields are not correct.
Here is a more complex example of the above comparison. If you have more than one pair of start and end dates, you can use arrays as shown. Additionally, this script requires the input dates to be within a certain range, in this case, no fewer than 30 days in the past and no more than 365 days in the future.
// Enter all start and end date fields you wish to check, as well as the previous values 
// Make sure that you keep the placement in the sequence the same for all pairs 
var startDate = new Array(current.start_date,current.work_start); 
var prevStartDate = new Array(previous.start_date,previous.work_start); 
var endDate = new Array(current.end_date,current.work_end); 
var prevEndDate = new Array(previous.end_date,previous.work_end);

// The text string below is added to the front of ' start must be before end' 
var userAlert = new Array('Planned','Work');
// Set the number of Previous Days you want to check 
var pd = 30; 
// Det the number of Future Days you want to check 
var fd = 365;
// You shouldn't have to modify anything below this line
var nowdt = new GlideDateTime();
var nowMs = nowdt.getNumericValue(); 
var pdms = nowMs; 

// Subtract the product of previous days to get value in milliseconds
pdms -= pd * 24 * 60 * 60 * 1000; 
var fdms = nowMs; 

// Add the product of future days to get value in miliseconds
fdms += fd * 24 * 60 * 60 * 1000; 
var badDate = false;
 // Iterate through all start and end date / time fields 
for (x = 0; x < startDate.length; x ++) { 
  if ((!startDate[x].nil()) && (!endDate[x].nil())) { 
    var start = startDate[x].getGlideObject().getNumericValue(); 
    var end = endDate[x].getGlideObject().getNumericValue(); 
    if (start > end) {
      gs.addInfoMessage(userAlert[x] + ' start must be before end');
      startDate[x].setError(userAlert[x] + ' start must be before end');
      badDate = true; } 
    else if ((prevStartDate[x]) != (startDate[x])) { 
      if (start < pdms) {
         gs.addInfoMessage(userAlert[x] + ' start must be fewer than ' + pd + ' days ago');
         startDate[x].setError(userAlert[x] + ' start must be fewer than ' + pd  + ' days ago');
         badDate = true; } } 
    else if ((prevEndDate[x]) != (endDate[x])) { 
      if (end > fdms) {
         gs.addInfoMessage(userAlert[x] + ' end must be fewer than ' + fd + ' days ahead');
         endDate[x].setError(userAlert[x] + ' end must be fewer than ' + fd + ' days ahead');
         badDate  = true ; 
} } } } 
if (badDate == true ) {
  current. setAbortAction ( true ) ; }