Scheduling Monthly Reports on the First Working Day in ServiceNow

Sushma Pavani K
Tera Guru

Scenario:
You want to schedule a report to run every month—but specifically on the first working day of the month. This means:

  • If the 1st of the month is a weekday (Mon-Fri), run the report on that day.

  • If the 1st is a weekend (Saturday or Sunday), run the report on the next Monday.

  • Additionally, if the 2nd or 3rd is a Monday (because the 1st was on a weekend), run the report then.

Why is this important?

In many business scenarios, reports must be generated at the start of the month but only during working days to avoid non-business hours delays. Simply scheduling on the 1st isn’t sufficient if it falls on a weekend.

 

How to implement this logic in a Scheduled Script Execution?

You can use GlideDateTime along with some day-of-week and day-of-month checks in your scheduled job condition script.

Here’s a sample condition script that evaluates whether "today" is the first working day:

var now = new GlideDateTime();
var day = now.getDayOfMonth(); // Day of the month (1-31)
var weekDay = now.getDayOfWeek(); // Day of the week (1=Sunday, 7=Saturday)

var answer = false;

if (day == 1 && weekDay != 7 && weekDay != 1) { // 1st day & not Sunday(1) or Saturday(7)
answer = true;
} else if (day == 2 && weekDay == 2) { // 2nd day & Monday(2)
answer = true;
} else if (day == 3 && weekDay == 2) { // 3rd day & Monday(2)
answer = true;
} else {
answer = false;
}

answer;

 

 Screenshot 2025-06-20 at 4.36.10 PM.png

Explanation:

  • getDayOfMonth() returns the current day number.

  • getDayOfWeek() returns the weekday number (Sunday = 1, Monday = 2, ..., Saturday = 7).

  • We check:

    • If it’s the 1st and a weekday (Mon-Fri, i.e., day of week not Sunday or Saturday),

    • Or the 2nd or 3rd and Monday (to catch weekends).

If any condition matches, the scheduled job runs the report.


How to Use:

  1. Navigate to System Scheduler > Scheduled Jobs.

  2. Create a new Scheduled Script Execution.

  3. Set the Run schedule to Daily at your preferred time.

  4. Add the above condition script in the Condition field.

  5. Add your report generation code in the script section or call a report run API.

This setup ensures the report only executes on the first working day, no matter if the month starts on a weekend.


Bonus: Handling holidays

For organizations with holidays beyond weekends, you might extend this logic by integrating a holiday calendar (custom table) and checking if the current day is a holiday to skip it.

 

Summary

By leveraging GlideDateTime and weekday/day-of-month checks in your scheduled job conditions, you can automate reports to run precisely on the first working day each month. This improves business continuity and data availability without manual intervention.

1 REPLY 1

danmjunqueira
Kilo Guru

Great article, this solves a very practical scheduling challenge that many teams face in ServiceNow reporting.

The use of GlideDateTime for evaluating weekday and day-of-month logic is clean and reliable. I appreciate how the script accounts for weekends that fall on the 1st, 2nd, or 3rd and routes execution to the next valid working day.

Here’s a point of view and one valuable enhancement:

While the script does an excellent job of navigating weekends, business calendars often include holidays that aren’t weekends, like national holidays or company-specific days off. In many enterprises, delivering reports on such days could be misleading or go unnoticed by stakeholders, especially if those reports are time-sensitive (e.g., financial or operational summaries).


Suggested Enhancement: Integrate a Holiday Calendar
To make this script truly production-grade for enterprise use, consider integrating a Holiday Table, where you store recognized non-working days (outside weekends).

Here's how to extend the script:

var now = new GlideDateTime();
var day = now.getDayOfMonth();
var weekDay = now.getDayOfWeek(); // 1=Sunday, 7=Saturday
var today = now.getDate().getValue(); // Format: YYYY-MM-DD

var grHoliday = new GlideRecord('your_holiday_table'); // Create a custom table if needed
grHoliday.addQuery('date', today);
grHoliday.query();

var isHoliday = grHoliday.hasNext();
var isWeekday = (weekDay >= 2 && weekDay <= 6);
var answer = false;

if (!isHoliday) {
if (day == 1 && isWeekday) {
answer = true;
} else if ((day == 2 || day == 3) && weekDay == 2) {
answer = true;
}
}

Thanks for sharing, this kind of practical ServiceNow content really empowers admins and developers to build intelligent automation!