Interested in a ServiceNow event built for developers? Registration for now[dev]26 is officially open!

planned_end_date value returned in Client Script differs from displayed value on Change Task form

Sirri
Kilo Sage

Hi Team,

I am working on a Client Script on the Change Task table to make the field "Reason for Late Task Closure" mandatory when a task is closed after the Planned End Date.

The script is triggered on the State field change and compares the current date/time with the planned_end_date value.

On Change Client script (on state Field):
var CLOSED_STATE = "3";

var plannedEnd = g_form.getValue("planned_end_date");

if (!plannedEnd) {
g_form.setMandatory("u_reason_for_late_task_closure", false);
g_form.setDisplay("u_reason_for_late_task_closure", false);

return;
}

// Convert ServiceNow date (25/Jul/2025 18:00:00) to JavaScript Date
var planned = parseSNDate(plannedEnd);
var now = new Date();

// Debugging
//alert("State : " + newValue);
//alert("Planned : " + planned);
//alert("Now : " + now);

if (newValue == CLOSED_STATE && now.getTime() > planned.getTime()) {

//alert("Condition TRUE");

g_form.setDisplay("u_reason_for_late_task_closure", true);
g_form.setMandatory("u_reason_for_late_task_closure", true);

} else {

//alert("Condition FALSE");
g_form.setMandatory("u_reason_for_late_task_closure", false);
g_form.setDisplay("u_reason_for_late_task_closure", false);

}
}

// Function to convert 25/Jul/2025 18:00:00 to JavaScript Date
function parseSNDate(dateStr) {

var months = {
Jan: 0,
Feb: 1,
Mar: 2,
Apr: 3,
May: 4,
Jun: 5,
Jul: 6,
Aug: 7,
Sep: 8,
Oct: 9,
Nov: 10,
Dec: 11
};

var parts = dateStr.split(' ');

var d = parts[0].split('/');
var t = parts[1].split(':');

return new Date(
parseInt(d[2], 10), // Year
months[d[1]], // Month
parseInt(d[0], 10), // Day
parseInt(t[0], 10), // Hour
parseInt(t[1], 10), // Minute
parseInt(t[2], 10) // Second
);

 

Observation

I noticed that the value returned from:

g_form.getValue('planned_end_date')



is different from the value shown on the form.

Example:

Value displayed on form

11/Sep/2026 08:20:19

Value returned in script/XML
2026-09-11 05:20:19

The instance timezone is configured as:
Asia/Riyadh (UTC+3)

Because of this difference, the date/time comparison is not behaving as expected, and the mandatory field validation is firing inconsistently.

Questions

  1. Why does g_form.getValue('planned_end_date') return a different value than what is displayed on the form?
  2. Is the returned value always in UTC/internal format while the form shows the user's timezone-adjusted value?
  3. What is the recommended approach for comparing a Date/Time field with the current date/time in a Client Script?
  4. Should g_form.getDisplayValue(), GlideDateTime, or another approach be used to ensure accurate time comparisons?

Please fix this code as per my requirement & provide the correct one. 

Any guidance or best practices would be appreciated.

Thank you.




3 REPLIES 3

Brad Bowman
Mega Patron

I would try a low code approach by using a scripted UI Policy instead of this client script

https://www.servicenow.com/community/developer-articles/no-code-date-validations-through-catalog-ui-... 

 

If you want/need to stick with the Client Script, here is a format that I have used:

var currentDateObj = new Date();
		var currentDateStr = formatDate(currentDateObj, g_user_date_format);
		var currentDate = getDateFromFormat(currentDateStr, g_user_date_format);
		var endDate = getDateFromFormat(g_form.getValue('v_end_date'), g_user_date_time_format);
		var startDate = getDateFromFormat(g_form.getValue('v_start_date'), g_user_date_time_format);

		//prevent start date less than 15 minutes from now
		if (startDate - currentDate < 900000) {
			alert('Start Date must be at least 15 minutes from now.');
			g_form.clearValue('v_start_date');
		}
    
		//prevent end date less than 30 minutes ahead of start date
		if (endDate - startDate < 1800000) {
			alert('End Date must be at least 30 minutes from Start Date.');
			g_form.clearValue('v_end_date');
		}

@Brad Bowman  ,


This Case & my case is different can you re check & provide the script as per my case.

thank you

Deėpak Sharma
Mega Sage

hi @Sirri 

Questions

  1. Why does g_form.getValue('planned_end_date') return a different value than what is displayed on the form?
    Ans: g_form.getValue('planned_end_date') fetches the raw value stored in the database. ServiceNow stores all Date/Time fields in the standard format (YYYY-MM-DD HH:mm:ss) and in the UTC time zone only, regardless of the user's localized settings.
  2. Is the returned value always in UTC/internal format while the form shows the user's timezone-adjusted value?
    Ans:Yes.
  3. What is the recommended approach for comparing a Date/Time field with the current date/time in a Client Script?
    Ans:The cleanest client-side approach is to fetch the UTC value using g_form.getValue and then parse that specific YYYY-MM-DD HH:mm:ss string into a JavaScript Date object using Date.UTC(), and compare it against new Date.
  4. Should g_form.getDisplayValue(), GlideDateTime, or another approach be used to ensure accurate time comparisons?
    Ans: Do not use getDisplayValue() for comparisons.

 

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

    var CLOSED_STATE = "3";
    if (newValue != CLOSED_STATE) {
        g_form.setMandatory("u_reason_for_late_task_closure", false);
        g_form.setDisplay("u_reason_for_late_task_closure", false);
        return;
    }
    var plannedEnd = g_form.getValue("planned_end_date"); 
    if (!plannedEnd) {
        g_form.setMandatory("u_reason_for_late_task_closure", false);
        g_form.setDisplay("u_reason_for_late_task_closure", false);
        return;
    }

    var plannedDate = parseServiceNowUTC(plannedEnd);
    var now = new Date();

    if (now.getTime() > plannedDate.getTime()) {
        g_form.setDisplay("u_reason_for_late_task_closure", true);
        g_form.setMandatory("u_reason_for_late_task_closure", true);
    } else {
        g_form.setMandatory("u_reason_for_late_task_closure", false);
        g_form.setDisplay("u_reason_for_late_task_closure", false);
    }
}

function parseServiceNowUTC(dateStr) {
    var parts = dateStr.split(' ');
    var d = parts[0].split('-');
    var t = parts[1].split(':');
    return new Date(Date.UTC(
        parseInt(d[0], 10),     // Year
        parseInt(d[1], 10) - 1, // Month 
        parseInt(d[2], 10),     // Day
        parseInt(t[0], 10),     // Hour
        parseInt(t[1], 10),     // Minute
        parseInt(t[2], 10)      // Second
    ));
}

 

Happy to help! If this resolved your issue, kindly mark it as the correct answer ✅  and Helpful and close the thread 🔒 so others can benefit too.

Warm Regards,

Deepak Sharma

Community Rising Star 2025