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

Time elapsed in current status (Scripted Field + Date Time search template)

Marco Colageo June 26, 2013

Hi community,

I need help to do the last step on the definition of a scripted field that returns the time the issue has spent into the current status.

Below is the scripted field code:

import com.atlassian.core.util.DateUtils
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.history.ChangeItemBean
import com.atlassian.jira.issue.Issue
 
def componentManager = ComponentManager.getInstance()
def changeHistoryManager = componentManager.getChangeHistoryManager()

/*def inProgressName = "In Progress"
Get the current status name */ def inProgressName = issue.getStatusObject().getName() def rt = [0] changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {ChangeItemBean item -> def timeDiff = System.currentTimeMillis() - item.created.getTime() if (item.fromString == inProgressName) { rt << -timeDiff } if (item.toString == inProgressName){ rt << timeDiff } } DateUtils.getDurationString(Math.round(rt.sum() / 1000))

That's a slightly modified version of the Groovy Scripted Fiels example (link).

The code works properly to return a string well formatted ( e.g. 1h 11m) by setting the Free Text Field template.

What I need now is to convert the string into a Data Format so that I can query it to know issues that are in the same status since one week for istance.

If I set the Date Time Template and I put this linecodes instead of the very last one:

def strDuration = DateUtils.getDurationString(Math.round(rt.sum() / 1000))
DateUtils.getDuration(strDuration)

I got the error below:

$datePickerFormatter.format($value)

Any idea how I can convert the duration string into a data-time friendly value?

Regards

Marco

1 answer

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

1 vote
Answer accepted
Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 26, 2013

If you use the Date Time Template you have to return a Timestamp object not a long. So maybe what you want is a Number Template and than return the days or hours the issue was in the current status as Double object.

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 26, 2013

So using the Number template and returning

return (Math.round(rt.sum() / 3600000)) as Double

should give you the number of hours the issue was in the current status.

Marco Colageo June 26, 2013

Hi Henning,

Thanks for your reply. It returns the number of hours, but it still does not work properly. I had '4h 11m', now I've got '4' nut the JQL filter does not see it as a number.

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 26, 2013

Did you configure the searcher as a number searcher? Both template and searcher have to be "number".

Marco Colageo June 26, 2013

It works thanks!

Daniel Bower March 5, 2015

What was ultimately the full working script for this? It's exactly what I'm looking to do in my system as well. Thanks.

Bill Tanner November 16, 2017

Did you ever get the full working script?  I am trying the same thing.

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 19, 2017

For Jira 7+ this would be

import com.atlassian.jira.component.ComponentAccessor

def changeHistoryManager = ComponentAccessor.changeHistoryManager
def currentStatusName = issue?.status?.name

def rt = [0]
changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {item ->

def timeDiff = System.currentTimeMillis() - item.created.getTime()
if (item.fromString == currentStatusName) {
rt << -timeDiff
}
if (item.toString == currentStatusName){
rt << timeDiff
}
}
return (Math.round(rt.sum() / 3600000)) as Double
 
Bill Tanner November 20, 2017

Thanks for the reply!

 

I am getting the following error on line 11 (rt << -timeDiff>

 

[static type checking] - cannot call <T> java.util.list <java.lang.Integer>#leftShift(T) with arguments [long] @ line 11, column 9.

 

Any help?

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 20, 2017

Try to initialize the list with a long:

def rt = [0L]
Shawn Danisa April 25, 2018

Hi 

I'm getting an error.

Cannot find matching method java.lang.Object#div(int).  Please check if the right and if the method exists

 

Cannot find matching method

java.lang.Math#round(java.lang.Object)  Please check if the declared type is right and if the method exists.

 

This I get on the last line (return statement)

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 25, 2018

Mmh, maybe there is a NULL creation date (this shouldn't be the case). Try to add

rt -= null

before the return statement and see if this helps.

Anil Kumar Bondada December 6, 2018

 Hello @Henning Tietgens

We're trying to create a custom field which can show the "time in current status" in days for  the issues in JIRA. The field has to reset and show the new value(new age) whenever the issue is transitioned.  I created a custom script field and added the code which was suggested in your earlier comments.  Look like its giving me the reslut in Hours. How should I change it to get the result Days? Thanks in Advance.

FYI, we're on 7.12.1

This is code that I applied

 

import com.atlassian.jira.component.ComponentAccessor

def changeHistoryManager = ComponentAccessor.changeHistoryManager
def currentStatusName = issue?.status?.name

def rt = [0L]
changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {item ->

def timeDiff = System.currentTimeMillis() - item.created.getTime()
if (item.fromString == currentStatusName) {
rt << -timeDiff
}
if (item.toString == currentStatusName){
rt << timeDiff
}
}
return (Math.round(rt.sum() / 3600000)) as Double
Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 7, 2018

You have to calculate the number of days instead the number of hours. How, depends on your meaning of "day". 24h = 1 day or 8h (working hours) = 1d?

If 8h = 1 day the last line would be

return (Math.round(rt.sum() / 3600000 / 8)) as Double

Btw, this number is calculated every time the issue is displayed, not every time the issue is transitioned. 

Anil Kumar Bondada December 7, 2018

Thanks for the quick response. I've modified the code and its working perfectly now. As you mentioned, it's only working when the ticket is displayed. But I think we can live with it. We just need to know the status age when looking at the displayed ticket. 

 

Final Code

import com.atlassian.jira.component.ComponentAccessor

def changeHistoryManager = ComponentAccessor.changeHistoryManager
def currentStatusName = issue?.status?.name

def rt = [0L]
changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {item ->

def timeDiff = System.currentTimeMillis() - item.created.getTime()
if (item.fromString == currentStatusName) {
rt << -timeDiff
}
if (item.toString == currentStatusName){
rt << timeDiff
}
}
return (Math.round(rt.sum() / 3600000 / 24)) as Double
Mahalakshmi Sivasamy January 2, 2019

Hi All,

 

I have tried with the above code to get time in current status and i am getting error as below. Can you please help me on this error. 

 

Code i have used is:

import com.atlassian.jira.component.ComponentAccessor

def changeHistoryManager = ComponentAccessor.changeHistoryManager
def currentStatusName = issue?.status?.name

def rt = [0L]
changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {item ->

def timeDiff = System.currentTimeMillis() - item.created.getTime()
if (item.fromString == currentStatusName) {
rt << -timeDiff
}
if (item.toString == currentStatusName){
rt << timeDiff
}
}
return (Math.round(rt.sum() / 3600000 / 24)) as Double

 

Capture.JPG 

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 2, 2019

Hi,

try 

return (Math.round((rt.sum() as Long) / 3600000 / 24)) as Double

as last line. 

Mahalakshmi Sivasamy January 3, 2019

Many thanks for you response.

New error occurs with the above code

Capture.JPG

Error message in the custom field:

Capture.JPG

 

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 3, 2019

Hi,

the Static Type checking error is only in the editor, at runtime the type should be clear. But If you don't want to see the error icon use this as the last line.

return (Math.round(((rt.sum() as Long) / 3600000 / 24) as Long)) as Double

Make sure to select "Number field" as Template for the scripted field.

Capture 2019-01-04_08-44-37_AM.png

Mahalakshmi Sivasamy January 4, 2019

Thank you, it works.

What is the fucntion i should use to display the result in below format?

 

Eg: 2w 2d

Henning Tietgens
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 4, 2019

If you want a duration the result has to be a long containing the durations in seconds, currently the script results in days as Double. Change the last line to

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

and use the "Duration" or "Duration (time-tracking)" template.

Like siva likes this
TAGS
AUG Leaders

Atlassian Community Events