Reputation: 4564
I'm migrating some signatures from f(long dur, TimeUnit timeUnit)
to f(Duration duration)
, and would like to implement the former with the latter.
Being on Java 8, I can't find any API to easily convert the long
+TU
to a Duration
, the only idea that comes to me is to do something ugly like:
static Duration convert(long dur, TimeUnit timeUnit) {
switch (timeUnit) {
case DAYS:
return Duration.ofDays(dur);
case HOURS:
/* alternative, but (again) I don't have an easy conversion from TimeUnit -> ChronoUnit */
return Duration.of(dur, ChronoUnit.HOURS);
case ..... /* and so on */
}
}
Or did I miss some API?
Upvotes: 8
Views: 5641
Reputation: 29058
You can use static method Duration.of(long, TemporalUnit)
.
It expects an amount as long
, and a TemporalUnit
, so you need to convert the TimeUnit into ChronoUnit.
static Duration convert(long dur, TimeUnit timeUnit) {
return Duration.of(dur, timeUnit.toChronoUnit());
}
Method toChronoUnit()
was introduced in JDK version 9.
With Java 8 you can translate TimeUnit
into ChronoUnit
using ThreeTen library's utility method Temporals.chronoUnit(TimeUnit)
.
If you don't want to introduce a dependency on this library in your project, you can make use of the utility method provided in the answer by Paul.
Upvotes: 12
Reputation: 20091
You're on the right track. Since you think the right track is ugly the solution is to hide the ugliness! Here's the implementation of TimeUnit.toChronoUnit()
from OpenJDK:
/**
* Converts this {@code TimeUnit} to the equivalent {@code ChronoUnit}.
*
* @return the converted equivalent ChronoUnit
* @since 9
*/
public ChronoUnit toChronoUnit() {
switch (this) {
case NANOSECONDS: return ChronoUnit.NANOS;
case MICROSECONDS: return ChronoUnit.MICROS;
case MILLISECONDS: return ChronoUnit.MILLIS;
case SECONDS: return ChronoUnit.SECONDS;
case MINUTES: return ChronoUnit.MINUTES;
case HOURS: return ChronoUnit.HOURS;
case DAYS: return ChronoUnit.DAYS;
default: throw new AssertionError();
}
}
To keep your code cleaner I would implement a static utility method based on above (i.e. pass in a TimeUnit
parameter) and get the ChronoUnit
without doing a conversion in each case
. You'll end up with 1 call to Duration.of(long amount, TemporalUnit unit)
and your code will be as beautiful as if you were using Java 9+!
Upvotes: 2
Reputation: 4564
For Java 8 there is a roundabout solution :\
(we unnecessarily convert from our TU -> millis (or whatever unit) -> Duration) like this:
long dur = ...
TimeUnit unit = ...
Duration result = Duration.ofMillis(unit.toMillis(dur));
Caveat emptor with extremely large values though, Long.MAX_VALUE
days cannot be correctly converted into long millis
(compared to Duration
's ctor that does throw when trying to init with such a value):
final long millis = TimeUnit.DAYS.toMillis(Long.MAX_VALUE); // ouch
final Duration dur = Duration.ofMillis(dur);
System.err.println(dur.toDays() == Long.MAX_VALUE); // returns 'false'
Upvotes: 5