package nl.andrewlalis.simply_scheduled.schedule; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.Optional; /** * An hourly schedule is used to execute a task once per hour, at a specific * minute of the hour. */ public class HourlySchedule implements Schedule { private final ZoneId zoneId; private final int minute; public HourlySchedule(int minute) { this(minute, ZoneId.systemDefault()); } public HourlySchedule(int minute, ZoneId zoneId) { if (minute < 0 || minute > 59) { throw new IllegalArgumentException("Minute must be in the range [0, 59]."); } this.zoneId = zoneId; this.minute = minute; } @Override public Optional<Instant> getNextExecutionTime(Instant referenceInstant) { ZonedDateTime currentTime = referenceInstant.atZone(this.zoneId); int currentMinute = currentTime.getMinute(); if (currentMinute < this.minute) { return Optional.of(currentTime.truncatedTo(ChronoUnit.MINUTES).plusMinutes(this.minute - currentMinute).toInstant()); } return Optional.of(currentTime.plusHours(1).plusMinutes(this.minute).truncatedTo(ChronoUnit.MINUTES).toInstant()); } }