显示日期/时间剩余当前时间

时间:2021-05-11 02:56:37

标签: java android date kotlin

我正在尝试创建一个函数来向我发送一个字符串,该字符串表示餐厅的营业状态,例如:“营业”、“营业”、“22 分钟”

我将关闭时间显示为:2021-05-11T06:45:00Z

我想根据当前时间进行比较,但不起作用。

我已经完成了下面的代码:

fun getCloseTime(ctx: Context): String? {
    val timeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH)
    val diff: Duration = Duration.between(
            LocalTime.parse(next_close_time, timeFormatter),
            LocalTime.parse(getISO8601StringForDate(), timeFormatter))
    return when {
        (diff.toDays().toInt() > 0 ) || (diff.toHours() > 0) -> "Open"
        (diff.toMinutes().toInt() <= 60) -> diff.toMinutes().toString()
        else -> ctx.getString(R.string.closed)
    }
}

private fun getISO8601StringForDate(): String? {
    val now = Date()
    val dateFormat: DateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
    return dateFormat.format(now)
}

我的目标是:

  • 当前在 next_close_time 之后返回“Closed”
  • next_close_timecurrent 之间的差异超过一个小时时,我们显示“打开”
    • next_close_timecurrent 之间的差异小于一个小时时,我们以分钟为单位显示关闭前的剩余时间

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

不仅您的代码中存在错误,而且还有一些简化的机会。

  • 错误:您的持续时间符号错误。您正在计算从关闭时间到当前时间的持续时间,因此,如果我们之前关闭,则为正值,如果关闭时间晚,则为负值。我相信你的意图正好相反。因此,将两个参数交换为 Duration.between()
  • 错误和简化机会: getISO8601StringForDate() 返回错误的解析格式。当我运行你的代码时,我得到了一个像 java.time.format.DateTimeParseException: Text '2021-05-11T13:27:20Z' could not be parsed at index 2 这样的异常,因为引用的字符串与你的格式模式 hh:mm a 不匹配。没有理由仅仅为了解析它而在 UTC 中格式化当前时间。相反,只需从 LocalTime.now(ZoneOffset.UTC) 获取 UTC 中的当前时间,而根本不使用 getISO8601StringForDate()
  • 简化的机会:如果 diff.toDays().toInt() > 0true,那么 diff.toHours() > 0 也必然是,所以你只需要后一个条件。
  • 错误:如果我们没有进入持续时间至少为整整一小时的第一种情况,那么 diff.toMinutes().toInt() <= 60总是{{ 1}}。相反,此时您需要测试的是 true 是否为正数(大于 0)。您可以使用 diff(如果我正确理解 Kotlin not(diff.isNegative()))。

PS 正如我在此上下文中所说的,您不需要 ISO 8601 格式的 UTC 当前时间点。如果有一天有人需要它,获得它的方法很简单:

not()

这将返回一个类似 return Instant.now().toString() 的字符串,这很好,因为根据 ISO 8601 标准,秒的小数部分是可选的。

链接:Wikipedia article: ISO 8601