【问题标题】:DateTimeParseException - could not be parsed at index 15DateTimeParseException - 无法在索引 15 处解析
【发布时间】:2021-02-16 19:52:38
【问题描述】:

我得到了这个例外:

java.time.format.DateTimeParseException:文本'02/16/21 09:11 PM' 无法在索引 15 处解析

我在这里做错了什么?

    private fun extractTimestamp(date: String, time: String): Long {
        val formatter = DateTimeFormatter.ofPattern("MM/dd/yy hh:mm a")
        return LocalDateTime.parse("$date $time", formatter)
            .atZone(ZoneId.systemDefault())
            .toInstant().toEpochMilli()
    }

索引 15 位于“PM”,09:11 是有效的 AM/PM 时间。

【问题讨论】:

  • Locale.getDefault 在您的程序中返回什么?该代码适用于 en_US 语言环境。您可能希望将其显式传递给 ofPattern 方法
  • 我使用的是配置了英文的安卓设备,它返回 en_GB。

标签: android date datetime kotlin


【解决方案1】:

Java 有禁止的方法。你永远不应该打电话给他们。如果您的 IDE 能够在任何方法调用时生成警告,无论它出现在何处,请将这些方法添加到此列表中。

DateTimeFormatter.ofPattern(pattern) 就是其中之一。这是被禁止的。不要使用它。

问题是,它假定您系统的语言环境。在您的情况下,它假定为英国语言环境。让我们反过来练习:

LocalDateTime ldt = LocalDateTime.of(2021, 16, 2, 21, 11, 0);
System.out.println(ldt.format(DateTimeFormatter.ofPattern("MM/dd/yy hh:mm a", Locale.UK)));

>02/16/21 09:11 pm

// huh.

LocalDateTime ldt = LocalDateTime.of(2021, 16, 2, 21, 11, 0);
System.out.println(ldt.format(DateTimeFormatter.ofPattern("MM/dd/yy hh:mm a", Locale.ENGLISH)));

>02/16/21 09:11 PM

好吧,看看那个。显然,在英国地区,AM/PM 是小写的。

默认情况下,DTF 区分大小写。这就是这里的全部错误。如果您尝试使用小写 pm 进行解析,则它可以正常工作。您可以明确要求不区分大小写,但这不是这里的解决方法。语言环境可能是中文或日文,而 a 在那里的含义可能完全不同。

真正的解决方法是永远不要调用此方法,而是在您明确指定语言环境的地方使用覆盖。那个很好:

private fun extractTimestamp(date: String, time: String): Long {
        val formatter = DateTimeFormatter.ofPattern("MM/dd/yy hh:mm a", Locale.ENGLISH)
        return LocalDateTime.parse("$date $time", formatter)
            .atZone(ZoneId.systemDefault())
            .toInstant().toEpochMilli()
    }

我唯一改变的是在里面添加了, Locale.ENGLISH

有时您会面临实际使用平台默认设置的需要,例如在向用户呈现时间时。我强烈建议您仍然跳过这些方法,而是使用Locale.getDefault() 使其明确。也许是多余的代码,但在这种情况下,毫无疑问:通过明确应用默认值,这使您的代码更易于阅读。例如,这很可能意味着您不必编写堆栈溢出答案。更短的代码并不总是更好的代码。

【讨论】:

  • 谢谢!这真的很有帮助。我通常在我的设备上使用 en_US,但这个 en_GB 配置的设备揭示了一个我自己不太可能发现的问题。
猜你喜欢
  • 2020-06-10
  • 1970-01-01
  • 2019-02-15
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 2018-12-12
  • 2018-07-20
相关资源
最近更新 更多