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

Java 8 获取一天中给定时间的前一个瞬间,java-8,java-time,Java 8,Java Time,我七点四十五分起床。我想让我的代码返回上一时刻的时间,当这是当地时间(即上一个唤醒时间) 我知道我能做到: LocalTime wakeUpTime = LocalTime.of(7, 45); ZonedDateTime now = ZonedDateTime.now(); ZonedDateTime todaysWakeUpTime = now.with(wakeUpTime); ZonedDateTime lastWakeUpTime; if(todaysWakeUpTime.isAft

我七点四十五分起床。我想让我的代码返回上一时刻的时间,当这是当地时间(即上一个唤醒时间)

我知道我能做到:

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);

是否有更干净的版本,例如使用时间调节器,更好地传达意图(获得最后一次)?

可以编写一个
时间调节器,允许代码读取为:

LocalTime wakeUpTime = LocalTime.of(7, 45);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime lastWakeUpTime = now.with(previousTime(wakeUpTime));
在某些地方,您需要编写一个实现adjsuter的静态方法:

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

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

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


最干净的方法是拥有一个内置的特性,这样您就不需要自己编写整个代码。当然,您可以编写一个调整器并重用它(但是请注意包含时态调整器的类/方法的命名,否则您可能很难再次找到它,因为这个问题是所有静态助手类/工具固有的)。旁注:我的时间库Time4J已经支持这个开箱即用的特性(即使使用编译时的typesafety),请参见
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");
        }
    };
}