Dates on the client side in ServiceNow have always been challenging. Javascript has its own complexities in this regard and mixing this with ServiceNow’s date formats and user preferences can make it a nightmare.
Here we walk through some of the methods of working with client side dates that make it MUCH simpler and allow us to avoid the situation of having to return to the server via GlideAjax for most, if not all, date calculations.
If you’re here as a reference and just need the key code snippets, here you go. Basically, to get a javascript date from a ServiceNow date field value do this:
var my_date = new Date(date_number);
Or, from a Date/Time field do this:
var my_date = new Date(date_number);
The Details
Working with dates on the client side of things in ServiceNow has always been a challenge. Part of this is just due to Javascript and the challenges associated with dates and the other is ServiceNow. Given that users can have their own date format makes it even more challenging. That said, we are given some tools (albeit undocumented ones) that can help improve the situation.
I ran across some information a while back (thanks to John Roberts) that helps the situation drastically. The key comes down to a couple global variables defined by the system as well as function that helps use those variables.
The variables give us the date and datetime formats for the logged in user, and the function lets us use those to get something we can work with a little easier.
User datetime format: g_user_date_time_format
User date format: g_user_date_format
These used with the getDateFromFormat function gives us an easy way to get a value for the date (essentially a Unix Timestamp). That value can then be used directly or immediately passed into a Javascript Date object to allow for reformatting, testing, or whatever else is needed.
Here are a few functions that I put together to simplify the date validation process that is so often needed.
Test for valid DateTime based on user format:
if(value == '' || value == undefined || value == null){
return false;
}
return(getDateFromFormat(value, g_user_date_time_format) != 0);
}
Test for valid Date based on user format:
if(value == '' || value == undefined || value == null){
return false;
}
return (getDateFromFormat(value, g_user_date_format) != 0);
}
To take this a step further, you could easily add comparisons of dates or add custom date formats based on the values.
One thing to keep in mind with this, depending on where the date is coming from you may still have two date formats. Any of the dates that will work as shown are going to be the values in fields on a form or the Display Value of the date. If you’re getting something from the server (e.g. via GlideAjax) as just a value then it will be stored in the regular system format of YYYY-MM-DD HH:MM:SS.
An additional example suggested by a co-worker (thank Thomas) to validate that the date is within an hour
if (isLoading || newValue == '') {
return;
}
//To change the date range from 1 hour, change var minutes_from_now to desired amount time
var minutes_from_now = 60;
var date_obj = new Date(getDateFromFormat(newValue, g_user_date_time_format));
var future_date = new Date(new Date().getTime() + minutes_from_now*60000);
if(future_date < date_obj){
alert("Time is too far out");
}
}
Hopefully this helps save you some of the frustration I’ve experienced over the years when dealing with client side dates in ServiceNow.
This is really a cool cheat sheet kind of information to be handy always… when ever you are having users in multiple time zones and multiple time formats…
Thanks, James. Very handy.
But getDateFromFormat doesnt work on service portal . is there any alternativ for it to run on service portal
Unfortunately, I haven’t found a great solution for Service Portal yet. I think it’d be a great enhancement request to ServiceNow to add support back in. If I can find something I’ll post it here.
Looks like a basic implementation of moment.js is available in service portal, however this only works from service portal and not the backend.
By default the format of the date component is incorrecnt and will need to be converted to uppercase to work with moment.js. You could do something like this which should work.
var dateFormat = g_user_date_format.toUpperCase();
// get the full date time format
var dateTimeFormat =g_user_date_time_format;
// construct correct date time format where we strip the date and use the upcase version
var newDateTimeFormat = dateFormat + dateTimeFormat.substring(dateFormat.length);
//create date object using moments and correct date time format
var dateObj = moment(g_form.getValue(‘the_date_field’), newDateTimeFormat);