Client Script Date/Time Functions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-25-2011 02:33 PM
This post started out with me trying to compare glide date/time fields via client scripts, which can be a bear. Since gs. is not available in the client, I was forced to come up with other methods of manipulating these fields via a client script. Using g_form.getNumericValue(), then parsing out the year, month, day, time etc. and putting that into a new Date() javascript object was one among many options I saw. However this method does not take into account differences in date/time formats.
The method I decided to use was Asynchronous Glide Ajax. Forget the "AJAXEvaluateSynchronously" function of the past. With GlideAjax you can query for information asynchronously not preventing the browser from continuing to respond, unlike the other. Big win! So I set out to build a "ClientDateTimeUtils" script include that a glideajax script could call.
I am hoping to continue to improve these scripts, add more functionality, etc. If you have any suggestions, please let me know. A common ClientDateTimeUtils script would be nice to have.
The actual script include can be way found below. These are the functions, and an associated glideajax examples, of what you can call with this.
- getNowDateTimeDiff
This ajax function will allow you to calculate the date/time difference between a field on the form and the now date/time. You can specify a return type - "dttype" to get the result in seconds, minutes, hours, or days. See the comment below for the parameter values.
var cdt = g_form.getValue('due_date'); //First Date/Time field
var dttype = 'minute'; //this can be day, hour, minute, second. By default it will return seconds.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getNowDateTimeDiff');
ajax.addParam('sysparm_fdt', cdt);
ajax.addParam('sysparm_difftype', dttype);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
} - getDateTimeDiff
This ajax function will allow you to send in two different glide date/time fields and return a calculation of their date/time difference in seconds, minutes, hours, or days.
var cdt = g_form.getValue('due_date'); //First Date/Time field
var sdt = g_form.getValue('expected_start'); //Second Date/Time field
var dttype = 'minute'; //this can be day, hour, minute, second. By default it will return seconds.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getDateTimeDiff');
ajax.addParam('sysparm_fdt', cdt);
ajax.addParam('sysparm_sdt', sdt);
ajax.addParam('sysparm_difftype', dttype);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
} - getDateTimeBeforeNow
This ajax function will take a glide date/time field and return the amount of time till the now date/time. A positive number will represent prior to now, and negative will be how much time after now. This is pretty much a duplicate of the first one "getNowDateTimeDiff" but it gives you the opposite in positive, negative numbers. Positive = before, negative = after.
var cdt = g_form.getValue('due_date'); //first Date/Time field
var dttype = 'minute'; //this can be day, hour, minute, second. By default it will return seconds.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getDateTimeBeforeNow');
ajax.addParam('sysparm_fdt', cdt);
ajax.addParam('sysparm_difftype', dttype);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
} - getDateTimeBeforeNowBool
This ajax function will return a true or false if the date/time field is before the now date/time. This made it simpler, rather than having to do more processing on the client side, just evaluate true/false. Makes it simple.
var cdt = g_form.getValue('due_date'); //first Date/Time field
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getDateTimeBeforeNowBool');
ajax.addParam('sysparm_fdt', cdt);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
} - getNowDateTime
This function returns the date and time of right now.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getNowDateTime');
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer); - getNowDate
This function returns the date of right now.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getNowDate');
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer); - getNowTime
This function returns the time of right now.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name','getNowTime');
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer); - addDateTimeAmount
With this ajax function you can add more time to a glide date/time field. You can add seconds, minutes, hours, days, weeks, months, and years. If you want to take time away, use a negative number in the addtime variable.
Limitation:
One limitation that I have found so far is in the return date/time format. The added-to-time new date/time is returned in the standard internal date/time format. I am trying to figure out how to return it based on the user defined date/time format. Still a work in progress.
var cdt = g_form.getValue('due_date'); //Choose the field to add time from
var addtime = 3; //The amount of time to add
var addtype = 'day'; //The time type. Can be second, minute, hour, day, week, month, year.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name', 'addDateTimeAmount');
ajax.addParam('sysparm_fdt', cdt);
ajax.addParam('sysparm_addtime', addtime);
ajax.addParam('sysparm_addtype', addtype);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
//You could then take the new Date/Time answer and set the value of another field.
// g_form.setValue('expected_start', answer);
alert(answer);
} - addDateAmount
This is a function to add time to a Glide Date field. You can add days, weeks, months, or years.
var cdt = g_form.getValue('some_date'); //Choose the field to add time from
var addtime = 3; //The amount of time to add
var addtype = 'day'; //The time type. Can be day, week, month, year.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name', 'addDateAmount');
ajax.addParam('sysparm_fdt', cdt);
ajax.addParam('sysparm_addtime', addtime);
ajax.addParam('sysparm_addtype', addtype);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
} - addTimeAmount
This is a function to add time to a Glide Time field. You can add seconds, minutes, hours.
var cdt = g_form.getValue('some_time_field'); //Choose the field to add time from
var addtime = 3; //The amount of time to add
var addtype = 'day'; //The time type. Can be second, minute, hour.
var ajax = new GlideAjax('ClientDateTimeUtils');
ajax.addParam('sysparm_name', 'addTimeAmount');
ajax.addParam('sysparm_fdt', cdt);
ajax.addParam('sysparm_addtime', addtime);
ajax.addParam('sysparm_addtype', addtype);
ajax.getXML(doSomething);
function doSomething(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
}
ClientDateTimeUtils Script Include Code
I have not found that there is any limitation with the date or time formats a user may use in the calculation of the dates/times on the server. I have tested each one of these in many different timezones and date/time formats with consistent success in their calculation. The only limitation that I have found is listed above in the "addDateTimeAmount" function. i.e. The returned date/time is in the standard internal format, not the user defined format. One other point of variation would be that all of my testing was done with Glide Date/Time fields. I have not tested merely Glide Date or Time fields.
var ClientDateTimeUtils = Class.create();
ClientDateTimeUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
//Takes a Single Date/Time Field and returns its time difference from nowDateTime().
//params = sysparm_fdt (the first date/time field), sysparm_difftype (time based format to return result. See "_calcDateDiff" function comments)
getNowDateTimeDiff: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date-Time Field
var diffTYPE = this.getParameter('sysparm_difftype'); // Date-Time Type to return the answer as. Can be second, minute, hour, day
var diff = gs.dateDiff(gs.nowDateTime(), firstDT, true);
var timediff = this._calcDateDiff(diffTYPE, diff);
//return "getNowDateTimeDiff: FIRST DT: " + firstDT + " -DIFFTYPE: " + diffTYPE + " -TIME DIFF: " + timediff;
return timediff;
},
//Diff the amount of time between two different Date/Time fields
//params = sysparm_fdt (the first date/time field), sysparm_sdt (second date/time field), sysparm_difftype (time based format to return result. See "_calcDateDiff" function comments)
getDateTimeDiff: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date-Time Field
var secondDT = this.getParameter('sysparm_sdt'); // Second Date-Time Field
var diffTYPE = this.getParameter('sysparm_difftype'); // Date-Time Type to return the answer as. Can be second, minute, hour, day
var diff = gs.dateDiff(firstDT, secondDT, true);
var timediff = this._calcDateDiff(diffTYPE, diff);
//return "getDateTimeDiff: FIRST DT: " + firstDT + " -SECOND DT: " + secondDT + " -DIFFTYPE: " + diffTYPE + " -TIME DIFF: " + timediff;
return timediff;
},
//Takes your date/time field and returns the amount of time before now. A positive is time before now, a negative number is after now.
//params = sysparm_fdt (the first date/time field), sysparm_difftype (time based format to return result. See "_calcDateDiff" function comments)
getDateTimeBeforeNow: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date-Time Field
var diffTYPE = this.getParameter('sysparm_difftype'); // Date-Time Type to return the answer as. Can be second, minute, hour, day
var diff = gs.dateDiff(firstDT, gs.nowDateTime(), true);
var timediff = this._calcDateDiff(diffTYPE, diff);
//return "getDateTimeBeforeNow: FIRST DT: " + firstDT + " -DIFFTYPE: " + diffTYPE + " -TIME DIFF: " + timediff;
return timediff;
},
//Returns true if it is before now, and false if it is after now.
//params = sysparm_fdt (the first date/time field)
getDateTimeBeforeNowBool: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date-Time Field
var diff = gs.dateDiff(firstDT, gs.nowDateTime(), true);
var answer = '';
if (diff >= 0){answer = 'true';}
else {answer = 'false';}
return answer;
},
//Returns the Date/Time of right now.
getNowDateTime: function(){
var now = gs.nowDateTime(); //Now Date/Time
return now;
},
//Returns the Date right now.
getNowDate: function(){
var now = GlideDate();; //Now Date
return now.getLocalDate();
},
//Returns the Time of right now.
getNowTime: function(){
var now = GlideTime();; //Now Time
var modnow = now.getLocalTime().toString().split(' ');
return modnow[1];
},
//Takes a date/time field and adds time to it.
//params = sysparm_fdt (the first date/time field), sysparm_addtype (type of time to add - second, minute, hour, day, week, month, year), sysparm_addtime (amount of time to add based on the type).
addDateTimeAmount: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date-Time Field
var addTYPE = this.getParameter('sysparm_addtype'); //What to add - second (addSeconds()), minute (need to add conversion), hour (need to add conversion), day (addDays()), week (addWeeks()), month (addMonths()), year (addYears())
var addTIME = this.getParameter('sysparm_addtime'); //How much time to add
var day = GlideDateTime(firstDT);
if(addTYPE == 'second'){day.addSeconds(addTIME);}
else if (addTYPE == 'minute'){day.addSeconds(addTIME*60);}
else if (addTYPE == 'hour'){day.addSeconds(addTIME*(60*60));}
else if (addTYPE == 'day'){day.addDays(addTIME);}
else if (addTYPE == 'week'){day.addWeeks(addTIME);}
else if (addTYPE == 'month'){day.addMonths(addTIME);}
else if (addTYPE == 'year'){day.addYears(addTIME);}
else {day.addDays(addTIME);}
//return "First Date: " + firstDT + " -Time to Add: " + addTIME + " -Add Type: " + addTYPE + " -Added Time: " + day;
return day;
},
//Takes a glide date field and adds time to it.
//params = sysparm_fdt (the first date/time field), sysparm_addtype (type of time to add - day, week, month, year),sysparm_addtime (amount of time to add based on the type).
addDateAmount: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date Field
var addTYPE = this.getParameter('sysparm_addtype'); //What to add - day (addDays()), week (addWeeks()), month (addMonths()), year (addYears())
var addTIME = this.getParameter('sysparm_addtime'); //How much time to add
var day = GlideDate();
day.setValue(firstDT);
if(addTYPE == 'day'){day.addDays(addTIME);}
else if (addTYPE == 'week'){day.addWeeks(addTIME);}
else if (addTYPE == 'month'){day.addMonths(addTIME);}
else if (addTYPE == 'year'){day.addYears(addTIME);}
else {day.addDays(addTIME);}
//return "First Date: " + firstDT + " -Time to Add: " + addTIME + " -Add Type: " + addTYPE + " -Added Time: " + day;
return day;
},
addTimeAmount: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date-Time Field
var addTYPE = this.getParameter('sysparm_addtype'); //What
var addTIME = this.getParameter('sysparm_addtime'); //How much time to add
var time = GlideTime();
time.setValue(firstDT);
if(addTYPE == 'second'){time.addSeconds(addTIME);}
else if (addTYPE == 'minute'){time.addSeconds(addTIME*60);}
else if (addTYPE == 'hour'){time.addSeconds(addTIME*(60*60));}
else {time.addSeconds(addTIME);}
var modtime = time.toString().split(' ');
//return "First Date: " + firstDT + " -Time to Add: " + addTIME + " -Add Type: " + addTYPE + " -Added Time: " + time;
return modtime[1];
},
//Private function to calculate the date difference return result in second, minute, hour, day.
_calcDateDiff: function(diffTYPE, seconds){
var thisdiff;
if (diffTYPE == "day"){thisdiff = seconds/86400;}
else if (diffTYPE == "hour"){thisdiff = seconds/3600;}
else if (diffTYPE == "minute"){thisdiff = seconds/60;}
else if (diffTYPE == "second"){thisdiff = seconds;}
else {thisdiff = seconds;}
return thisdiff;
}
});
- 183,645 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-10-2018 09:31 AM
Hi, thanks for the reply and apologies for the delay - I haven't tried that. Can you please confirm the easiest way to enable this? Many thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-15-2018 07:02 AM
Hi all, I'm still looking for assistance on how I can set/calculate the 'Planned end date' (type: date/time) field from the values entered on a 'Planned start date' (type: date/time) field and a new/custom 'Duration' (type: duration) field. I.e. user enters the Planned start date, enters how long the change is to take and then the Planned end date is automatically calculated / set.
While I have been able to successfully set the 'Duration' value based off on 'Planned start date' and 'Planned end date' values using the 'Calculated Value' attribute on the 'Duration' field, I have not been able to set 'Planned end date' based on 'Planned start date' and 'Duration'.
Unanswered Community post here:
https://community.servicenow.com/community?id=community_question&sys_id=6aa6a486db0a57c058dcf4621f9619d5&anchor=answer_6b70f046db465fc00e3dfb651f961956
Many thanks in advance.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-16-2018 07:18 AM
I'm not sure that I can provide assistance with setting end dates based on duration (although my recommendation would be to avoid AJAX callbacks in this situation and just use a before insert business rule), but I do have some interesting information for anyone looking to compare two dates in a client script.
I've pulled this snippet out of a couple of client scripts that were set up for us by a ServiceNow engineer back when we first became customers and one of their in-house people actually helped with the initial setup/customization on our instance.
Here's the client script (we have a few that reuse this code):
/*
* onChange Client Script - change_request
* should be set to run on change of start_date and end_date
* Alert if planned end date is before planned start date
*/
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue == '') {
return;
}
var end = g_form.getValue("end_date");
var start = g_form.getValue("start_date");
// skip if start or end is blank
if (start == "" || end == "") {
return;
}
// get user's date time display format
var format = g_user_date_time_format;
var isEndBeforeStart = compareDates(start, format, end, format);
// 1 (true) if start is greater than end
// 0 if end is greater than start of if they are the same
// -1 if either of the dates is in an invalid format
if (isEndBeforeStart) {
g_form.hideErrorBox('start_date');
//g_form.setValue("start_date", "");
g_form.showErrorBox('start_date', "Planned start date cannot be greater than Planned end date");
}
}
And it is really this little snippet that does all the work:
// get user's date time display format
var format = g_user_date_time_format;
var isEndBeforeStart = compareDates(start, format, end, format);
// 1 (true) if start is greater than end
// 0 if end is greater than start of if they are the same
// -1 if either of the dates is in an invalid format
So you can go the AJAX route if you need more but it seems like for basic date field comparisons this will be much, much easier to work into a client script.
Edit: I've so far been unable to find any reference to this code in the product docs or the API docs on the developer site. It may be that there were examples of or references to this on the old Wiki docs that are no longer available.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-04-2018 05:50 AM
Hi ,
I have the same issue , on selection of Start Date End date should be populated in the form .
Validation is of One year .
This is the onChange and Script include
onChange Script :
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
//Type appropriate comment here, and begin script below
g_form.setMandatory('end_date', true);
alert('end_date');
var stDate = g_form.getValue('start_date');
alert(stDate);
var endDate = new Date(stDate);
alert(endDate);
var year1 = endDate.getFullYear();
var month = endDate.getMonth() +1 ;
var day = endDate.getDate();
var newenddate = month + "/"+ day + "/" + year1;
alert(newenddate);
var addtime = 1;
var addtype = 'year';
var time = new GlideAjax('CurrentDate');
time.addParam('sysparm_name','addDateAmount');
time.addParam('sysparm_fdt',newenddate);
time.addParam('sysparm_addtime',addtime);
time.addParam('sysparm_addtype',addtype);
time.getXML(EndDate);
function EndDate(response)
{
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
g_form.setValue('end_date', answer);
}
}
Script Include :
var CurrentDate = Class.create();
CurrentDate.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
addDateAmount: function(){
var firstDT = this.getParameter('sysparm_fdt'); //First Date Field
var addTYPE = this.getParameter('sysparm_addtype'); //What to add - day (addDays()), week (addWeeks()), month (addMonths()), year (addYears())
var addTIME = this.getParameter('sysparm_addtime'); //How much time to add
var day = new GlideDate();
day.setValue(firstDT);
gs.log("addTYPE" + addTYPE);
gs.log("addTIME" +addTIME);
if(addTYPE == 'day'){day.addDays(addTIME);}
else if (addTYPE == 'week'){day.addWeeks(addTIME);}
else if (addTYPE == 'month'){day.addMonths(addTIME);}
else if (addTYPE == 'year'){day.addYears(addTIME);}
else {day.addDays(addTIME);}
//return "First Date: " + firstDT + " -Time to Add: " + addTIME + " -Add Type: " + addTYPE + " -Added Time: " + day;
return day;
},
type: 'CurrentDate'
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-25-2018 10:45 AM
Is their any update to method #8 with the limitation that the planned end date returned value only comes through in the standard value not the user defined value? This works as mentioned, just if the returned value was right. Or is their a better way to accomplish the same thing?
