【问题标题】:How to get open/close from opening hours by current time如何在当前时间从开放时间打开/关闭
【发布时间】:2018-04-10 10:41:36
【问题描述】:

我有一个关于在线餐厅订单的android 项目。我在时间逻辑上遇到了一些问题

我通过String 得知餐厅的营业或关闭时间:

  • 餐厅 1:open at "16:00"close at "02.00"
  • 餐厅 2:open at "02.00"close at "16:00"

如果这次at "18:00" 餐厅 1 应该开门了。

我已经像这样尝试过下面的代码, 但是餐厅 1 仍然关闭:

val open = "16:00"
val close = "02:00"
val calendar = Calendar.getInstance()
val time = calendar.time
val currentTime: String = SimpleDateFormat("HH:mm").format(time)

if(currentTime.compareTo(open) >= 0 currentTime.compareTo(close) < 0){
    // do something is open
}
else{
    // do something is close
}

我使用kotlin,也许有人可以帮助我也使用java

【问题讨论】:

  • 你确定 "currentTime.compareTo(open) >= 0 currentTime.compareTo(close)
  • 还是||?取决于关闭时间是否超过午夜。还有@ValentinMichalak
  • 我建议你避免使用SimpleDateFormat 类。它不仅过时了,而且出了名的麻烦。今天我们在java.time, the modern Java date and time API 的表现要好得多。

标签: java android time kotlin compare


【解决方案1】:

如果您要比较时间值(小时和分钟),则不应将它们作为字符串进行比较,而应作为它们真正代表的事物:一天中的时间。

在 java 中有 the java.time classes(在 JDK >= 8 中)。在旧版本中,Threeten backport 中提供了相同的类。

最初我以为我可以使用LocalTime(代表一天中的某个时间的类),但问题是当地时间从午夜开始到晚上 11:59 结束,所以它无法处理以餐厅 1 为例,该餐厅在次日关闭。

因此,您必须在LocalDateTime(表示日期和时间)或ZonedDateTime(如果您想考虑夏令时效果)之间进行选择。我使用的是后者,但两种类型的代码相似:

// timezone I'm working on (use JVM default, or a specific one, like ZoneId.of("America/New_York")
ZoneId zone = ZoneId.systemDefault();
// today
LocalDate today = LocalDate.now(zone);

// times
// 16:00
LocalTime fourPM = LocalTime.of(16, 0); // or LocalTime.parse("16:00") if you have a String
// 02:00
LocalTime twoAM = LocalTime.of(2, 0); // or LocalTime.parse("02:00") if you have a String

// restaurant 1: opens today 16:00, closes tomorrow 02:00
ZonedDateTime rest1Start = today.atTime(fourPM).atZone(zone);
ZonedDateTime rest1End = today.plusDays(1).atTime(twoAM).atZone(zone);

// restaurant 2: opens today 02:00, closes today 16:00
ZonedDateTime rest2Start = today.atTime(twoAM).atZone(zone);
ZonedDateTime rest2End = today.atTime(fourPM).atZone(zone);

// time to check
String timeToCheck = "18:00";
// set time - or use ZonedDateTime.now(zone) to get the current date/time
ZonedDateTime zdt = today.atTime(LocalTime.parse(timeToCheck)).atZone(zone);

// check if it's open
if (rest1Start.isAfter(zdt) || rest1End.isBefore(zdt)) {
    // restaurant 1 is closed
} else {
    // restaurant 1 is open
}
// do the same with restaurant 2

如果您不需要考虑 DST 更改,您可以使用 LocalDateTime - 只需省略对 atZone 的调用,结果是 LocalDateTime

【讨论】:

  • 好答案,但我建议更改您的代码示例以分别显式实例化 LocalTime 对象并作为参数传递。这将使逻辑更加清晰,因为 16:0002:00 值来自正在讨论的逻辑之外(由餐厅经理设置为业务政策)。
  • @BasilBourque 确实,这样的代码更好,谢谢!
  • 是的,如何将 t1 t2 变量命名为有意义的名称,例如 openingTimeclosingTime 或类似的餐厅贸易术语。
  • 因为 t1 是餐厅 1 的开店时间和餐厅 2 的关闭时间,不过我会想更好的名字,等等。。
  • 抱歉,ZoneId 需要 API 26,我无法申请 API 19
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 2023-03-25
  • 2012-02-18
  • 2018-08-21
  • 2016-07-16
相关资源
最近更新 更多