【问题标题】:Checking if a ZonedDateTime is between a certain time检查 ZonedDateTime 是否在某个时间之间
【发布时间】:2017-05-26 04:53:27
【问题描述】:

我正在使用下面的代码获取某个位置的时间和日期

        ZoneId zoneId = ZoneId.of("America/New_York");
        ZonedDateTime dateAndTimeForAccount = ZonedDateTime.ofInstant(now, zoneId);
        System.out.println(dateAndTimeForAccount);

如何检查dateAndTimeForAccount 是否在早上 6 点到 10 点之间?

【问题讨论】:

  • 请重新访问已接受的答案。对于“10:01”-“10:59”的边缘情况,它会返回 TRUE,这会影响新读者,他们会将其视为“6 到 10”的解决方案。

标签: java zoneddatetime


【解决方案1】:

一种可能的解决方案是使用ValueRange

注意:以下解决方案将导致 10:59true(请参阅最底部的“极端情况输出”:

ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime dateAndTimeForAccount = ZonedDateTime.ofInstant(now, zoneId);
System.out.println(dateAndTimeForAccount);

ValueRange hourRange = ValueRange.of(8, 10);
System.out.printf("is hour (%s) in range [%s] -> %s%n", 
        dateAndTimeForAccount.getHour(),
        hourRange, 
        hourRange.isValidValue(dateAndTimeForAccount.getHour())
);

示例输出

2017-01-11T07:34:26.932-05:00[America/New_York]
is hour (7) in range [8 - 10] -> false

edit:sn-p 指南作为建议解决方案的示例。这不是一个完整的解决方案,并且在代码中可见,它只检查小时部分。

极端情况输出: 结果为 true10:59

2017-01-11T10:59:59.999-05:00[America/New_York]
is hour (10) in range [8 - 10] -> true

【讨论】:

  • @epox 我从帖子中删除了您的编辑。 1) sn-p 清楚地表明它只考虑了小时部分(在代码和示例输出中)2) OP 接受了答案,所以看来 sn-p 足以找到他/她的解决方案
【解决方案2】:
int currentHour = dateAndTimeForAccount.getHour();
boolean isBetween6And10 = 6 <= currentHour && currentHour <= 10;

如果您想将其推广到任何特定的 java.time 类,您可以使用 TemporalQuery 类:

class HourTester extends TemporalQuery<Boolean> {
    @Override
    public Boolean queryFrom(TemporalAccessor temporal) {
        int hour = temporal.get(ChronoField.HOUR_OF_DAY);
        return 6 <= hour && hour <= 10;
    }
}

用法:boolean isBetween6And10 = dateAndTimeForAccount.query(new HourTester());

【讨论】:

    【解决方案3】:

    介于 6 am10 am 之间

    这对于 "99%" 的情况应该足够了,因为 "you" 不能保证 JVM 时钟的精度超过 1 毫秒。

        return 6 <= t.getHour() && t.getHour() < 10;
    

    介于6 to 10 am 之间

      static final LocalTime OPEN_TIME = LocalTime.of(06, 00);
      static final LocalTime CLOSE_TIME = LocalTime.of(10, 00);
    
        return !t.toLocalTime().isBefore(OPEN_TIME) && !t.toLocalTime().isAfter(CLOSE_TIME);
    

    6 to 10 am之间独占

        return t.toLocalTime().isAfter(OPEN_TIME) && t.toLocalTime().isBefore(CLOSE_TIME);
    

    证明:

      boolean isWithinSixToTen(ZonedDateTime t) {
        return 6 <= t.getHour() && t.getHour() < 10;
      }
    
    
    
    import static org.assertj.core.api.Assertions.assertThat;
    
      ZonedDateTime time(String time) {
        return ZonedDateTime.parse("2017-01-11" + "T" + time + "-05:00[America/New_York]");
      }
    
        assertThat(isWithinSixToTen(time("10:01"))).isFalse();
        assertThat(isWithinSixToTen(time("10:00"))).isFalse();
        assertThat(isWithinSixToTen(time("09:59:59.999999999"))).isTrue();
        assertThat(isWithinSixToTen(time("06:00"))).isTrue();
        assertThat(isWithinSixToTen(time("05:59"))).isFalse();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 1970-01-01
      相关资源
      最近更新 更多