2

公司的营业时间为上午 8 点至晚上 10 点。无论在文本字段中输入什么时间,下面的代码似乎都会增加 4 小时。因此,如果我将开放时间更改为 11:59,我会得到正确的上午 8 点开始日期,但无法将结束时间更改为 26:01,因此我无法让结束时间正常工作。数据必须以 UTC 格式存储在数据库中,但出于显示目的,它以 EST 格式显示。

public static boolean insideBusinessHours(String startTime, String endTime, String date) {

   
    LocalDateTime localStart = stringToLDT_UTC(startTime, date);
    LocalDateTime localEnd = stringToLDT_UTC(endTime, date);
    String UTCstart = localStart.toString().substring(11,16);
    String UTCend = localEnd.toString().substring(11,16);
    
    LocalTime enteredStart = LocalTime.parse(UTCstart);
    LocalTime enteredEnd = LocalTime.parse(UTCend);
    LocalTime openingHour = LocalTime.of(07, 59);
    LocalTime closingHour = LocalTime.of(22, 1);
    Boolean startTimeAllowed = enteredStart.isAfter(openingHour);
    Boolean endTimeAllowed = enteredEnd.isBefore(closingHour);

    if (startTimeAllowed && endTimeAllowed) {
        return true;
    }
    else {
        return false;
    }

}

public static LocalDateTime stringToLDT_UTC(String time, String date) {
    DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    LocalDateTime ldt = LocalDateTime.parse(date + " " + time, format)
            .atZone(ZoneId.systemDefault())
            .withZoneSameInstant(ZoneId.of("UTC"))
            .toLocalDateTime();
    return ldt;
}
4

1 回答 1

3

尽管日期和时间需要以 UTC 存储,但我相信在本地时间进行比较更有意义。

private static final LocalTime OPENING_HOUR = LocalTime.of(8, 0);
private static final LocalTime CLOSING_HOUR = LocalTime.of(22, 0);

public static boolean insideBusinessHours(String startTime, String endTime) {
    LocalTime start = LocalTime.parse(startTime);
    LocalTime end = LocalTime.parse(endTime);
    boolean startTimeAllowed = !start.isBefore(OPENING_HOUR);
    boolean endTimeAllowed = !end.isAfter(CLOSING_HOUR);
    return startTimeAllowed && endTimeAllowed;
}

进一步评论:

  • 如果开放时间每天都有效,则不需要日期(您需要将其转换为 UTC 或从 UTC 转换,这是我避免的)。
  • 似乎您在每一端都添加了一分钟,以确保开始和结束分别落在开始和结束时间。更正确的做法是要求开始时间落在开场时间开场时间之后。同样是结束时间之前或之后的结束时间。在我使用的代码中,not before表示on 或 after
  • 在 Java 中,以 0 开头的整数文字被解释为八进制。因此,除非您打算使用八进制,否则不要使用前导 0。您可能会发现07一天中的某个小时看起来不错。08但是当不工作时你会得到一个惊喜。0700 在不同的上下文中,当例如确实有效但表示 448时,您的用户可能会感到非常不愉快。
  • 不要使用Boolean物体。如果您可以避免它,请永远不要这样做,因为null引用 a的风险Boolean令人困惑,并且根据经验通常会导致错误。使用原语boolean(小写b)。
  • 大多数经验丰富的程序员更喜欢return startTimeAllowed && endTimeAllowed;比您的if-else语句更简洁。

关联

于 2021-09-04T12:18:48.860 回答