Calculate date only day of the week

Is it possible to use the runner script to do this?

I need to calculate how many days (day of the week) I need to work to consume all the estimated hours.

Example:
Estimate = 200h
Resource = 2 dev
Time dedicated 4h per day
Start of activity 2/23/2017


200 (estimated hours) / 4 (hours per day) = 50 (days)
50 (days) / 2 (dev resources) = 25 working days

Starting the activity on 2/23/2017, how to add 25 days? (These days being only days of the week (ignoring weekends))


How many days do I have to work to consume these hours?
25 days
What day will I finish work?
I do not know (how to add 25 days only day of week from 02/23/2017?)

1 answer

You could do this with a Scripted FIeld. Most of the real work is just doing some date math using Groovy/Java APIs.

Programmer's warning: Date math is hard. Groovy helps make it a little easier, but I'm still naively assuming there are no holidays, sick days, or other days off in the mix that need to be skipped over, which won't always be the case.

Basically, we'll calculate the total number of days as you do in your pseudo code. Divide that by 5, leaving off the remainder. That's the number of whole weeks, which we can easily add to a date.

The remainder of days need to be carefully looped over in order to skip over weekends.

import com.atlassian.jira.component.ComponentAccessor
import java.sql.Timestamp

def jiraDurationUtils = ComponentAccessor.jiraDurationUtils

def remainingEstimate = issue.estimate
def numberOfDevs = 2
def millisecondsPerDay = jiraDurationUtils.parseDuration("4h") * 1000

def baseDays = remainingEstimate / millisecondsPerDay
def realDays = baseDays / numberOfDevs
def workingDaysPerWeek = 5

int solidWeeks = realDays / workingDaysPerWeek
int remainingDays = realDays % workingDaysPerWeek

/*
Note: I'm hard-coding the start date here, 
but we could make the start date based on a custom field like this:

def customFieldManager = ComponentAccessor.customFieldManager
def startDateField = customFieldManager.getCustomFieldObjects(issue).find{it.name == "Start Date"}
def startDate = issue.getCustomFieldValue(startDateField) as Timestamp

Also, I'm naively assuming that the start date is not on a weekend
*/
def startDate = Date.parse("2017/02/23", "YYYY/MM/dd")
def startDatePlusWeeks = startDate + (7 * solidWeeks)
def endDate = startDatePlusWeeks
def cal = endDate.toCalendar()

if (remainingDays >= 1) {
    //Loop through the remaining days, adding one each time, skipping to Monday when it's Friday
    (1..remainingDays).each{
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
            cal.add(Calendar.DAY_OF_MONTH, 3)
        }
        else {
            cal.add(Calendar.DAY_OF_MONTH, 1)
        }
    }
}
return cal.getTime().toTimestamp()

There are some good resources and tutorials on Java & Groovy date/calendar math. They're worth a look if you want to extend the above script to include holidays and such like.

http://mrhaki.blogspot.com/2010/12/groovy-goodness-convert-date-to.html 

http://www.javaworld.com/article/2074678/core-java/groovy-jdk--gdk---date-and-calendar.html

https://dzone.com/articles/groovy-jdk-gdk-date-and 

And, of course, there's always the good ol' GroovyDocs:

http://docs.groovy-lang.org/docs/groovy-next/html/groovy-jdk/java/util/Calendar.html

http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Date.html 

Hi @Jonny Carter [Adaptavist]

Using your code I was able to create one that meets my need.
I only have 2 doubts:

1. How do I pass the value of a custom field?
(The Resource and Dedicated field are custom fields in JIRA)

2. What output format do I have to use to be able to use the Data Picker format?
(I'm using the text format to display for now)

 

import com.atlassian.jira.component.ComponentAccessor
import java.sql.Timestamp
 
def jiraDurationUtils = ComponentAccessor.jiraDurationUtils

def remainingEstimate = 200 //(customfield_13902)
def numberOfDevs = 2 //(customfield_14107)
def hourPerDay = 4 //(customfield_14108)
def Date = "23/02/2017" //(customfield_10800)
def startDate = new Date().parse("d/M/yyyy",Date)
def baseDays = remainingEstimate / hourPerDay
def realDays = (baseDays / numberOfDevs) -1
def cal = startDate.toCalendar()
    (1..realDays).each{
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
            cal.add(Calendar.DAY_OF_MONTH, 3)
        }
        else {
            cal.add(Calendar.DAY_OF_MONTH, 1)
        }
    }
return cal.getTime().format("d/MM/yyyy")

Suggest an answer

Log in or Sign up to answer
Atlassian Community Anniversary

Happy Anniversary, Atlassian Community!

This community is celebrating its one-year anniversary and Atlassian co-founder Mike Cannon-Brookes has all the feels.

Read more
Community showcase
Julia Dillon
Posted Apr 17, 2018 in Jira

Tell us how your team runs on Jira!

Hey Atlassian Community! Today we are launching a bunch of customer stories about the amazing work teams, like Dropbox and Twilio, are doing with Jira. You can check out the stories here. The thi...

798 views 2 19
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you