获取一天中给定时间的前一瞬间

Getting previous instant with given time of day

我的起床时间是 7:45。我希望我的代码 return 这是当地时间的前一个时刻(即前一个唤醒时间)

我知道我能做到:

LocalTime wakeUpTime = LocalTime.of(7, 45);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime todaysWakeUpTime = now.with(wakeUpTime);
ZonedDateTime lastWakeUpTime;

if(todaysWakeUpTime.isAfter(now)){
    // e.g. it is now 4:30, so wake-up is still to come, 
    // return the one from yesterday
    lastWakeUpTime = todaysWakeUpTime.minusDays(1);
} else {
    // e.g. it is now 11:30, so wake-up for today is already past
    lastWakeUpTime = todaysWakeUpTime;
}

System.out.println(lastWakeUpTime);

是否有更简洁的版本,例如使用时间调整器,哪个更好地传达了意图(获得这些时间中的最后一个)?

A TemporalAdjuster 可以写成允许代码读作:

LocalTime wakeUpTime = LocalTime.of(7, 45);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime lastWakeUpTime = now.with(previousTime(wakeUpTime));

你需要在某处编写一个实现调整器的静态方法:

public static TemporalAdjuster previousTime(LocalTime time) {
    return temporal -> {
        // logic to find the previous occurrence of the time
    };
}

实现逻辑将需要决定当输入是不同类型的时间时要做什么,例如LocalDate(没有时间,所以不能工作),LocalTime(没有日期,所以没有更早的),ZoneDateTime(夏令时更改如何),Instant(没有时区的日期或时间)。

根据@JodaStephen 的回答(谢谢!),这是我的调节器(供参考):

public static TemporalAdjuster previousTime(LocalTime time){
    return (temporal) -> {
        if (temporal instanceof ZonedDateTime) {
            ZonedDateTime zdt = (ZonedDateTime) temporal;
            ZonedDateTime newTime = zdt.with(time);
            if(newTime.isAfter(zdt)){
                newTime = newTime.minusDays(1);
            }
            return newTime;
        } else {
            throw new DateTimeException("This adjuster only handles ZonedDateTime");
        }
    };
}