The CreatorCon Call for Content is officially open! Get started here.

Auto-Close Tasks within Business Hours With GlideSchedule API

Sanjay S
Tera Contributor

Have you ever wanted to automatically close tasks in ServiceNow only after a specific number of business days, based on your organization’s working hours and holiday schedule?

 

In this blog post, I’ll walk you through a real-world script I built to automatically close resolved Incident Tasks or Any Record after a configurable number of business days — not just calendar time. This script uses the GlideSchedule API to accurately track time inside working hours only (e.g., 8 AM – 4 PM, Monday–Friday, excluding holidays).

 

Use Case:

Close tasks that are in the Resolved state for more than X business days (configured via system property) based on a defined working schedule.

For example:

  • A task resolved on Friday at 4 PM will close the following Wednesday at 4 PM, assuming an 8–4, Monday–Friday schedule.

How to Implement This Script

You can implement this script in multiple ways depending on how you'd like it to run:

  1. Scheduled Script Execution (Recommended)
    Run it daily or hourly using a Scheduled Job in the background.

  2. Custom Scheduled Business Rule (Like Incident Auto-Close)
    Replicate the behavior of the OOB Incident Auto-Close mechanism by:

  3. Scheduled Trigger - Flow Designer.

Script Explained:

function autoCloseTask() {

    var endDate = new GlideDateTime(); // Fetch current date & Time to compare 
    var scheduleId = 'Sys_Id'; // your actual schedule sys_id (e.g. 8-4, UK M-F with holidays)
    var schedule = new GlideSchedule(scheduleId);
    var diffHours; // Stores the Business Hours schedule to convert total elapsed hours into business days for Auto-Close evaluation.

    var scheduleSpan = new GlideRecord("cmn_schedule_span");
    /* Fetch Schedule Entry Details for a Given Schedule. Retrieve the Schedule Entries (from the cmn_schedule_span table) associated with a specific Schedule (e.g., "8-4", "UK M–F with holidays") by including only the following details: Start Date,End Date,Business Hours. This script queries the relevant schedule by name, then fetches and lists its associated time spans with relevant scheduling information. */
    scheduleSpan.addQuery("schedule", scheduleId);
    scheduleSpan.query();
    if (scheduleSpan.next()) {

        var startTime = scheduleSpan.start_date_time.getDisplayValue();
        var endTime = scheduleSpan.end_date_time.getDisplayValue();

        var startTimeDiff = new GlideDateTime(startTime);
        var endTimeDiff = new GlideDateTime(endTime);

        var diffMillis = endTimeDiff.getNumericValue() - startTimeDiff.getNumericValue(); // difference in milliseconds
        diffHours = diffMillis / (1000 * 60 * 60); // convert to hours
    } 

    if (schedule.isInSchedule(endDate)) { // checking the current day is on the schedule

        var ps = gs.getProperty('pass the Property which will Return No.of Days'); //Fetching Auto Close property value in days
        var pn = parseInt(ps);

        var gr = new GlideRecord('Incident');
        gr.addQuery('state', 'Resolved');
        gr.addNotNullQuery('resolved');
        gr.query();
        while (gr.next()) {

            var resolvedDate = gr.resolved;
            var startDate = new GlideDateTime(resolvedDate);
            var durationDiff = schedule.duration(startDate, endDate); // Determines the elapsed time in the schedule between two date time values using the timezone of the schedule

            var timeString = durationDiff.getDurationValue(); 
           // e.g The returned value will be in the format "1 00:24:18", representing total hours converted to either {Days:Hours:Minutes:Seconds} or {Hours:Minutes:Seconds} format; for example, 1 00:24:18 equals 24.4 hours, which is approximately 3.05 days based on your Business schedule. 

            // Parse the duration string into days, hours, minutes, seconds.
            var dayPart = 0;
            var hourPart = 0;
            var minutePart = 0;
            var secondPart = 0;

            // Converting "1 00:24:18" or "00:24:18" into total hours.

            if (timeString && timeString.indexOf(" ") > -1) {
                // Case: contains days
                var parts = timeString.split(" ");
                dayPart = parseInt(parts[0], 10);

                var timeParts = parts[1].split(":");
                hourPart = parseInt(timeParts[0], 10);
                minutePart = parseInt(timeParts[1], 10);
                secondPart = parseInt(timeParts[2], 10);
            } else if (timeString && timeString.indexOf(":") > -1) {
                // Case: only time (no days)
                var timeParts = timeString.split(":");
                hourPart = parseInt(timeParts[0], 10);
                minutePart = parseInt(timeParts[1], 10);
                secondPart = parseInt(timeParts[2], 10);
            }

            // Convert to total hours (can use float if needed)
            var totalHours = (dayPart * 24) + hourPart + (minutePart / 60) + (secondPart / 3600); 
           //converts this '1 00:24:18' value into hours


            totalHours = Math.round(totalHours * 100) / 100; 
            // Round to 2 decimal places (optional)

           var totalDays = (totalHours / parseInt(diffHours));  
                  totalDays.toFixed(2);
          // Converting total hours to no.of days based on 8hrs business duration.

            if (totalDays >= pn) { //Compare totalHours value with property value 

                gr.state = 'Closed'; // state is setting to closed
                gr.active = false;
                gr.update();

            }

        }

    }
}

This script was built out of a real-world need — to ensure tasks are closed only after the appropriate amount of working time has passed, not just based on 24hours on the clock.

Hope this helps you or your team automate similar processes in a schedule-aware, business-friendly way!

Let me know your thoughts, improvements, or how you’d extend this.

 

 

 

2 REPLIES 2

Sharath Allam
Tera Contributor

Really helpful

Sharath Allam
Senior Lead Consultant, Kaptius

NeshanthA
Tera Contributor

Really helpful for this content