1

I am trying to round off time to the upcoming 15 minutes time. e.g :

  1. 2017-12-11T13:11:51.728Z to 2017-12-11T13:15:00.000Z
  2. 2017-12-11T13:21:51.728Z to 2017-12-11T13:30:00.000Z

Groovy code :

def currentTime = context.expand('${#Project#currentTime}')
log.info currentTime
date1 =  new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(currentTime)
//Round off the time nearest to the mod 15
Calendar calendar = Calendar.getInstance();
calendar.setTime(date1);
int unroundedMinutes = calendar.get(Calendar.MINUTE);
int mod = unroundedMinutes % 15;
log.info calendar.add(Calendar.MINUTE, mod < 8 ? -mod : (15-mod));

Output :

Mon Dec 11 14:32:32 IST 2017:INFO:2017-12-11T14:32:32.690Z
Mon Dec 11 14:32:32 IST 2017:INFO:null

5
  • 1
    'currentTime' is of type String convert this to Date Commented Dec 11, 2017 at 8:48
  • After parsing to date, now output is 'null'.
    – rAJ
    Commented Dec 11, 2017 at 9:06
  • what you are getting from context.expand('${#Project#currentTime}')? Commented Dec 11, 2017 at 9:13
  • It's current datetime : 2017-12-11T13:11:51.728Z
    – rAJ
    Commented Dec 11, 2017 at 10:01
  • Are you using Java 8? If so, there are alternative data types to Date and Calendar
    – bdkosher
    Commented Dec 11, 2017 at 15:03

1 Answer 1

2

Here you go:

  • In order to get the difference minutes, created a closure.
  • The closure gets called recursively if needed.
  • If the current minutes is divisible by 15, it won't adjust the time; that is the reason for adding third value in the list.
  • To be able to test with multiple values, used list of dates. You may use it for single value as well.
def timez = ['2017-12-11T13:11:51.728Z', '2017-12-11T13:21:51.728Z', '2017-12-11T13:30:00.000Z']
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def roundValue = 15
//Change timezone if needed
def tz = 'IST'

TimeZone.setDefault(TimeZone.getTimeZone(tz))

Calendar calendar = Calendar.getInstance()

def getNearestMinutes
//Closure which gets called recursive
getNearestMinutes = { cmin, nearMin = roundValue ->
    def tempResult = cmin % nearMin
    if ( tempResult < nearMin && (0 < (nearMin - cmin)) ) {
        return (nearMin - cmin)
    } else { 
        return getNearestMinutes(cmin, nearMin+roundValue) 
    }
}


//Loop thru times and round the time
timez.each {
    calendar.time = Date.parse(dateFormat,it)
    def currentMinute = calendar.get(Calendar.MINUTE)
    def cof = currentMinute % roundValue
    if (cof) {
        currentMinute += getNearestMinutes(currentMinute)
        calendar.set(Calendar.MINUTE, currentMinute )
    }       
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)
    log.info calendar.time.format(dateFormat)   

}

You can quickly try it online demo

EDIT: Felt that the solution could be made something more simple than applying above difficult conditions.

Here is another solution to round time to near future 15 min. Yet, easy to read code unlike multiple conditions in the first solution. This is simple one using Switch statement

def timez = ['2017-12-11T13:11:51.728Z', '2017-12-11T13:21:51.728Z', '2017-12-11T13:30:00.000Z', '2017-12-11T13:46:00.000Z']
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def roundValue = 15
//Change timezone if needed
def tz = 'IST'

TimeZone.setDefault(TimeZone.getTimeZone(tz))

Calendar calendar = Calendar.getInstance()

def getNexTime = { min ->
  def result
  switch(min) {
    case 1..15: 
        result = 15
        break
    case 16..30:
        result = 30
        break
    case 31..45:
        result = 45
        break
    case 46..60:
        result = 60
        break
    default:
        result = 0
        break
  }
  result
}



//Loop thru times and round the time
timez.each {
    calendar.time = Date.parse(dateFormat,it)
    def currentMinute = calendar.get(Calendar.MINUTE)
    if (0 != getNexTime(currentMinute)) {
        calendar.set(Calendar.MINUTE, getNexTime(currentMinute) )
    }
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)
    println calendar.time.format(dateFormat)    
}
4
  • Thanks @Rao, Almost done...i only need output in this format (2017-12-11T13:15:00.000Z). Seconds and miliseconds should be zero.
    – rAJ
    Commented Dec 11, 2017 at 11:55
  • It is update just couple of minutes back check the changes by click in edit link below the solution or take it once again and try or try the demo.
    – Rao
    Commented Dec 11, 2017 at 11:57
  • Perfert. Thanks :)
    – rAJ
    Commented Dec 11, 2017 at 11:59
  • @rAJ, Thanks you find it useful. You may see the second solution which is more simple logic.
    – Rao
    Commented Dec 11, 2017 at 12:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.