Data/src/main/java/de/ph87/data/series/Alignment.java

60 lines
2.0 KiB
Java

package de.ph87.data.series;
import lombok.*;
import java.time.*;
import java.time.temporal.*;
import java.util.function.*;
public enum Alignment {
FIVE(t -> t.truncatedTo(ChronoUnit.MINUTES).minusMinutes(t.getMinute() % 5), Duration.ofMinutes(5), Duration.ofMinutes(5)),
HOUR(t -> t.truncatedTo(ChronoUnit.HOURS), Duration.ofHours(1), Duration.ofHours(1)),
DAY(t -> t.truncatedTo(ChronoUnit.DAYS), Duration.ofDays(1), Duration.ofDays(1)),
WEEK(t -> t.truncatedTo(ChronoUnit.DAYS).minusDays(t.getDayOfWeek().getValue() - 1), Period.ofWeeks(1), Duration.ofDays(7)),
MONTH(t -> t.truncatedTo(ChronoUnit.DAYS).minusDays(t.getDayOfMonth() - 1), Period.ofMonths(1), Duration.ofDays(31)),
YEAR(t -> t.truncatedTo(ChronoUnit.DAYS).minusDays(t.getDayOfYear() - 1), Period.ofYears(1), Duration.ofDays(366)),
;
@NonNull
public final Function<ZonedDateTime, ZonedDateTime> align;
@NonNull
public final TemporalAmount amount;
@NonNull
public final Duration maxDuration;
Alignment(@NonNull final Function<@NonNull ZonedDateTime, @NonNull ZonedDateTime> align, @NonNull final TemporalAmount amount, @NonNull final Duration maxDuration) {
this.maxDuration = maxDuration;
this.align = align;
this.amount = amount;
}
@NonNull
public Aligned align(@NonNull final ZonedDateTime date) {
return new Aligned(this, date);
}
@NonNull
public ZonedDateTime plus(@NonNull final ZonedDateTime date, final long amount) {
return date.plus(multiplyAmount(amount));
}
@NonNull
@SuppressWarnings("unused")
public ZonedDateTime minus(@NonNull final ZonedDateTime date, final long amount) {
return plus(date, -amount);
}
@NonNull
public TemporalAmount multiplyAmount(final long amount) {
if (this.amount instanceof final Duration duration) {
return duration.multipliedBy(amount);
} else if (this.amount instanceof final Period period) {
return period.multipliedBy((int) amount);
}
throw new RuntimeException("Cannot multiply unimplemented TemporalAmount: %s".formatted(this.amount));
}
}