Just a heads up: On March 24, 2025, starting at 4:30pm CDT / 19:30 UTC, the site will be undergoing scheduled maintenance for a few hours. During this time, the site might be unavailable for a short while. Thanks for your patience.
×Hi gang,
I know Jaimie has a great example of calculating total time an issue's been in a particular status:
I've been trying to modify it to only count duration during weekdays (no weekends). I've seen some examples, but I can't get my version to work. I feel like I am close, but missing something. Can someone take a look at my script, and suggest what I need to change? Thanks!!
PS – if someone has a way to use jiraDurationUtils to parse the duration to keep out weekends. that would be good to know. Wasn't successful via that approach either.
import com.atlassian.jira.component.ComponentAccessor import static java.util.GregorianCalendar.* import com.atlassian.jira.issue.history.ChangeItemBean enableCache = { -> false } def changeHistoryManager = ComponentAccessor.getChangeHistoryManager() def myStatus = "In Progress" List<Long> rt = [0L] def changeItems = changeHistoryManager.getChangeItemsForField(issue, "status") changeItems.reverse().each { ChangeItemBean item -> item.toString == myStatus def timeStart = System.currentTimeMillis() def timeEnd = item.created.getTime() def c1 = new GregorianCalendar() c1.setTimeInMillis(timeStart) int w1 = c1.get(DAY_OF_WEEK); c1.add(DAY_OF_WEEK, -w1); def c2 = new GregorianCalendar() c2.setTimeInMillis(timeEnd) int w2 = c2.get(DAY_OF_WEEK); c2.add(DAY_OF_WEEK, -w2); //end Saturday to start Saturday def days = (c2.getTimeInMillis() - c1.getTimeInMillis()) / (1000 * 60 * 60 * 24) as long def daysWithoutWeekendDays = days - (days * 2 / 7) as long // Adjust days to add on (w2) and days to subtract (w1) so that Saturday // and Sunday are not included if (w1 == SUNDAY && w2 != SATURDAY) { w1 = MONDAY; } else if (w1 == SATURDAY && w2 != SUNDAY) { w1 = FRIDAY; } if (w2 == SUNDAY) { w2 = MONDAY; } else if (w2 == SATURDAY) { w2 = FRIDAY; } //convert to seconds for Duration def timeDiff = (daysWithoutWeekendDays - w1 + w2) * (60 * 60 * 24) // def timeDiff = timeStart - timeEnd if (item.fromString == myStatus) { rt << -timeDiff } if (item.toString == myStatus) { rt << timeDiff } } def total = rt.sum() as Long return total ?: 0L
//After working and troubleshooting I came up with the solution which gives actual time excluding weekend (Saturday and Sunday)
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.history.ChangeItemBean
import java.util.concurrent.TimeUnit
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.bc.issue.IssueService.UpdateValidationResult
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager
import com.atlassian.core.util.DateUtils
import com.atlassian.jira.issue.history.ChangeItemBean
def statusCode = ['Done','In Progress','In testing','In Implementation','To Do'];
IssueManager im = ComponentAccessor.getIssueManager()
//MutableIssue issue = im.getIssueObject('TES-24') // Uncomment for troubleshoot in console
ChangeHistoryManager changeHistoryManager = ComponentAccessor.getChangeHistoryManager()
String myStatus = "In Progress" // can be taken dynamically -> issue.getStatus.name
List<Long> rt = [0L]
long curTime = System.currentTimeMillis();
changeHistoryManager.getChangeItemsForField(issue, "status").reverse().each { ChangeItemBean item ->
item.toString == myStatus
Calendar c1 = new GregorianCalendar()
c1.setTimeInMillis(item.created.getTime())
int iHolydayCnt = 0;
while(c1.getTimeInMillis() < curTime)
{
c1.add(Calendar.DAY_OF_YEAR, 1)
if((c1.get(Calendar.DAY_OF_WEEK).equals(Calendar.SATURDAY)) || c1.get(Calendar.DAY_OF_WEEK).equals(Calendar.SUNDAY) )
++iHolydayCnt;
//log.warn(iHolydayCnt)
}
//convert to seconds for Duration
long timeDiff = curTime - item.created.getTime() - iHolydayCnt*(60*60*24*1000)
// def timeDiff = timeStart - timeEnd
if (item.fromString == myStatus) {
rt << -timeDiff
}
if (item.toString == myStatus) {
rt << timeDiff
}
}
def total = rt.sum()/1000 as Long
def mytotal =DateUtils.getDurationString(total)
log.warn(total)
log.warn(mytotal)
return mytotal ?: 0L
// Happy Coding // Sanjay_D_D_Programmer
Thanks buddy..
It helped me a lot !
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Well done buddy..
works really great to get the actual time excluding weekends.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Can you please give me the steps to get this implemented in our Jira Cloud?
Appreciate it very much.
Regards,
Zaldy
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Try this one to find holydays count:
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.changehistory.ChangeHistoryManager import com.atlassian.jira.issue.history.ChangeItemBean ChangeHistoryManager changeHistoryManager = ComponentAccessor.getChangeHistoryManager() String myStatus = "In Progress" List<Long> rt = [0L] long curTime = System.currentTimeMillis(); changeHistoryManager.getChangeItemsForField(issue, "status").reverse().each { ChangeItemBean item -> item.toString == myStatus Calendar c1 = new GregorianCalendar() c1.setTimeInMillis(item.created.getTime()) int iHolydayCnt = 0; while(c1.getTimeInMillis() < curTime){ c1.add(Calendar.DAY_OF_YEAR, 1) if((c1.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) || (c1.get(Calendar.SUNDAY)) ) ++iHolydayCnt; } //convert to seconds for Duration long timeDiff = curTime - item.created.getTime() - iHolydayCnt*(60*60*24*1000) // def timeDiff = timeStart - timeEnd if (item.fromString == myStatus) { rt << -timeDiff } if (item.toString == myStatus) { rt << timeDiff } } def total = rt.sum() as Long return total ?: 0L
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks buddy Your scripts helped me a lot but need some minor correction which i did you can refer above.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Vasiliy Zverev ,
Is this script working for initial statuses,e.g Open Or To Do like that?,in my case it is working for remaining statuses rather than initial status i.e.Open or To Do,can you please help me.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.
Register Now
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.