Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

How to calculate a person's age from DOB value with Scripted field

Philemon Nkafu
Contributor
September 27, 2020

I have a requirement to automatically calculate a person's age based on the value of entered in the DOB field. Am very new to scripting but have tried the below script to no success, It is not returning the person's age. I used the ScriptRunner scripted field and my selected template is "Date Time" and my searcher is "Date Time Picker Range"  Please, I need some help

import com.atlassian.jira.component.ComponentAccessor
import java.time.Period
import java.time.LocalDate
import java.time.ZoneId

def customFieldManager = ComponentAccessor.customFieldManager
def dob = customFieldManager.getCustomFieldObjectsByName("DOB")[0]
def dobValue = dob.getValue(issue) as Date

static def convertToLocalDateViaInstant(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
}

def today = LocalDate.now()
def birthday = convertToLocalDateViaInstant(dobValue) as LocalDate

def age = Period.between(birthday, today)

return String.format("%d years, %d months, %d days", age.getYears(), age.getMonths(), age.getDays())

 

1 answer

0 votes
Nic Brough -Adaptavist-
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.
September 28, 2020

Why are you using a date-time template?  Your script is returning a string, not a date.

Also, how are you triggering the recalculation you need to do every year?

Philemon Nkafu
Contributor
September 28, 2020

@Nic Brough -Adaptavist- 

Appreciate the identification of the template error. However, upon testing, I realized I may need some further help.

1. Am seeing NULL pointer exception error in the log, it has to do with the DOB field being empty in some tickets. Am thinking of a line like below but not sure. Please can you help with providing the line

If the DOB field is empty ignore it
if (DOBValue==null) {
return null
}

2. Also, can you help me with the line(s) for the recalculation?

3. As you can see, am returning year, month & day, how do I return only Year?

4. I would also like to have the script return the age for all DOB entered for projects in the database

 

Thanks for all your help.

Nic Brough -Adaptavist-
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.
September 30, 2020
  1. It's not great to compare to null, you can just say "if there is a value" or "if there is no value" - in this case you can say the second with "if (!DOBValue) "
  2. Where are you stuck on it?
  3. If you want just the year, then change your script to only return the year, and change the output type to number or string - a year is not a date/time value
  4. You do understand you are going to need to run an update script every day?
Philemon Nkafu
Contributor
September 30, 2020

@Nic Brough -Adaptavist- Appreciate you getting back to me. Am now stuck at the following:

1. The line to ignore the empty DOB field 

2. The line for the recalculation or running everyday.

Below is my updated script. Please can you add the above lines and send back to me. Am really new to scripting and this is challenging to me .

 

import com.atlassian.jira.component.ComponentAccessor
import java.time.Period
import java.time.LocalDate
import java.time.ZoneId

def customFieldManager = ComponentAccessor.customFieldManager
def dob = customFieldManager.getCustomFieldObjectsByName("DOB")[0]
def dobValue = dob.getValue(issue) as Date

static def convertToLocalDateViaInstant(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
}

def today = LocalDate.now()
def birthday = convertToLocalDateViaInstant(dobValue) as LocalDate

def age = Period.between(birthday, today)

return String.format("%d years", age.getYears())

Nic Brough -Adaptavist-
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.
September 30, 2020

For the empty field, see my previous comment.

The code for recalculation is not done in a scripted field - you need something that will read every issue that has a "birthday" set to today's date and trigger a re-index on it.

I think you may not quite understand how scripted fields work, as you're missing the point a little.  When their script is run, they calculate a value for a field and store it, so it can be displayed (and searched on, and sorted by etc).

Imagine you enter a birthday for me - say 29/02/1976, and you did this today.  The scripted field will calculate that I'm 44 and display that.   All good.  Until you look at the issue on the 1/3/<next year>.  The value remains 44 which is now wrong.

Now, it will change to 45 if you edit or transition the issue, or do anything else that causes it to be re-indexed (note it's not as simple as "re-index it", but that is an easy way to think of it for most purposes). 

That's why I say you'll need a service that can run and update it - your ages are going to go out of date annually.

Philemon Nkafu
Contributor
September 30, 2020

@Nic Brough -Adaptavist- Thanks for the clarification. I have inserted the line from your comment above and got an error.

Am very new to scripting and would need help getting that line right. Please, can you help completing the script .

Appreciate your help.

Nic Brough -Adaptavist-
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.
October 2, 2020

What is the error you get?  (also, it would be really useful to see the lines of code that cause it - probably more useful than the error!)

Philemon Nkafu
Contributor
October 4, 2020

@Nic Brough -Adaptavist- Below is the error am seeing in the log 

 

2020-09-29 13:23:04,811 ERROR [customfield.GroovyCustomField]: *************************************************************************************
2020-09-29 13:23:04,857 ERROR [customfield.GroovyCustomField]: Script field failed on issue: PP-4, field: Age
java.lang.NullPointerException: Cannot invoke method toInstant() on null object
 at Script108.convertToLocalDateViaInstant(Script108.groovy:11)
 at Script108$convertToLocalDateViaInstant.callStatic(Unknown Source)
 at Script108.run(Script108.groovy:17)
Philemon Nkafu
Contributor
October 4, 2020

@Nic Brough -Adaptavist- Below is the error I am getting 

2020-09-29 13:23:04,811 ERROR [customfield.GroovyCustomField]: *************************************************************************************
2020-09-29 13:23:04,857 ERROR [customfield.GroovyCustomField]: Script field failed on issue: PP-4, field: Age
java.lang.NullPointerException: Cannot invoke method toInstant() on null object
 at Script108.convertToLocalDateViaInstant(Script108.groovy:11)
 at Script108$convertToLocalDateViaInstant.callStatic(Unknown Source)
 at Script108.run(Script108.groovy:17)
Nic Brough -Adaptavist-
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.
October 6, 2020

Sorry for the delay

Your script is trying to

return dateToConvert.toInstant()

But you do not define dataToConvert anywhere.

Suggest an answer

Log in or Sign up to answer