Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Subtract two dates and then adding outcome to Duration field

Alon Grod
Tera Expert

Hi,

I have the fields sys_updated_on and u_date_move_to_pending both of type Date/Time.

In addition, I have the field u_pending_time of type Duration.
when some condition is met, Im trying to subtract sys_updated_on - u_date_move_to pending and insert the outcome into u_pending_time. 
u_pending_time should be equal to the current.u_pending_time + new outcome. (should be like a counter).

What am I doing wrong?

 

WhatsApp Image 2024-01-07 at 11.30.37.jpeg

2 REPLIES 2

Iraj Shaikh
Mega Sage

Hi @Alon Grod 

Your script has the right idea, but there are a few issues that need to be addressed. The `GlideDateTime.subtract()` method returns a `GlideDuration` object, which represents the difference between two `GlideDateTime` objects. However, `GlideDateTime.add()` is not a valid method for adding durations. Instead, you should use the `add()` method on a `GlideDuration` object to add another duration to it.

Here's a corrected version of your script:

 

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

    // Create GlideDateTime objects for the two Date/Time fields
    var updatedOn = new GlideDateTime(current.sys_updated_on);
    var dateMoveToPending = new GlideDateTime(current.u_date_move_to_pending);

    // Calculate the duration between the two Date/Time fields
    var duration = GlideDateTime.subtract(updatedOn, dateMoveToPending);

    // If current.u_pending_time is not empty, create a GlideDuration object from it
    var currentPendingTime;
    if (current.u_pending_time != '') {
        currentPendingTime = new GlideDuration(current.u_pending_time);
    } else {
        // If it's empty, initialize a new GlideDuration with zero duration
        currentPendingTime = new GlideDuration(0);
    }

    // Add the new duration to the current pending time
    currentPendingTime.add(duration);

    // Set the new total duration back to the 'u_pending_time' field
    current.setValue('u_pending_time', currentPendingTime.getDisplayValue());

    // Update the record
    current.update();

})(current, previous);

 


Please note the following changes:

1. I've added a check to see if `current.u_pending_time` is not empty before creating a `GlideDuration` object from it. If it's empty, we initialize a new `GlideDuration` with zero duration.
2. I've used the `add()` method on the `GlideDuration` object to add the new duration to the current pending time.
3. I've used `getDisplayValue()` to get the display value of the `GlideDuration` object, which is suitable for setting the value of the duration field.
4. I've added a call to `current.update()` to save the changes to the record. This may or may not be necessary depending on the context in which this script is running. If this script is part of a business rule that runs on 'before' events, you should remove the `current.update()` line to prevent a recursive update.

Please mark this response as correct or helpful if it assisted you with your question.

Tai Vu
Kilo Patron
Kilo Patron

Hi @Alon Grod 

You can achieve your requirement using these APIs below.

dateDiff(String startDate, String endDate, Boolean numericValue)

add(GlideDuration duration)

 

Sample Script for your case.

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

	var duration = gs.dateDiff(gr.getDisplayValue('u_date_move_to_pending'), gr.getDisplayValue('sys_updated_on'));
	var gdPending = new GlideDuration(duration);
	var gdCurrentPending = new GlideDuration(gr.u_pending_time.dateNumericValue());
	var result = gdCurrentPending.add(gdPending);
	current.u_pending_time = result;

})(current, previous);

 

Cheers,

Tai Vu