How to: Set seconds to 00 and round to quarter hour for date time then add duration to get end time

Zach Wehrli
Tera Contributor

I wanted to share this script after many google searches and combining different solutions. 

Hope this helps someone else out there!

 

My base need was:

I wanted to have my users select the start date and time and input the duration so I could add them and set the end date and time from that. I also wanted to automatically round the minutes to the nearest quarter hour and set the seconds to 00 for the start time.

 

For the duration field, I wanted to remove or hide the seconds since we didn't want them. This wasn't possible since it requires DOM manipulation(not recommended by ServiceNow) or changing a global setting for your ServiceNow instance, which I didn't want to change a setting that we may need later.

What I ended up doing was simply ignoring the 'seconds' field when adding the duration to my start time.

 

Here is the post that leads me to my solution:

https://www.servicenow.com/community/developer-forum/sum-of-start-date-and-duration-field-into-end-d...

Got the math for rounding quarter hours from here:

https://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quarter-hour-in-javascr...

 

Below is the client script I used to set seconds to 00 and round the minutes to the nearest quarter hour, then add the duration field to that to set the end date and time field.

This should give a base to start from if your need is similar but not exact.

The script here is set as onChange for my start date field.

For my duration field, I used the same thing but remove the round seconds and minutes section at the top.

 

EDIT: I found an issue with my code that after submission, all times were set to 12:00 AM regardless of selection.

I've updated the scripts to ensure the proper date/time format is passed. 
I've also set it up to use an onLoad script to store my functions then simply call those functions from an onChange script tied to my start time and duration fields.

 

Here is the onLoad script:

 

function onLoad() {
    //Type appropriate comment here, and begin script below

}

checkTimeRoundness = function() {
    startDateTime = new Date(g_form.getValue("planned_start_date"));
    min = startDateTime.getMinutes();
    sec = startDateTime.getSeconds();
    if (sec != '0') {
        roundStartTime();
    } else if (min != '0' && min != '15' && min != '30' && min != '45') {
        roundStartTime();
    }
};

roundStartTime = function() {
    // Rounds seconds to 00 and minutes to nearest quarter hour
    startDateTime = new Date(g_form.getValue("planned_start_date"));
    roundedMinutes = ("0" + (((startDateTime.getMinutes() + 7.5) / 15 | 0) * 15) % 60).slice(-2);
    roundedHour = ((((startDateTime.getMinutes() / 105) + .5) | 0) + startDateTime.getHours()) % 24;
    startDateTime.setSeconds('00');
    startDateTime.setMinutes(roundedMinutes);
    startDateTime.setHours(roundedHour);
    dtSDT = formatDate(startDateTime, g_user_date_time_format); //This converts the date into the proper format before setting the value
    g_form.setValue("planned_start_date", dtSDT);
};


updateEndTime = function() {

        if (g_form.getValue('planned_start_date') != '' && g_form.getValue('duration') != '') {
            startDate = new Date(g_form.getValue("planned_start_date"));
            endDate = new Date(g_form.getValue("planned_start_date"));
            duration = g_form.getValue("duration");
            days = parseInt(duration.split(" ")[0]);
            hours = parseInt(duration.split(" ")[1].split(":")[0]);
            minutes = parseInt(duration.split(" ")[1].split(":")[1]);
            seconds = parseInt(duration.split(" ")[1].split(":")[2]);
            totalSeconds = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + 0; //replaced the 'seconds' var ref with a 0 at the end to ignore any entered seconds in the duration field
            if (totalSeconds < 1800) {
                //increase minutes to minimum 30 minutes
                minutes = '30';
                totalSeconds = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds;
                //g_form.setValue("minutes", minutes); //cannot change the display value of duration field
                g_form.showFieldMsg('duration', "Though the field does not reflect the increase, the duration has been increased to a minimum value of 30 minutes. You can still change the value to higher if needed.", 'error'); //to show blue text
            }
            endDate.setSeconds(startDate.getSeconds() + totalSeconds);
            dtEDT = formatDate(endDate, g_user_date_time_format); //This converts the date into the proper format before setting the value
            g_form.setValue("planned_end_date", dtEDT);
        }
};

 

 

And your onChange script should look something like this:

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }

   // Round the time to nearest quarter hour and set seconds to 0
    checkTimeRoundness();

    // Update the end date if both start date and duration are set.  Also ensures a minimum of 30 minutes duration
    updateEndTime();
	
}

 

0 REPLIES 0