Java 9. Where “forever” is hard coded.

In Java 9 we can find two new methods in the TimeUnit class.

public ChronoUnit toChronoUnit();
public static TimeUnit of(ChronoUnit chronoUnit);

Now, conversion between those two types is trivial. If both types are identical, why there are two types instead of one?

TimeUnit (since Java 5)

This enumeration started with only four elements: NANOSECONDS, MICROSECONDS, MILLISECONDS and SECONDS. In Java 6, three more elements appear: MINUTES, HOURS, DAYS. Usage is quite popular among methods that are expecting time-based arguments. For example tryLock from java.util.concurrent.

lock.tryLock(50L, TimeUnit.MILLISECONDS);

There is also one very popular sleep method. In most cases used in a wrong way. Usually kills apps or tests performance:

TimeUnit.SECONDS.sleep(1L);

ChronoUnit (since Java 8)

Dedicated to use for date or time related operations. Immutable. Defines much more duration types (i.e.: HALF_DAYS, DECADES). ChronoUnit defines element called FOREVER:

FOREVER("Forever", Duration.ofSeconds(Long.MAX_VALUE, 999_999_999));

In other words, Java defines forever as 9 223 372 036 854 775 807 seconds. Which is 2.92277266 × 10¹¹ years. Better be sure to schedule Java upgrade in your application before times run out.

Not compatible in both directions

Since TimeUnit is smaller (less enumeration elements) than ChronoUnit. It is not possible to convert some of the ChronoUnit instances. Trying to do something like this is going to produce IllegalArgumentException:

TimeUnit.of(ChronoUnit.HALF_DAYS);

So, converting from the TimeUnit to ChronoUnit is always safe.

Ok, so what’s worth to rememeber?

TimeUnit is coupling code related with threading. It provides quite efficient but rather trivial conversions (i.e.: toSeconds, toNanos). ChronoUnit is much more powerful. It is trying to meet all non-trivial time/date/calendar requirements. Since Java 9 there is easy way to convert between them.