1

When comparing two dates, how do I get the difference between two date objects in DAYS? (for example - 2017-07-31 and 2017-07-28 --> this should return 3 days).

UNIX timestamp will not work as it is not accurate for my case - there is no way knowing whether I should round up or down to the nearest 24hours (1 day).

getDay() function does not work inside of scoped application within ServiceNow.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • can you use moment js in your project? – nmbrphi Jan 10 '19 at 12:52
  • no. You cannot load any libraries into ServiceNow. –  Jan 10 '19 at 12:54
  • if you can only use vanilla js, maybe you can use this: var diffDays = Math.floor(( start - end ) / 86400000); Where start and end are two dates objects. – nmbrphi Jan 10 '19 at 13:01
  • can you use your custom js or not – dev_ramiz_1707 Jan 10 '19 at 13:04
  • No. only vanilla js or servicenow js (whoever is familiar with the platform). –  Jan 10 '19 at 13:06
  • @nmbrphi - thanks but does not work. I thought of this before I posted the question. –  Jan 10 '19 at 13:07
  • sorry @bystrik I've never used servicenow before... If this documentation is pertinent , I see the function DurationCalculator - calcScheduleDuration(String startTime, String endTime), have you tried this? https://docs.servicenow.com/bundle/london-application-development/page/app-store/dev_portal/API_reference/DurationCalculator/concept/c_DurationCalculatorAPI.html#r_DC-calcScheduleDuration_S_S – nmbrphi Jan 10 '19 at 13:14
  • that is fine. But as many other solutions, durationcalculator script does not run inside of scoped appilcations, only in global scope. –  Jan 10 '19 at 14:04
  • @bystrik sorry, didn't know that... last chance :D, maybe this solution in vanillajs can work: https://stackoverflow.com/a/20669357/2650704 – nmbrphi Jan 10 '19 at 14:34

3 Answers3

2

The most commonly used API available in Service Now to calculate duration is gs.DateDiff(date1, date2) but it does not work in scoped applications.

SN has provided its own APIs which can fetch the duration in a scoped app using GlideDateTime API

If your fields are date/time

var date1 = new GlideDateTime("2011-08-28 09:00:00");
var date2 = new GlideDateTime("2011-08-31 08:00:00");
var diff = GlideDateTime.subtract(date1, date2);
gs.info(diff.getDisplayValue());

If you need to refer it on any fields from a record then specify dates as

var date1 = new GlideDateTime(current.sys_created_on);
var date2 = new GlideDateTime(current.sys_updated_on);

To get the numeric difference in seconds

gs.info(diff.getNumericValue());

To subtract the duration for date fields only

diff = GlideDate.subtract(date1, date2);
gs.info(diff.getDisplayValue());
Alikutty K
  • 146
  • 3
0

Given dates in the format YYYY-MM-DD, you can use the Date constructor, subtract one from the other and divide by the number of milliseconds in one day.

The strings will be parsed as UTC, so there are no issues with daylight saving and ECMAScript has exactly 8.64e7 ms per day. Even if you need to round, daylight saving doesn't change the value by more than 1 hour (and in some places less) so rounding is fine. E.g.

var d0 = '2017-07-31';
var d1 = '2017-07-28';
var diffDays = (new Date(d0) - new Date(d1)) / 8.64e7;

console.log(diffDays);

It's generally recommended to avoid the built–in parser, however in this case it's likely OK. But for confidence, parse the strings manually, a library can help but it only requires a 2 line function.

If your dates are not created as above and are not set to midnight, you can get days between dates by setting them to midnight, subtracting and rounding, e.g.

var d0 = new Date(2017, 6, 31, 23, 15, 45); // 2017-07-31T23:15:25 local
var d1 = new Date(2017, 6, 28, 3, 15, 45);  // 2017-07-28T03:15:25 local

function diffDays(d0, d1) {
  var a = new Date(d0).setHours(0,0,0,0);
  var b = new Date(d1).setHours(0,0,0,0);
  return Math.round((a - b) / 8.64e7);
}

console.log(diffDays(d0, d1));
RobG
  • 142,382
  • 31
  • 172
  • 209
  • thanks, this is a nice vanila JS solution. For my scenario it is not a solution however, it does provide a solution for the problem I presented. That's why I vote it up. Thanks for the effort. –  Jan 16 '19 at 13:57
0

If you want to do this in say a business rule, inside a scoped application, it might look like the following (Tested in Orlando version):

(function executeRule(current, previous /*null when async*/) {

    var field_1 = new GlideDateTime(current.field_1);
    var field_2 = new GlideDateTime(current.field_2);
    current.field_duration = new GlideDuration(field_1.getNumericValue() - field_2.getNumericValue());

})(current, previous);
Greg
  • 2,410
  • 21
  • 26