Calculating the Difference Between Two Dates in ServiceNow
- nathanlee142
- Mar 19
- 17 min read
Updated: Apr 1

In ServiceNow development, date calculations play a crucial role in workflows and automation. Many business processes require measuring how much time has passed between two events – for example, tracking how long an incident has been open (incident age) or scheduling an action a certain number of days after a task’s start date. Accurately calculating the difference between two dates ensures that ServiceNow workflows can trigger escalations, send reminders, or compute durations for reports and SLAs. In fact, ServiceNow developers frequently encounter requirements to compare dates or compute date differences as part of client-side validations and server-side logic.
This article will explore several methods to calculate date differences in ServiceNow, focusing on client scripts and server-side Script Includes (using GlideAjax), and will also
highlight out-of-the-box solutions like Business Duration fields. We’ll provide step-by-step guidance for each approach, discuss common challenges (like time zone and schedule considerations), and outline best practices to ensure your date difference calculations are efficient and accurate.
Different Methods to Calculate Date Differences in ServiceNow
ServiceNow offers multiple ways to calculate the difference between two dates, depending on whether you want to perform the calculation on the client side (in the user’s browser) or on the server side. Below, we’ll cover the two primary custom methods – using a Client Script and using a Script Include with GlideAjax – as well as out-of-the-box (OOTB) functionalities available for certain use cases.
1. Client-Side Calculation Using Client Scripts
If you need to instantly calculate a date difference on a form (for example, when a user fills out a form and you want to display the number of days between a start date and end date), a client-side script is a straightforward solution. Client Scripts run in the browser and can respond to field changes in real-time.
How it works: You can use JavaScript Date objects in a Client Script to compute the difference between two date fields. ServiceNow’s g_form.getValue('<field_name>') method returns the value of a date or date/time field as a string. By converting these values to JavaScript Date objects, you can subtract one from the other to get the difference in milliseconds, then convert that to days or hours as needed.
For example, in plain JavaScript, you might do something like:
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue === '') {
return;
}
var startStr = g_form.getValue('start_date');
// e.g. "2023-09-01 12:00:00"
var endStr = g_form.getValue('end_date');
// e.g. "2023-09-05 08:00:00"
var start = new Date(startStr);
var end = new Date(endStr);
var diffMs = end - start;
// difference in milliseconds
var diffDays = Math.floor(diffMs / 86400000);
// 86,400,000 ms in a day
g_form.setValue('duration_days', diffDays);
}
In the snippet above, we use Math.floor(diffMs / 86400000) to get the whole number of days between the two dates. You could similarly calculate hours or minutes by adjusting the divisor. This approach is useful for simple use cases, such as populating a read-only “Number of days” field (duration_days in this example) when an end date is selected. The calculation happens immediately in the user’s browser, so it’s very responsive for the end-user.
Step-by-step guide (Client Script method):
Identify the fields you want to compare (e.g., Start Date and End Date) and the field where you want to show the result (e.g., Duration (days)).
Create a Client Script on the form’s table (or Catalog Client Script for a catalog item) with the appropriate type (often onChange of the end date field, or onSubmit if you want to validate before submission). In the script, use g_form.getValue('field_name') to retrieve the date values.
Convert the values to Date objects and compute the difference. As shown above, subtracting two Date objects yields the difference in milliseconds. Divide by the appropriate constant to get days, hours, etc. (For instance, divide by 1000*60*60*24 for days).
Handle edge cases: Check for empty values or invalid dates (e.g., if the user hasn’t filled one of the fields, or if the end date is before the start date). You might decide to prevent negative values or show a message if the dates are in the wrong order.
Update the result field or UI: Use g_form.setValue() to set the result field, or use g_form.addInfoMessage()/alert() to display the difference to the user. In our example, we set a field called duration_days.
Test the script with different scenarios (start date after end date, same day, different months, etc.) to ensure accuracy.
Using a client script for date difference is simple and does not require a round-trip to the server, but it does have limitations. For one, the calculation is based on the client’s local time interpretation of the date strings, which could lead to time zone issues if not handled carefully. ServiceNow date/time fields are stored in UTC but displayed in the user’s time zone.
When using the new Date(string) approach, the string (e.g., “2025-03-18 10:00:00”) is treated as local time by JavaScript if no time zone is specified. This means that if your users are in different time zones, the result could vary. A best practice is to ensure the format includes a time zone or, better yet, perform critical calculations on the server side where ServiceNow can handle time zone normalization via its APIs. For purely date-only fields (no time component), the time zone factor is less of an issue, but you should still be mindful if your instance serves users globally.
Performance tip: Client-side calculations are done in the browser, which is fine for one-off computations on a single form. However, if you need to compute date differences for a list of records or in batch, doing it on the client side is not efficient. In those cases, consider a server-side approach (discussed next) or computing the values in a scheduled job or business rule.
2. Server-Side Calculation Using Script Includes and GlideAjax
For more complex or heavy-duty date difference calculations, or when you need the result to be consistent regardless of client time zone, a server-side calculation is recommended. In ServiceNow, the typical way to invoke server-side logic from the client is by using GlideAjax with a Script Include. This approach is especially useful in scenarios where business logic (like working hour schedules or user-specific time zones) must be applied, or when the calculation should be reused in multiple places.
With a Script Include, you can leverage the full power of server-side APIs such as the GlideDateTime class, which is designed for date/time manipulation in ServiceNow. GlideDateTime handles UTC conversions and offers methods to compute differences directly.
How it works: You create a Script Include (marked as Client callable) containing a function (e.g., calculateDifference) that takes two dates, performs the computation on the server, and returns the result. From the client script, you use GlideAjax to call this Script Include function asynchronously and retrieve the answer.
Here’s a high-level example of using GlideAjax to calculate a date difference:
Client Script (snippet):
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue === '') {
return;
}
var startDate = g_form.getValue('start_date');
var endDate = g_form.getValue('end_date');
var ga = new GlideAjax('DateDifferenceUtils');
// Script Include name
ga.addParam('sysparm_name', 'calculateDifference');
// function name in Script Include
ga.addParam('sysparm_start_date', startDate);
ga.addParam('sysparm_end_date', endDate);
ga.getXMLAnswer(function(answer) {
// This callback runs when the server responds
if (answer) {
g_form.setValue('duration_days', answer);
// assume the script returns a numeric day count
} else {
g_form.clearValue('duration_days');
}
});
}
In this snippet, we pass the start and end dates to a Script Include called DateDifferenceUtils and specifically call the calculateDifference function within it. We use getXMLAnswer() with a callback function to handle the response asynchronously (to avoid freezing the form while waiting for the server).
Script Include (snippet):
var DateDifferenceUtils = Class.create();
DateDifferenceUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
calculateDifference: function() {
var start = this.getParameter('sysparm_start_date');
var end = this.getParameter('sysparm_end_date');
if (!start || !end) {
return 0;
// or some error indication
}
var gStart = new GlideDateTime(start);
var gEnd = new GlideDateTime(end);
var diff = GlideDateTime.subtract(gStart, gEnd);
var days = diff.getRoundedDayPart();
return days.toString();
},
type: 'DateDifferenceUtils'
});
In this server-side code, we take the two date strings from the client, convert them to GlideDateTime objects, and then use GlideDateTime.subtract(start, end) to get the difference as a GlideDuration object. We then retrieve the rounded number of days from that duration. The GlideDuration API provides methods like getRoundedDayPart() (as used above) to get the days portion of the duration. Alternatively, we could use diff.getTotalSeconds() or diff.getNumericValue() to get the raw difference (in milliseconds or another unit) and then convert to days or hours as needed.
This approach has several advantages:
Accuracy and Time Zone Handling: GlideDateTime automatically handles conversion of the input date strings to the internal UTC format. The calculation on the server is done in UTC, so the result is consistent regardless of the user’s browser locale. According to ServiceNow’s documentation and community experts, using the GlideDateTime APIs (like subtract()) is the recommended approach when working with date/time objects. In fact, the ServiceNow platform notes that if you are working with GlideDateTime objects, you should use their methods (e.g., subtract) instead of older utility functions.
Reusability: Once you have a Script Include like DateDifferenceUtils, you can call calculateDifference from any client script, UI action, or even server script if needed. This avoids duplicating logic in multiple client scripts.
Advanced Logic: On the server, you can easily incorporate additional logic. For example, you could modify the Script Include to return the difference in a format like “X days Y hours” or to calculate business hours difference (with a work schedule, as we’ll discuss later). You could also perform error handling (e.g., return a message if the end date is before the start date) and handle that response on the client.
Step-by-step guide (GlideAjax + Script Include method):
Plan your Script Include: Decide on a name (e.g., DateDifferenceUtils) and function name (e.g., calculateDifference). Determine what parameters it will need (sysparm_start_date, sysparm_end_date, etc.) and what it should return (days, hours, formatted string, etc.).
Create the Script Include in ServiceNow. Go to System Definition > Script Includes and create a new record:
Name it (e.g., DateDifferenceUtils).
Make sure Client callable is checked (this is required to call it from client scripts via GlideAjax).
Base it on AbstractAjaxProcessor (as shown above) so that you can use this.getParameter() to retrieve GlideAjax parameters.
Write the function (e.g., calculateDifference) to perform the calculation. Use GlideDateTime for date/time math. For example, you can subtract the two dates. If you want the result in days, one approach is to get the difference in milliseconds and convert to days.
For instance,
var msDiff = gEnd.getNumericValue() - gStart.getNumericValue();
var days = Math.floor(msDiff / (1000*60*60*24));
would give full days difference. You can also use GlideDuration methods like getRoundedDayPart() as in our example. (Note: GlideDateTime.subtract(gStart, gEnd) returns a GlideDuration of gEnd - gStart).
Return the result. Remember that with GlideAjax, the return value should be a string. If you have a numeric result, convert it to string (e.g., return days.toString(); or include it directly in a string).
Create the Client Script that will call this Script Include:
Choose when it should run (e.g., onChange of the end date field, or perhaps onSubmit if you want to just calculate when saving, or even a form button via UI Action).
In the client script, retrieve the date values from the form (g_form.getValue).
Initialize a GlideAjax object with the name of your Script Include. Add the required parameters including sysparm_name for the function and any data (start and end dates).
Call ga.getXMLAnswer(callbackFunction) for asynchronous processing. Inside the callback, use the answer (which is the string you returned) to update the form (set a field or display info). For example, set the duration_days field or show a message.
Alternative: If you prefer a simpler approach and the slight delay is acceptable, you can use ga.getXMLWait(); var answer = ga.getAnswer(); immediately, as shown in some community solutions.
This makes the call synchronous – the script will pause until the server responds. This is easier to script (no callback function needed; you get the answer in the next line) but be cautious with performance. A synchronous wait can freeze the user interface momentarily. It’s generally fine for quick calculations, but asynchronous (with callback) is the recommended pattern for production.
Test the end-to-end solution: Open the form, change the dates, and ensure the result field updates correctly. Test edge cases (start date after end date, same date, etc.). If the script include returns an error or “0” for invalid inputs, make sure your client script handles that gracefully (e.g., clears the output field or alerts the user).
Using GlideAjax and a server Script Include is powerful. For instance, if you later decide the difference should exclude weekends, you could modify only the server code to calculate business days difference, without touching the client script at all.
Example: The ServiceNow community provides many examples of this pattern. In one example, a user needed to ensure an “expiry date” is not earlier than a “stored date” on a form. They created an onChange Client Script that passes the two dates to a Script Include via GlideAjax, then checks the returned boolean to decide if an error message should be shown. Another example involved calculating the number of days between two dates in a catalog item; the solution used a GlideAjax call that returned the day count, which was then set to a field on the form.
On the server side, ServiceNow’s APIs make it easy to compute differences. One commonly used method in global scripts is gs.dateDiff(start, end, booleanReturnNumeric). This utility will directly return the difference between two date/time values – either as a formatted string (if the third parameter is false) or as a numeric value in seconds (if the third parameter is true). For example, gs.dateDiff(date1, date2, true) would return the difference in seconds. However, note that gs.dateDiff expects the inputs as strings in a specific date format (usually the user’s format or system format) and it is considered a legacy function. It doesn’t work in ServiceNow’s scoped applications.
The recommended practice is to use GlideDateTime methods for new developments. For instance, the code snippet below achieves a similar result using GlideDateTime:
var startGDT = new GlideDateTime(current.start_date);
var endGDT = new GlideDateTime(current.end_date);
var diff = GlideDateTime.subtract(startGDT, endGDT);
gs.info(diff.getDisplayValue());
// e.g., outputs "3 00:00:00" for 3 days difference
This example subtracts two GlideDateTime objects and then logs the difference’s display value. The getDisplayValue() on a GlideDuration (result of subtract) gives a string like ddd hh:mm:ss. If you prefer a numeric value (milliseconds), you can use diff.getNumericValue(), or if you specifically want days, use methods on GlideDuration such as getDayPart() or getRoundedDayPart() as shown earlier. The Stack Overflow community note that while gs.dateDiff was commonly used, the GlideDateTime API is more suitable for scoped apps and future-proof solutions.
Best Practice: Keep the heavy calculations on the server whenever possible. Not only does this take advantage of ServiceNow’s optimized libraries, but it also keeps the client lightweight. Use the client script mainly to pass parameters and handle the response (updating the UI). This separation of concerns makes your code easier to maintain.
3. Out-of-the-Box Solutions (Business Duration and Calendar Duration Fields)
Before writing custom scripts, it’s worth knowing that ServiceNow provides some built-in mechanisms to track durations between dates, especially in the context of task records like Incidents or Change Requests.
Two fields in particular often come up: Calendar Duration and Business Duration. These are OOTB fields that can capture the time difference between when a task is opened and when it is closed/resolved, in calendar time and business time respectively.
Calendar Duration – typically the total elapsed time between record creation and closure (in days, hours, minutes, calculated 24x7).
Business Duration – the elapsed time between creation and closure but only counting within defined business hours (as per a schedule or SLA calendar).
For example, if an incident was opened and resolved after exactly 4 days, the Calendar Duration might be 96 hours. If the business schedule is 8 hours per workday (say 9am–5pm weekdays), the Business Duration for the same incident might be 32 hours (i.e. 4 business days). These fields are populated by out-of-the-box business rules. In older versions of ServiceNow, a core business rule called “mark_closed” was responsible for calculating these upon closure of a task, using functions like gs.dateDiff and gs.calDateDiff (calendar date diff and calendar date diff with schedule).
However, it’s important to note that these legacy duration fields have evolved over time. According to ServiceNow, the Incident duration and business duration fields are now essentially considered obsolete in newer releases. They were originally used by an older SLA engine that ServiceNow has since replaced. Modern ServiceNow implementations typically use the SLA (Service Level Agreement) engine and Metrics to track durations such as “time to resolve” or “time in a certain state,” rather than relying on the static business_duration field on the record. If you have SLAs defined (e.g., an SLA for resolving an incident in 5 business hours), the SLA data will inherently measure elapsed time against a schedule.
That said, you can still leverage out-of-the-box functionality for date differences in certain scenarios:
Business Duration (Schedule) Calculation: Instead of manually writing code to exclude non-working hours, you can use the GlideSchedule API or the newer Duration Calculator API provided by ServiceNow. GlideSchedule allows you to define a schedule (e.g., Monday–Friday 9–5, excluding holidays) and then calculate the time between two DateTime values according to that schedule. For example, the snippet below demonstrates calculating business hours between two datetimes using a schedule:
var sched = new GlideSchedule('08fcd0830a0a0b2600079f56b1adb9ae', gs.getUser().getTimeZone());
// The long string above would be the sys_id of a schedule
// (e.g., your company’s business hours schedule)
var duration = sched.duration(startDate.getGlideObject(), endDate.getGlideObject());
Here, sched.duration() will return a GlideDuration representing the working time between the start and end (using the schedule with the given sys_id). You could then get the hours or days from that GlideDuration as needed. This is essentially what gs.calDateDiff did with the “default schedule,” but using GlideSchedule gives you control over which schedule to apply. ServiceNow documentation encourages using GlideSchedule (and related methods like scheduleDuration) instead of the deprecated gs.calDateDiff().
Duration Fields on Forms: If you simply need to display the elapsed time between two fields on a form, consider using a formula field or calculation field if available. For example, in some cases, administrators create a field of type “Duration” and use a business rule or client script to populate it with the difference between two other date fields. Since the Duration type in ServiceNow is stored as milliseconds (an integer) and rendered as days/hours/minutes, it’s well-suited to hold a difference value. You can calculate the value (ms difference) in a before-insert/update business rule or via the Script Include method described above, and simply set that duration field.
Reporting and Metrics: If your use case is reporting on durations (like “average time to fulfill requests” or “incident age in days”), you might not need a custom field at all. ServiceNow’s reporting can compute differences on the fly (for example, you can create a report with a formula to subtract two date fields).
Also, the Metrics feature in ServiceNow can track date differences – for instance, capturing the time when a record enters a certain state and when it leaves, then computing the difference.
Performance Analytics (if enabled) can also plot durations over time without additional scripting.
In summary, the out-of-the-box Business Duration and Calendar Duration are helpful to know about, but for new development you should carefully consider if they meet your needs or if an updated approach (like SLAs or GlideSchedule) is more appropriate. If you do use the OOTB fields, be aware of how they are calculated and that they rely on legacy scripts that may not function if, for example, gs.calDateDiff is deprecated in your instance’s version. In most cases, custom GlideAjax logic or SLA tracking will be more flexible and maintainable.
Common Challenges and Best Practices
Calculating date differences in ServiceNow can involve a few pitfalls. Here are some common challenges you might face and best practices to handle them:
Time Zone and Format Issues: As mentioned, ServiceNow stores Date/Time in UTC and displays them in the user’s time zone. If you take a date string from g_form.getValue() and use JavaScript’s Date object on the client, ensure that the string includes a time zone or is interpreted correctly. A safe approach is to perform critical calculations on the server with GlideDateTime, which handles time zones for you. Always test with users in different time zones if your application is global.
Date vs Date-Time Fields: ServiceNow has both Date (no time component) and Date/Time fields. If you are calculating differences in days and using Date fields (which default to time 00:00:00 of that date in UTC), you might get an extra day in the calculation if you don’t account for time. For example, difference between 2023-03-01 and 2023-03-02 might show as 1 day exactly, but if interpreted in certain time zones, it could be 0 days and some hours. To avoid confusion, consider converting date-only fields to a common time (e.g., set both to noon or to midnight) when calculating, or simply use server logic which will treat date-only as midnight UTC. On the client side, you might manually append a time "00:00:00" to date values if using getValue on a date field, as suggested in a community example (ensuring the string is complete for GlideDateTime usage).
Negative Differences (Start After End): Decide how to handle scenarios where the start date is after the end date. In some use cases, a negative result makes no sense (e.g., a “due date” before “start date” could be considered invalid). You might enforce that by clearing the fields or showing a message. In other scenarios (like calculating time overdue), a negative value might be meaningful. In our examples, we often simply return a number which could be negative; the calling code can interpret it or prevent such input. One community solution returned false if the difference was <= 0 to indicate an error condition.
Performance Considerations: If you need to calculate date differences for many records (for example, updating a “age in days” field for all open incidents daily), doing this in a client script is not feasible. Instead, use a Business Rule or a Scheduled Script Execution (Scheduled Job) on the server. The server can loop through records with GlideRecord and use current.dateField1.getGlideObject() and current.dateField2.getGlideObject() with GlideSchedule or GlideDateTime to compute differences in bulk. Leverage vectorized operations where possible. Also, if using GlideAjax, avoid calling it in a tight loop on the client – it’s better to send a batch request or perform the logic server-side entirely.
Choosing the Right API: As emphasized, prefer GlideDateTime and GlideDuration for new scripts. They offer a rich set of methods (e.g., getDifference(), subtract(), getNumericValue(), etc.) that can give you differences in various formats. The older gs.dateDiff and gs.calDateDiff can still work in global scope or older instances, but they are not available in scoped applications and are effectively legacy. Also, be cautious with gs.dateDiff output: if you request a non-numeric result, it returns a string like "003 00:00:00" (for 3 days), which you would need to parse if you want just the number.
Business Schedules: If your difference needs to respect business hours or exclude certain periods, using GlideSchedule is a best practice. You can create schedules in ServiceNow (e.g., a 9-5 workday schedule, or an SLA schedule) and then use that schedule’s ID in your Script Include to calculate business durations. This ensures your calculation is accurate even as schedules change (holidays, etc., are accounted for in the schedule data). The ServiceNow docs encourage using the schedule-based calculations over older calendar functions. If you have an SLA tied to a task, often the SLA engine will already track business elapsed time for you; you might pull that from the task’s SLA or use it as a cross-check.
Testing and Verification: Whenever dealing with date math, test thoroughly. Use known examples (e.g., two dates exactly X days apart, dates that span daylight savings changes if relevant, etc.) to verify your logic. If possible, compare the output of your custom logic to a trusted source (for example, compare a GlideSchedule calculation to the OOTB Business Duration on an incident) to ensure they match expectations.
Code Maintenance: Keep your date calculation logic in one place if possible. If using GlideAjax, centralize the logic in the Script Include (as we did with DateDifferenceUtils). This way, if business rules change (say you now need to calculate in hours instead of days), you update it in one spot. Also document any assumptions (such as “using system timezone” or “excluding weekends”) for future maintainers.
By following these best practices, you can avoid common errors such as off-by-one-day issues or misinterpreted times, and ensure your date difference calculations are both accurate and performant. ServiceNow provides robust tools – as long as you use the right APIs and approach for the task.
Conclusion
Calculating the difference between two dates in ServiceNow is a common requirement that can be addressed in multiple ways. In this article, we discussed both client-side and server-side techniques. For immediate feedback on forms and simple needs, a client-side solution (using a Client Script with JavaScript date arithmetic) can suffice. It’s quick to implement and improves user experience by showing results in real time.
However, for more reliable and complex calculations, especially those involving business logic or needing to run regardless of user context, a server-side Script Include with GlideAjax is the recommended approach. This method leverages ServiceNow’s GlideDateTime API for accuracy and handles time zones and schedules more gracefully.
We also highlighted out-of-the-box options like the Business Duration and Calendar Duration fields. These can automatically compute elapsed time on task records, though they primarily serve legacy purposes today. In many modern use cases, SLA mechanisms or GlideSchedule should be used to calculate business time differences, as they are more flexible and officially supported moving forward.
So which approach is best? It depends on your use case:
If you need a quick calculation in the user interface (and absolute precision to the millisecond isn’t critical), using a client script is perfectly fine.
If you need to enforce the calculation for business rules, or share the result across the platform (not just on the form), go with a server-side solution. A Script Include called via GlideAjax provides a clean, reusable way to get date differences on demand.
When dealing with business working hours, strongly consider using ServiceNow’s schedule capabilities (either via GlideSchedule API in a Script Include or by leveraging the SLA engine). This saves you from reinventing the logic to exclude weekends/holidays and ensures consistency with how SLAs are calculated in ServiceNow.
Always remember to implement error handling and consider edge cases like incomplete data or reversed dates – this will make your solution robust.
In conclusion, calculating date differences in ServiceNow is made easier by the platform’s built-in classes and features. By choosing the right method for the job and following best practices (such as using GlideDateTime for server calculations and testing with real-world scenarios), you can build efficient automations and workflows that rely on time-based logic. Whether it’s for SLA tracking, aging tickets, or scheduling future tasks, ServiceNow gives you the tools to get the time right. Want to learn more about how to compare two dates in ServiceNow? Check out this article. Use the approach that best fits your scenario, and you’ll ensure your ServiceNow applications handle date differences with precision and reliability.