Вы можете реализовать пользовательский TemporalUnit
, основанный на произвольном (положительном) Duration
. Вы можете использовать его так же, как и любой другой встроенный ChronoUnit
, например,
LocalTime start = LocalTime.parse("08:00");
LocalTime end = LocalTime.parse("10:00");
DurationUnit min15 = DurationUnit.ofMinutes(15);
System.out.println(min15.between(start, end)); // prints: 8
System.out.println(start.until(end, min15)); // prints: 8
System.out.println(start.plus(3, min15)); // prints: 08:45
DurationUnit min7 = DurationUnit.ofMinutes(7);
System.out.println(min7.between(start, end)); // prints: 17
System.out.println(start.until(end, min7)); // prints: 17
System.out.println(start.plus(3, min7)); // prints: 08:21
Пользовательский TemporalUnit
:
public final class DurationUnit implements TemporalUnit {
private static final int SECONDS_PER_DAY = 86400;
private static final long NANOS_PER_SECOND = 1000_000_000L;
private static final long NANOS_PER_DAY = NANOS_PER_SECOND * SECONDS_PER_DAY;
private final Duration duration;
public static DurationUnit of(Duration duration) { return new DurationUnit(duration); }
public static DurationUnit ofDays(long days) { return new DurationUnit(Duration.ofDays(days)); }
public static DurationUnit ofHours(long hours) { return new DurationUnit(Duration.ofHours(hours)); }
public static DurationUnit ofMinutes(long minutes) { return new DurationUnit(Duration.ofMinutes(minutes)); }
public static DurationUnit ofSeconds(long seconds) { return new DurationUnit(Duration.ofSeconds(seconds)); }
public static DurationUnit ofMillis(long millis) { return new DurationUnit(Duration.ofMillis(millis)); }
public static DurationUnit ofNanos(long nanos) { return new DurationUnit(Duration.ofNanos(nanos)); }
private DurationUnit(Duration duration) {
if (duration.isZero() || duration.isNegative())
throw new IllegalArgumentException("Duration may not be zero or negative");
this.duration = duration;
}
@Override
public Duration getDuration() {
return this.duration;
}
@Override
public boolean isDurationEstimated() {
return (this.duration.getSeconds() >= SECONDS_PER_DAY);
}
@Override
public boolean isDateBased() {
return (this.duration.getNano() == 0 && this.duration.getSeconds() % SECONDS_PER_DAY == 0);
}
@Override
public boolean isTimeBased() {
return (this.duration.getSeconds() < SECONDS_PER_DAY && NANOS_PER_DAY % this.duration.toNanos() == 0);
}
@Override
@SuppressWarnings("unchecked")
public <R extends Temporal> R addTo(R temporal, long amount) {
return (R) this.duration.multipliedBy(amount).addTo(temporal);
}
@Override
public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
return Duration.between(temporal1Inclusive, temporal2Exclusive).dividedBy(this.duration);
}
@Override
public String toString() {
return this.duration.toString();
}
}