Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Calculate time in multiple statuses (cont.)


Hi all,

This post is a continuation/repost of my recent blog post, but I'm looking to figure out how to calculate the amount of time that an issue has been under a select group of statuses.

I'm aware that Scriptrunner Library has a solution that enables you to create a scripted field with the duration template that records the time that an issue has been under a certain status, referenced here: 

Count the time an issue was in a particular status

What I want to do is use this code and change it up to where it can calculate the time that the issue has been under not just one status, but a certain collection of statuses.

Since my last post, I've edited the code a bit myself. Pretty much all I could think of for now was to duplicate the block that covers the changeItems object, but replicate it for another status...and then in the end, take the two arrays that store the total time that the issue was in said statuses, use addAll(), and then sum up the values in the newly-expanded array. See below:

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.history.ChangeItemBean
def changeHistoryManager = ComponentAccessor.changeHistoryManager

// Status to be counted
def toDo = 'On Hold'
def totalStatusTime = [0L]

// Every status change is checked
def changeItems = changeHistoryManager.getChangeItemsForField(issue, "status")
changeItems.reverse().each { ChangeItemBean item ->
def timeDiff = System.currentTimeMillis() - item.created.time
// Subtract time if the "from" status is equal to the status to be checked and from and to statuses are different.
// This allows to count the time the issue is in the state for the first time
if (item.fromString == toDo && item.fromString != item.toString) {
totalStatusTime << -timeDiff
// Add time if the "to" status is equal to the status to be checked
if (item.toString == toDo) {
totalStatusTime << timeDiff

def intakeReview = "Intake Review"
def totalStatusTime2 = [0L]

changeHistoryManager.getChangeItemsForField (issue, "status")
changeItems.reverse().each {ChangeItemBean item ->
def timeDiff = System.currentTimeMillis() - item.created.time

if (item.fromString == intakeReview && item.fromString != item.toString) {
totalStatusTime << -timeDiff
if (item.toString == intakeReview) {
totalStatusTime << timeDiff


def total = totalStatusTime.sum() as Long
(total / 1000) as long ?: 0L


This seemed to have worked for these two statuses in particular when previewing the code over an issue in our system. This issue was created and set by default to the Open status. In exactly 4 days, 18 hours, and 53 minutes after the issue was created, the issue was then moved to the Intake Review status. I was only in the Intake Review status for 4 minutes, and it was then moved to the On Hold status...and the issue has been On Hold for the past 35 weeks, 4 days, 6 hours, 57 minutes and counting.

Previewing the above code for the same issue, the amount of time that the issue was in On Hold will be added to the 4 minutes that it was Intake Review and the result will come up as 35 weeks, 4 days, 7 hours, 1 minute. This is the result I want, which is great.

However...for some reason,  when I want to find out the time in the Open status, the code only returns null. And worse yet, when I want to find how long the issue has been in both Open and On Hold statuses, instead of doing [35 weeks, 4 days, 6 hours, 57 minutes] + [4 days, 18 hours, and 53 minutes]'ll still return null :(

Any reason why this is happening?


Also, if anyone has suggestions on how to clean this up and have the script iterate through the time the issue has been in a selection of statuses (say Open, Intake ReviewOn Hold, and In Progress) rather than just copying and pasting a block for each status, that'd be awesome too.

As always, any tips or advice is highly appreciated! Let me know if there's any other info you need from my end.






1 comment

Hi @Ian Balas 

A couple of FYIs first:

  • You may want to post something like this in the Questions area to get more eyes on it rather than in Discussions
  • You may want to check out the developer community area for ideas:

Regarding the Open measure which you indicate evaluates to NULL...  If you are not handling that NULL and just adding it to an actual value might it not collapse to NULL?  That could explain what you are seeing.

And, your measurement scenario seems pretty complex.  Using this code, I think you will need to continue what you are trying: evaluate, status by status, and then doing the math for what you want. In your earlier post there are some suggestions to try; how did those help?

Your other options are to purchase an add-on product with lots of flexibility for time measurement or to use the Automation for Jira features and custom fields to build your own.

Best regards,



Log in or Sign up to comment
Community showcase
Published in Jira

Admins, notify your Jira instance of system-wide changes with the new admin announcement banner

Hi All! We’re excited to share the launch of an announcement banner that lets Jira site administrators communicate directly to their users across their  Jira Cloud instance.  ...

495 views 16 17
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you