Converting Date Differences into a Formatted Duration String - ben-vargas/servicenow-wiki GitHub Wiki

When working with incidents, changes, or any records that involve start and end times, it’s often useful to calculate how long something took. ServiceNow’s gs.dateDiff() function returns time differences in either seconds or days, but turning those results into a human-friendly DD:HH:MM:SS format requires extra steps. The following example shows how to compute a duration between two datetime fields and present it in a readable string format.


Use Case

Scenario:
You have two custom datetime fields on a record (e.g., u_start_of_incident and u_end_of_incident) and you want to store both:

  1. The raw duration in seconds or milliseconds for calculations or reporting.
  2. A formatted string (DD:HH:MM:SS) that’s easy to understand at a glance.

Key Steps in the Code

  1. Retrieve and Parse Start/End Times:

    var start = new GlideDateTime();
    var end = new GlideDateTime();
    start.setDisplayValueInternal(current.u_start_of_incident);
    end.setDisplayValueInternal(current.u_end_of_incident);
    

    Here we instantiate two GlideDateTime objects and set their values based on fields from the current record. setDisplayValueInternal() ensures that the date/time strings are interpreted correctly by the platform.

  2. Calculate the Duration:

    current.u_duration = gs.dateDiff(start.getDisplayValue(), end.getDisplayValue(), false);
    

    Using gs.dateDiff(), the duration is computed in days (since the third parameter is false), and stored as a numeric value in current.u_duration.

  3. Get Duration in Seconds and Convert to Milliseconds:

    var time = gs.dateDiff(start.getDisplayValue(), end.getDisplayValue(), true); 
    time = parseFloat(time)*1000; 
    current.u_duration_str = msToTimeString(time);
    

    Passing true as the third parameter to gs.dateDiff() returns the difference in seconds. Multiplying by 1000 converts it into milliseconds.

  4. Formatting the Duration as DD:HH:MM:SS: The msToTimeString() function takes the milliseconds, breaks them down into days, hours, minutes, and seconds, and returns a formatted string.

    function msToTimeString(s, msInclude) {
      function addZ(n) { return (n<10?'0':'')+n; }
    
      var ms = s % 1000;
      s = (s - ms) / 1000;
      var secs = s % 60;
      s = (s - secs) / 60;
      var mins = s % 60;
      s = (s - mins) / 60;
      var hrs = s % 24;
      var days = (s - hrs) / 24;
    
      if (msInclude) {
        // Return DD:HH:MM:SS.sss format if msInclude is true
        return addZ(days)+':'+addZ(hrs)+':'+addZ(mins)+':'+addZ(secs)+'.'+ms;
      } else {
        // Return DD:HH:MM:SS format
        return addZ(days)+':'+addZ(hrs)+':'+addZ(mins)+':'+addZ(secs);
      }
    }
    

    By default, if msInclude is not provided or is false, it returns the format DD:HH:MM:SS. If true, it adds milliseconds as well.


Example

Before: You have an incident that started on 2021-07-01 08:30:00 and ended on 2021-07-03 10:45:30. The code calculates the duration:

  • Duration: 2 days, 2 hours, 15 minutes, 30 seconds
  • u_duration_str: 02:02:15:30

This makes it obvious that the incident lasted a bit over two days.


Customization and Adaptation

  • Custom Fields:
    Replace current.u_start_of_incident and current.u_end_of_incident with the fields relevant to your scenario.
  • Storing Values:
    If you don’t need milliseconds, skip the part converting to ms and call msToTimeString() differently.
  • Format Variations: You can tweak the code in msToTimeString() to remove days if unnecessary, or add other custom logic.

Best Practices

  • Validation:
    Ensure both start and end fields are populated before running the script. If end is before start, consider handling negative durations or logging an error.
  • Performance: The calculation and string formatting are lightweight, but avoid running this script repeatedly on the same record unnecessarily.
  • Testing: Test with multiple date ranges (short durations, multi-day spans) to confirm the format is always correct.

Conclusion

This snippet provides a practical way to calculate the duration between two datetime fields and convert that duration into a human-readable DD:HH:MM:SS string. It’s particularly useful for incidents, tasks, or any scenario where understanding elapsed time at a glance is important.