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

Trying to get total time in transition without weekends

Hi gang,

I know Jaimie has a great example of calculating total time an issue's been in a particular status:

https://scriptrunner.adaptavist.com/latest/jira/scripted-fields.html#_total_time_this_issue_has_been_in_progress

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

2 answers

//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 !

Like Sanjay_Dhandare likes this

Well done buddy..

works really great to get the actual time excluding weekends.

Like Sanjay_Dhandare likes this

Thanks Kunal for acknowledging ! 

@Madhusudan Bhosale 

Can you please give me the steps to get this implemented in our Jira Cloud?

Appreciate it very much.

Regards,

Zaldy

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&lt;Long&gt; rt = [0L]

long curTime = System.currentTimeMillis();

changeHistoryManager.getChangeItemsForField(issue, "status").reverse().each { ChangeItemBean item -&gt;
    item.toString == myStatus   
    
    Calendar c1 = new GregorianCalendar()
    c1.setTimeInMillis(item.created.getTime())
    int iHolydayCnt = 0;
    while(c1.getTimeInMillis() &lt; 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 &lt;&lt; -timeDiff
    }
    if (item.toString == myStatus) {
        rt &lt;&lt; timeDiff
    }
}

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

Thanks buddy Your scripts helped me a lot but need some minor correction which i did you can refer above.

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.

Suggest an answer

Log in or Sign up to answer
TAGS

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