我得到了这个异常:
java.time.format。DateTimeParseException: Text '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时间。
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()
使其显式。也许是多余的代码,但在这种情况下,这是毫无疑问的:通过清楚地说明正在应用默认值,使代码更容易阅读。例如,这很可能意味着您不必编写堆栈溢出答案。更短的代码并不总是更好的代码。