【问题标题】:Java Check wether Beginning and End Dates are within intervalJava检查开始日期和结束日期是否在间隔内
【发布时间】:2018-11-20 02:18:36
【问题描述】:

我必须检查预订的开始日期和结束日期是否在用户选择的时间跨度之间。因此,如果用户说他想查看从 2 月 12 日到 2 月 15 日的所有预订,它应该只显示该时间段内的预订。我只是想不通,我希望有人能帮助。这是我迄今为止的尝试:

    Timestamp tsBeginning = new Timestamp(dateBeginning.getTime()); //date entered by user
    Timestamp tsEnd = new Timestamp(dateEnd.getTime()); //date entered by user

for (Booking b : bookingList) {
                if(((b.getBeginning().after(tsBeginning) || b.getBeginning().equals(tsBeginning)) && b.getBeginning().before(tsEnd) || b.getBeginning().equals(tsEnd)) 
                        && ((b.getEnd().after(tsEnd) || b.getEnd().equals(tsEnd)) && (b.getEnd().before(tsEnd) || b.getEnd().equals(tsEnd)))){
                    bookingsForRoomInPeriod.add(b);

【问题讨论】:

  • 如果预订与边界重叠,您可能希望将其包括在内,对吗?用户选择 2 月 12 日 15:00 到 2 月 15 日 21:00 有一个预订 2 月 12 日 14 到 16 日——是否应该包括在内?
  • 如果您使用的是 sql,您应该只使用数据库查询来过滤这些日期范围
  • 一旦你开始混合&& 和|| 而不用括号将它们分组,我认为出错的可能性很高。您可能想用一些括号来说明您希望它们执行的顺序。
  • 另外,我会打破那个巨大的if 声明,让一些更容易阅读的帮助方法为你做一些检查(比如一个日期是否与另外两个日期一起),这样整个事情变得更容易阅读。我认为操作顺序(括号)和一长串逻辑运算符会让您感到困惑。
  • 我一般觉得写if(...) { /* before */ } else if (...) { /* after */ } else { /* in range */ }这种东西最好看。尝试这种方式,您可能会发现逻辑更易于阅读。如果添加新的成员函数,那么你可以写if(!booking.endsBefore(...) && !booking.startsAfter(...)){...。

标签: java sql date intervals


【解决方案1】:

编辑:讨论了很长时间。我似乎终于明白了:预订在一天中的某个日期和一个小时开始和结束(例如 6 月 14 日下午 3:30)。用户输入开始日期和结束日期,但没有小时。您需要包含完全包含在含日期范围内的预订。也就是说,在开始日期的 00:00 和结束日期的 24:00 之间。

      LocalDate userBeginning = // …
      LocalDate userEnd = // …
      LocalDateTime userBeginningTime = userBeginning.atStartOfDay();
      LocalDateTime userEndTime = userEnd.plusDays(1).atStartOfDay();

      if (! b.getBeginning().isBefore(userBeginningTime)
                && ! b.getEnd().isAfter(userEndTime)) {
          bookingsForRoomInPeriod.add(b);
      }

我假设getBeginning 和getEnd 返回LocalDateTime。在 Java 中,“一天的结束”(午夜)表示为第二天 00:00,这就是为什么我在用户输入的结束日期上加上 1 天。

您似乎正在使用的Timestamp 类早已过时。 java.time 是现代 Java 日期和时间 API,比老式日期和时间类更易于使用。 java.sql 中的日期和时间类尤其具有丑陋的设计,半路试图隐藏它们是(同样设计不佳的)java.util.Date 的子类。

假设您选择 Timestamp 是因为您从数据库中获取时间,并且假设您至少可以使用 Java 8 和至少 JDBC 4.2,请使用 @987654331 之一直接从您的结果集中获取 LocalDateTime 对象@ 方法传递 LocalDateTime.class 作为你想要的类型。

以前版本的答案:

……只有日期与时间无关,而且只有符合条件的预订 完全在用户选择的时间戳内应该是 包括

      if (! b.getBeginning().before(tsBeginning) && ! b.getEnd().after(tsEnd)) {
           bookingsForRoomInPeriod.add(b);
      }

我使用“not before”作为要求“on or after”的简短方式。同样,我用“not after”来表示“before or on”。

也就是说,您似乎正在使用的 Timestamp 类早已过时,并且不适合没有时间的日期。使用没有时间的数据库数据类型(在大多数 RDBMS 中,它简称为 date),而在 Java 中使用 java.time 中的 LocalDate。 java.time 是现代 Java 日期和时间 API,比老式日期和时间类更易于使用。 java.sql 中的日期和时间类尤其具有丑陋的设计,半路试图隐藏它们是(同样设计不佳的)java.util.Date 的子类。

【讨论】:

  • 是的,我正在使用时间戳,因为我从数据库中获取了我的预订时间,我尝试了您的代码,但现在它还包括在 userBegninning 之前和在 UserEnd 之后结束的日期(例如预订开始2018-06-08 和 2018-06-22 结束),但由于某种原因根本不包括仅持续一天的预订
  • 在这种情况下,您没有足够清楚地解释您想要的结果。预订日期和时间是否重要?是否应该只包括完全在用户选择的时间戳内的预订?请编辑您的问题以使其清楚。
  • 是的,只有日期与时间无关,只有完全在用户所选时间戳内的预订才应包括在内,抱歉英语不是我的母语,所以有时很难告诉别人什么我想做:D
  • 现在一切正常,但最后一天的预订仍然不包括在内,所以如果用户说从 2018-06-15 到 2018-06-15,日期仍然没有显示
  • 预订可以在同一日期开始和结束吗?零夜?在我对您的要求的理解中,这听起来像是一个错误。
猜你喜欢
  • 2019-07-11
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 2017-12-29
相关资源
最近更新 更多