Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
Community Members
Community Events
Community Groups

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

Atlassian Community Events