Print

One would think that the date/time data type would be cut and dry in terms of computing.  After all, programming around date/time has been a feature since the early days of digital computer systems. ServiceNow has to provide backend utilities to perform this translation since the developer cannot reach into the web server backend.  Though SN has a collection of date/time utilities, they are scant on formatting and calculation options.  You have to roll your own to compensate using the Glide library functions that SN makes available to the developer for translating a system or database stored time into a constant, generic format.  This article provides an example for how to create your own date/time utility utilizing the Glide library date/time functions.

Different operating systems handles date/time using different standards.  Databases stores date/time using even differing standards than the OS.  Aside from storing and interpreting a constant date/time, formatting the presentation can be onerous. Remember the Y2K dilemma?  In terms of open systems, date/time has been a non-event all the way around.  The value stored is the number of seconds past "epoch" (i.e. January 1, 1970) in Universal Time Code (i.e. Greenwich Meantime) and converted depending on the timezone specified in the computing environment the host is running.  Since this is expressed in integer form, time runs out, so to speak in January 2038.  Databases have their own epoch/integer system for storing date/time.  A translator to interpret a date/time is needed to present a date/time in various formats. 

On one application that I had to build, only the date itself was needed.  Defining the data dictionary was no big deal since the field was definable as a "date only".  In calculating date differences in a Business Rule, I had to role my own utilities for calculating and storing differences between two dates since the Glide calls only serviced date/time.  Below are some basic Javascript functional objects for working with date/time and passing the result to the client via Ajax.  Some are mine, some are from various sources made available in the SN community that I have collected.  The functionality is self documenting.

var AjaxUtils = Class.create();

AjaxUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

        calcDateDiff : function(start_date, end_date) {
		// This method calculates on whole days.
		// The "start day" counts as 1 day.
		
		var createdate = new GlideDateTime();
		var enddate = new GlideDateTime();
		
		// The current day is used for the endDate calculation if not provided.
		if (typeof(start_date) == 'undefined') {
			if (this.getParameter('sysparm_start_date')) {
				start_date = this.getParameter('sysparm_start_date');
			} else {
				start_date = gs.now();
			}
		}
		if (typeof(end_date) == 'undefined') {
			if (this.getParameter('sysparm_end_date')) {
				end_date = this.getParameter('sysparm_end_date');
			} else {
				end_date = gs.now();
			}
		}
		
		createdate.setDisplayValueInternal(start_date + ' 00:00:00');
		enddate.setDisplayValueInternal(end_date + ' 00:00:00');
		
		var variance = parseInt(gs.dateDiff(createdate.getDisplayValue(), enddate.getDisplayValue()).replace(/ .*/, '') );
		variance += 1;
		
		
		return variance.toString();
		
	},
	
	checkEndDate : function(startDate, endDate) {
		if(typeof(startDate) == 'undefined') {
			//startDate = new Packages.com.glide.glideobject.GlideDateTime();
			//startDate.setDisplayValue(this.getParameter('sysparm_start_date'));
			startDate = this.getParameter('sysparm_start_date');
		}
		if(typeof(endDate) == 'undefined') {
			//endDate = new Packages.com.glide.glideobject.GlideDateTime();
			//endDate.setDisplayValue(this.getParameter('sysparm_end_date'));
			endDate = this.getParameter('sysparm_end_date');
		}
		//gs.log('here:\n' + startDate + '\n' + endDate + '\n' + gs.dateDiff(startDate, endDate, true));
		return(gs.dateDiff(startDate, endDate, true) >= 0);
	},
	
	returnLeadTimeInDays : function(startDate) {
		var startDateTmp = new GlideDate();
		startDateTmp.setDisplayValue(startDate);
		
		var msStart = startDateTmp.getNumericValue();
		var msNow = new GlideDate().getNumericValue();
		var msDiff = msStart - msNow;
		var dayDiff = Math.floor(msDiff / 86400000);
		
		return(dayDiff);
	},
	
	
	checkLeadTime : function(startDate, leadTime) {
		startDate = new GlideDateTime();
		startDate.setDisplayValue(this.getParameter('sysparm_start_date'));
		leadTime = parseInt(this.getParameter('sysparm_lead_time'));
		
		var msStart = startDate.getNumericValue();
		var msNow = new GlideDateTime().getNumericValue();
		var msDiff = msStart - msNow;
		var dayDiff = Math.floor(msDiff / 86400000);
		
		return(dayDiff >= leadTime);
	},
	
	dateInFuture : function() {
		//Returns true if date is before now, and false if it is after now.
		var firstDT = this.getParameter('sysparm_fdt'); //Date-Time Field
		var diff = gs.dateDiff(firstDT, gs.nowDateTime(), true);
		var answer = '';
		new_diff = Math.floor(diff / 86400);
		if (new_diff >= 0){
			answer = 'true';
		} else {
			answer = 'false';
		}
		return answer;
	},
	
	dateInPast : function(firstDT) {
		//Returns true if date is before today, and false if it is today or later.
		if (typeof(firstDT) == 'undefined') {
			firstDT = this.getParameter('sysparm_fdt'); //Date-Time Field
		}
		var diff = gs.dateDiff(firstDT, gs.nowDateTime(), true);
		var answer = '';
		new_diff = Math.floor(diff / 86400);
		if (new_diff > 0){
			answer = 'true';
		} else {
			answer = 'false';
		}
		return answer;
	},
	
	date_timeInPast : function(firstDT) {
		//Returns true if date is before today, and false if it is today or later.
		if (typeof(firstDT) == 'undefined') {
			firstDT = this.getParameter('sysparm_fdt'); //Date-Time Field
		}
		var diff = gs.dateDiff(firstDT, gs.nowDateTime(), true);
		var answer = '';
		new_diff = Math.floor(diff / 60);
		if (new_diff > 0){
			answer = 'true';
		} else {
			answer = 'false';
		}
		return answer;
	},  type: "AjaxUtils"
});