在给定的时间内获得先前的瞬间

时间:2016-11-07 12:25:13

标签: java-8 java-time

我在7:45有一个叫醒时间。我希望我的代码返回前一个时刻,这是当地时间(即之前的唤醒时间)

我知道我可以这样做:

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

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

2 个答案:

答案 0 :(得分:3)

可以编写TemporalAdjuster,允许代码读作:

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(没有时区的日期或时间)。

答案 1 :(得分:0)

根据@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");
        }
    };
}