- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
I'm using a client catalog script and and client callable script include to implement a requirement and avoid the selection of weekend days and holidays on a date time field on a catalog item.
I'm using the glideSchedule isInSchedule method but I'm getting a false when selecting a week day.
Here is the client script
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || !newValue) {
return;
}
// Get today's date (without time)
var today = new Date();
today.setHours(0, 0, 0, 0);
// Get the selected date
var selectedDate = new Date(newValue);
selectedDate.setHours(0, 0, 0, 0);
// Calculate 3 days in milliseconds
var threeDaysMs = 3 * 24 * 60 * 60 * 1000;
// Minimum allowed date = today + 3 days
var minAllowedDate = new Date(today.getTime() + threeDaysMs);
// First validation: 3 days rule
if (selectedDate < minAllowedDate) {
g_form.clearValue('date_required');
g_form.showFieldMsg(
'date_required', 'Date required must be 3 days (or more) from the current date.', 'error');
return;
}
// SECOND VALIDATION: business days (Mon–Fri + excluding holidays)
var ga = new GlideAjax('DateBusinessValidator');
ga.addParam('sysparm_name', 'validateAndMinDate');
ga.addParam('sysparm_schedule', 'a4f73987db2e2340917fd7795e961951'); // sys id schedule
ga.addParam('sysparm_business_days', 3);
ga.addParam('sysparm_date', newValue);
ga.getXMLAnswer(function(answer) {
console.log("DEBUG → RAW ANSWER from Script Include:", answer);
try {
var res = JSON.parse(answer);
console.log("DEBUG → Parsed response:", res);
if (!res.isBusinessDay) {
console.warn("DEBUG → FAIL: isBusinessDay = false");
g_form.clearValue('date_required');
g_form.showFieldMsg('date_required', 'Selected date must be a business day (Mon–Fri, excluding holidays).', 'error');
} else {
console.log("DEBUG → PASS: isBusinessDay = true");
}
} catch (e) {
console.error("DEBUG → JSON PARSE ERROR:", e);
g_form.showFieldMsg('date_required', 'Error validating business day.', 'error');
}
});
}Here is the Script include
var DateBusinessValidator = Class.create();
DateBusinessValidator.prototype = Object.extendsObject(AbstractAjaxProcessor, {
validateAndMinDate: function() {
// Read parameters
var scheduleId = this.getParameter('sysparm_schedule');
var minBusinessDays = parseInt(this.getParameter('sysparm_business_days'), 10);
var dateStr = this.getParameter('sysparm_date');
// DEBUG: incoming parameters
gs.info("DEBUG SI → scheduleId: " + scheduleId);
gs.info("DEBUG SI → minBusinessDays: " + minBusinessDays);
gs.info("DEBUG SI → dateStr (raw): " + dateStr);
// Load schedule
var schedule = new GlideSchedule(scheduleId);
gs.info("DEBUG SI → schedule loaded? " + (schedule ? "YES" : "NO"));
// Force selected date to 09:00:00 to avoid timezone shifting
var selected = new GlideDateTime(dateStr + " 09:00:00");
gs.info("DEBUG SI → selected (with forced time): " + selected.getDisplayValue());
gs.info("DEBUG SI → selected (internal): " + selected.getValue());
// Check if selected date is a business day
var isBusiness = schedule.isInSchedule(selected);
gs.info("DEBUG SI → isBusinessDay: " + isBusiness);
// Calculate minimum allowed business date
var now = new GlideDateTime();
now.setDisplayValue(now.getLocalDate().toString() + " 09:00:00");
gs.info("DEBUG SI → now (forced 09:00): " + now.getDisplayValue());
var minDate = new GlideDateTime(now);
// Add business time: X days * 24h * 60m * 60s * 1000ms
var ms = minBusinessDays * 24 * 60 * 60 * 1000;
schedule.add(minDate, ms);
gs.info("DEBUG SI → minBusinessDate (calculated): " + minDate.getDisplayValue());
gs.info("DEBUG SI → minBusinessDate (local only): " + minDate.getLocalDate().toString());
// Build response
var result = {
isBusinessDay: isBusiness,
minBusinessDate: minDate.getLocalDate().toString()
};
gs.info("DEBUG SI → JSON returned: " + JSON.stringify(result));
return JSON.stringify(result);
}
});
here is my Schedule of 8 to 5 weekdays excluding holidays
Scheduled entry
I believe it could be because the "When" and "To" dates are in the past, however the schedule is set to repeat every weekday repeat until is empty.
Why I'm getting a false returned when selecting a week day in this case ?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
@Ramonrdd3
once you fix that schedule entry part highlighted by me below, check this link where it has solution
Business days Issue -> response from Dave_p
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 10x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Did you get it working? You can also just use an ui policy to handle the client side date restriction.
Also it might be simpler to make an all day workday schedule instead if you don't care about the working hours. And also make it floating tz so it uses the session timezone. Or you can set timezone on the gdts
Working with times is extremely difficult in my opinion but this is what I would do if i understand your requirement correctly, although i would probably have the n days in future restriction only on the client side
var date = new GlideDateTime(),
now = new GlideDateTime(),
schedule = new GlideSchedule("6bfda72083437210557ff0d6feaad315"),
daysFromNow = 3,
inputDate = "2026-02-15",
result = {
isDaysFromNow: false,
isBusinessDay: false,
minBusinessDate: ""
};
//set times at midnight session tz
now.setDisplayValue(now.getDate())
date.setDisplayValue(inputDate + " 00:00:00");
//is date x bizdays from now
now.addDays(daysFromNow);
result.isDaysFromNow = GlideDateTime.subtract(date, now).getNumericValue() <= 0;
//is in schedule aka business day
result.isBusinessDay = schedule.isInSchedule(date);
//find start of next business day 00:00:00 in session time
var untilNext = schedule.whenNext(date) / 1000;
date.addSeconds(untilNext);
result.minBusinessDate = date.getLocalDate();
gs.info(JSON.stringify(result, null, 2));
/*
*** Script: {
"isDaysFromNow": true,
"isBusinessDay": false,
"minBusinessDate": "2026-02-16"
}
*/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
// Add business time: X days * 24h * 60m * 60s * 1000ms
var ms = minBusinessDays * 24 * 60 * 60 * 1000;
schedule.add(minDate, ms);What are you actually getting back from the server. Wouldn't this just throw server-side because add() wants a gdt and a glideduration as arguments?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hey @lauri457
i didn't notice this was an error. I was not getting a response from server actually.
I have fixed that part to use a glide duration variable now. Thanks for pointing that out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Did you get it working? You can also just use an ui policy to handle the client side date restriction.
Also it might be simpler to make an all day workday schedule instead if you don't care about the working hours. And also make it floating tz so it uses the session timezone. Or you can set timezone on the gdts
Working with times is extremely difficult in my opinion but this is what I would do if i understand your requirement correctly, although i would probably have the n days in future restriction only on the client side
var date = new GlideDateTime(),
now = new GlideDateTime(),
schedule = new GlideSchedule("6bfda72083437210557ff0d6feaad315"),
daysFromNow = 3,
inputDate = "2026-02-15",
result = {
isDaysFromNow: false,
isBusinessDay: false,
minBusinessDate: ""
};
//set times at midnight session tz
now.setDisplayValue(now.getDate())
date.setDisplayValue(inputDate + " 00:00:00");
//is date x bizdays from now
now.addDays(daysFromNow);
result.isDaysFromNow = GlideDateTime.subtract(date, now).getNumericValue() <= 0;
//is in schedule aka business day
result.isBusinessDay = schedule.isInSchedule(date);
//find start of next business day 00:00:00 in session time
var untilNext = schedule.whenNext(date) / 1000;
date.addSeconds(untilNext);
result.minBusinessDate = date.getLocalDate();
gs.info(JSON.stringify(result, null, 2));
/*
*** Script: {
"isDaysFromNow": true,
"isBusinessDay": false,
"minBusinessDate": "2026-02-16"
}
*/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Thank you for the code and the suggestions regarding the schedule.
I had tried creating one but got an error message, something about overlapping events.
I was able to figure out that today and created a 24x5 weekdays excluding holidays schedule.
After testing the isInSchedule is working as expected, for days outside of my minimun business days requirement.
The solution I've reach is a mix from the one of Ankur and yours.
Here is the code for any future developer who comes across this scenario.
Script include
var DateBusinessValidator = Class.create();
DateBusinessValidator.prototype = Object.extendsObject(AbstractAjaxProcessor, {
validateAndMinDate: function() {
try {
var response = 'false';
var dateSelected = this.getParameter('sysparm_date');
gs.info("DEBUG SI → dateSelected: " + dateSelected);
var nowDateTime = new GlideDateTime();
gs.info("DEBUG SI → nowDateTime " + nowDateTime.getValue());
var days = 2;
var duration = new GlideDuration(days * 24 * 60 * 60 * 1000);
gs.info("DEBUG SI → duration is " + duration.getDisplayValue());
var schedule = new GlideSchedule('cdd6a30d9787b2d0607250900153af40'); //24x5 weekdays excluding holidays
var finalTime = schedule.add(nowDateTime, duration);
gs.info("DEBUG SI → finalTime is " + finalTime);
var finalTimeGdt = new GlideDateTime(finalTime);
gs.info("DEBUG SI → finalTimeGdt is " + finalTimeGdt.getValue());
finalTimeGdt.setValue(finalTimeGdt.getDate() + " 23:59:00");
gs.info("DEBUG SI → finalTimeGdt set to end of day is " + finalTimeGdt.getValue());
var dateSelectedGdt = new GlideDateTime(dateSelected);
gs.info("DEBUG SI → dateSelectedGdt is " + dateSelectedGdt.getValue());
if (dateSelectedGdt < finalTimeGdt) {
response = 'true';
}
gs.info("DEBUG SI → JSON returned: " + JSON.stringify(response));
return JSON.stringify(response);
} catch (e) {
gs.info("DEBUG SI → Error on Script Include: " + e);
}
},
validateFutureWeekEndDaysAndHolidays: function() {
try {
//gs.info("DEBUG SI → validateFutureWeekEndDaysAndHolidays started ");
var response = 'false';
var glideTime = new GlideTime();
glideTime.setValue('08:00:00');
var dateSelected = this.getParameter('sysparm_date');
//gs.info("DEBUG SI → dateSelected: " + dateSelected);
var schedule = new GlideSchedule('cdd6a30d9787b2d0607250900153af40', 'PST'); //24x5 weekdays excluding holidays
var dateSelectedGdt = new GlideDateTime(dateSelected);
dateSelectedGdt.add(glideTime);
//gs.info("DEBUG SI → date value : " + dateSelectedGdt.getValue());
//gs.info("DEBUG SI → date display value : " + dateSelectedGdt.getDisplayValue());
//is in schedule aka business day
response = schedule.isInSchedule(dateSelectedGdt);
//gs.info("DEBUG SI → isInSchedule : " + response);
return JSON.stringify(response);
} catch(e){
gs.info("DEBUG SI → Error on Script Include: " + e);
}
},
type: 'DateBusinessValidator'
});In here the first funcion allows me to validate if the selected date is within 2 business days or less. It's only allowed a date of 3 business days or more.
Second function allows me to validate if the selected date is a business day, necessary when outside my minium time range of 2 business days.
There room for much improvements but enough time has been put in this requirement and others are in line. There is also a concern regarding timezone, but I'll do a final test today and check that.
Thanks a lot for your assistance !

