Calculate duration and write to a text field

Maria DePasquale November 8, 2019

I have two custom date fields (start and end).  I need to first calculate the duration (end-start) and then format that value like this:  d hh:mm:ss

Even if the duration is long, it would still be the above format so no months or years, just days hh:mm:ss.  If the duration was shorter than a day, the format would be hh:mm:ss.

I need to write the value to a text field.  So, the resulting text field would look something like this:  2  12:23:54  (2 days, 12 hours, etc)

I need to include this code in Post Function --> Scriptrunner.  Does anyone have a script handy that would help with this task?

1 answer

1 accepted

0 votes
Answer accepted
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 8, 2019

You could use groovy.time.TimeCategory.minus(end, start) to get a groovy.time.TimeDuration

def endDate = new Date()
def startDate = new Date().parse("dd/MM/yyyy","11/1/2019")
groovy.time.TimeCategory.minus(endDate , startDate)

That script in the console outputs:  301 days, 9 hours, 44 minutes, 23.499 seconds

But you can combine different parts yourself to control the format:

def endDate = new Date()
def startDate = new Date().parse("dd/MM/yyyy","1/1/2018")
def duration = groovy.time.TimeCategory.minus(endDate , startDate)
"$duration.days $duration.hours:$duration.minutes:$duration.seconds"
Maria DePasquale January 31, 2020

Thanks for your suggestion @Peter-Dave Sheehan.  This Post Transition script is what I implemented.  Note, it also subtracts hours due to Saturdays and formats the duration.  There are more imports than needed... I know.

import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser
import java.util.*
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import static java.lang.Math.*
import java.util.concurrent.TimeUnit;
import java.util.Date.*
import java.text.DateFormat;
import java.text.SimpleDateFormat;

enableCache = {-> false}
def cfManager = ComponentAccessor.getCustomFieldManager();


Issue issue = issue
MutableIssue iss=issue
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager();

DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
def cfend = cfManager.getCustomFieldObjectByName("Incident End")
def cfstart = cfManager.getCustomFieldObjectByName("Incident Start")
def cfdur = cfManager.getCustomFieldObjectByName("Incident Duration")

def cfendVal = cfend.getValue(issue) as Date
def cfstartVal = cfstart.getValue(issue) as Date

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(cfstartVal);
cal2.setTime(cfendVal);
def numberOfSaturdays = 0
while (cal1.before(cal2)) {
if ((Calendar.SATURDAY == cal1.get(Calendar.DAY_OF_WEEK))) {
numberOfSaturdays++;
}
cal1.add(Calendar.DATE,1);
}

log.error("Number of Days Between Dates: " + numberOfSaturdays)

def subsat = (numberOfSaturdays * 1440)


long secondsInMilli = 1000;
long minutesInMilli = secondsInMilli * 60;
long hoursInMillli = minutesInMilli * 60;
long daysInMilli = hoursInMillli * 24;

long duration = cfendVal.getTime() - cfstartVal.getTime()
long diffInMinutesi = TimeUnit.MILLISECONDS.toMinutes(duration);
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);
duration = duration % daysInMilli;
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
duration = duration % hoursInMillli;
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
duration = duration % minutesInMilli;
long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);

log.error("end Val - " + cfendVal + " start Val - " + cfstartVal)
cfdur.updateValue(null,issue, diffInDays + "d" + " " + String.format("%02d", diffInHours) + ":" + String.format("%02d", diffInMinutes) + ":"+ String.format("%02d", diffInSeconds))

Like Peter-Dave Sheehan likes this

Suggest an answer

Log in or Sign up to answer