new SimpleDateFormat("hh:mm a", Locale.getDefault()).parse("04:30 PM") 给出无法解析的异常

new SimpleDateFormat("hh:mm a", Locale.getDefault()).parse("04:30 PM") giving Unparseable exception

最绝望的时候总会发生奇怪的事情。

我在这行代码中遇到了一些奇怪的事情

Date time = new SimpleDateFormat("hh:mm a", Locale.getDefault()).parse("04:30 PM");

正在给予

"Unparseable date: \"04:30 PM\" (at offset 6)"

仅在 Android 6.0 和 Android 6.0.1 设备中出现异常,在生产应用程序中(在 Google Play 商店)。

PS:我无法在 Android 6.0 模拟器和 HTC Desire 10 Pro Android 6.0.1 上重新生成此错误。 任何帮助在本地重新生成此错误或如何绕过它的方法将不胜感激。

编辑:2018 年 11 月 15 日 给出此异常的设备。

OS Version: 3.4.0-10662519 (G900FXXS1CQD8) OS API Level: 23 Device: klte Model (and Product): SM-G900F (kltexx) Manufacturer: samsung Other TAGS: release-keys SD Card state: mounted http.agent = Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-G900F Build/MMB29M)

OS Version: 3.10.84 (v1AJW-0) OS API Level: 23 Device: idol4 Model (and Product): 6055K (6055K) Manufacturer: TCL Other TAGS: release-keys SD Card state: mounted http.agent = Dalvik/2.1.0 (Linux; U; Android 6.0.1; 6055K Build/MMB29M)

OS Version: 3.10.84-g05b37ae (16293194481ff) OS API Level: 23 Device: p1 Model (and Product): LG-H818 (p1_global_com) Manufacturer: LGE Other TAGS: release-keys SD Card state: mounted http.agent = Dalvik/2.1.0 (Linux; U; Android 6.0; LG-H818 Build/MRA58K)

字符串的偏移量 6 是 PM.

的位置

这是一个地区问题。 AMPM,虽然源自拉丁语,但在英语中被称为,在许多其他语言中并不如此。因此,这些缩写在很多地方都无法识别。在您的代码中,您使用 Locale.getDefault(),如果它 returns 是非英语语言环境,您很可能会收到错误消息。例如尝试 Locale.ENGLISH。或者,请确保您获得的字符串格式和语言适用于默认语言环境。

java.time

如果您正在对应用程序中的时间或日期做任何重要的工作,以及任何为 Java 8 或更高版本或 Android API 26 级或更高级别编程的人: 您使用的 classes,DateSimpleDateFormat,一直存在设计问题,尤其是后者通常很麻烦。幸运的是,两者现在都已经过时了,取而代之的是 java.time,现代的 Java 日期和时间 API。所以改用这个:

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
    LocalTime time = LocalTime.parse("04:30 PM", timeFormatter);
    System.out.println(time);

输出:

16:30

A LocalTime 是一天中没有日期和时区的时间,似乎比老式的 Date class.[=30= 更符合您的需要]

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置了现代 API。
  • 在 Java 6 和 7 中获取 ThreeTen Backport,新 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接