Round minutes to ceiling using Java 8

user432024 picture user432024 · Aug 28, 2014 · Viewed 27.8k times · Source

So I'm lucky enough to use Java 8 and the new time APi but I don't see any rounding functions...

Basically if the time is...

2014-08-28T10:01.00.000 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.10.123 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.25.123 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.49.123 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.59.999 ----> 2014-08-28T10:02.00.000

This seems to be ok, but is it right?

LocalDateTime now =  LocalDateTime.now(Clock.systemUTC());
LocalDateTime newTime =  now.plusMinutes(1);

System.out.println(newTime.toString());
System.out.println(newTime.format(DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:00.000")));

Answer

JodaStephen picture JodaStephen · Aug 28, 2014

The java.time API does not support rounding to ceiling, however it does support rounding to floor (truncation) which enables the desired behaviour (which isn't exactly rounding to ceiling):

LocalDateTime now =  LocalDateTime.now();
LocalDateTime roundFloor =  now.truncatedTo(ChronoUnit.MINUTES);
LocalDateTime roundCeiling =  now.truncatedTo(ChronoUnit.MINUTES).plusMinutes(1);

In addition, there is a facility to obtain a clock that only ticks once a minute, which may be of interest:

Clock minuteTickingClock = Clock.tickMinutes(ZoneId.systemDefault());
LocalDateTime now =  LocalDateTime.now(minuteTickingClock);
LocalDateTime roundCeiling =  now.plusMinutes(1);

This clock will automatically truncate minutes to floor (although it is specified such that it may return a delayed cached value). Note that a Clock may be stored in a static variable if desired.

Finally, if this is a common operation that you want to use in multiple places, it is possible to write a library TemporalAdjuster function to perform the rounding. (Adjusters can be written once, tested, and made available as a static variable or method).