What Java library object encapsulate a number and `TimeUnit`?

1k views Asked by At

I want to pass around a time number and the TimeUnit it is in.

long number = some number;
TimeUnit timeUnit = some arbitrary time unit

What can hold both the time and timeUnit in one Object from the Java libraries?

3

There are 3 answers

2
The Coordinator On

There is no Java library object that encapsulates a number and an arbitrary TimeUnit. However, there is one in Java 8 that converts itself into whatever time unit is required:

java.time.Duration

Duration stores the provided quantity and then provides comparison and conversion to all other time units. For example:

// Create duration from nano time
Duration systemTime = Duration.ofNanos(System.nanoTime());

// Create duration from millis time
Duration systemTime = Duration.ofMillis(System.currentTimeMillis());

Of course, if doing addition and subtraction or other math operations, the precision is only as good as the precision of the current operation and the supplied Duration.

/**
* Example that tells if something has reached the required age
* TRUE IF THE current system time is older or equal to the required system time
*/
    // TRUE IF THE FILE HAS NOT WAITED ENOUGH TIME AFTER LAST CREATE/MODIFY
    private boolean isMature() {
        // it is not known whether required age is nanos or millis
        Duration requiredAge = systemTimeWhenMature();
        // so create a duration in whatever time unit you have
        // more precise = possibly better here
        Duration actualAge = Duration.ofNanos(System.nanoTime());
       // if ON or OLDER THAN REQUIRED AGE
       // actualAge - requiredAge  = balance
       // 20 - 21 = -1 (NOT MATURE)
       // 21 - 21 =  0 (OK)
       // 22 - 21 =  1 (OK)
       Duration balance = actualAge.minus(requiredAge);
       if (balance.isNegative()) {
           logger.info("Something not yet expired. Expires in {} millis.", balance.negated());
           return false;
       } else {
           return true;
       }
    }

And there are many more methods in Duration that are useful for converting and processing the stored quantity in various unit.

It is important to understand how the precision will affect calculations. This shows the general precision contract by example:

    // PICK A NUMBER THAT IS NOT THE SAME WHEN CONVERTED TO A LESSER PRECISION
    long timeNanos = 1234567891011121314L;
    long timeMillis = TimeUnit.MILLISECONDS.convert(timeNanos, TimeUnit.NANOSECONDS);

    // create from milliseconds
    Duration millisAccurate = Duration.ofMillis(timeMillis);
    Duration nanosAccurate = Duration.ofNanos(timeNanos);

    // false because of precision difference
    assertFalse(timeMillis == timeNanos);
    assertFalse(millisAccurate.equals(nanosAccurate));

    // true because same logical precision conversion takes place
    assertTrue(timeMillis - timeNanos <= 0);
    assertTrue(millisAccurate.minus(nanosAccurate).isNegative());

    // timeNanos has greater precision and therefore is > timeMillie
    assertTrue(timeNanos - timeMillis > 0);
    assertTrue(nanosAccurate.minus(millisAccurate).negated().isNegative());

In a nutshell .. I cannot believe it took me this long to find Duration! :)

0
LHA On

TimeUnit is just enum holding some time unit types like Second, Milliseconds, ...

TimeUnit is NOT for holding time BUT you can convert a time in a unit to another unit using TimeUnit API.

I think you have to create your object to hold time and its unit.

If you use Java 8. You can work with some new Date API

http://download.java.net/jdk8/docs/api/java/time/package-summary.html

0
Elliott Frisch On

In Joda-Time there is an Interval, but you'll need to create a Java Bean (perhaps calling it Interval) if you want to use only JRE inclusive Object types.