ben*_*rre 5 datetime localtime datetime-parsing java-8 java-time
当我尝试运行以下代码时:
LocalTime test = LocalTime.parse("8:00am", DateTimeFormatter.ofPattern("hh:mma"));
Run Code Online (Sandbox Code Playgroud)
我明白了:
Exception in thread "main" java.time.format.DateTimeParseException: Text '8:00am' could not be parsed at index 0
Run Code Online (Sandbox Code Playgroud)
知道为什么会这样吗?
小智 6
AM/PM模式是区域敏感的。如果您创建格式化程序但未设置java.util.Locale,它将使用 JVM 的默认值。无论如何,我已经检查了 JDK 1.8.0_144 并且没有使用小写am作为AM/PM字段文本的语言环境(我发现使用a.m.and 的语言环境AM,但没有使用am)。
因此,一种替代方法是设置使用AM(example: Locale.ENGLISH)的语言环境并使用 ajava.time.format.DateTimeFormatterBuilder构建不区分大小写的格式化程序。另一个细节是输入中的小时只有 1 位数字,因此您必须将模式更改为h(接受 1 位或 2 位数字,而hh仅接受2 位):
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// case insensitive
.parseCaseInsensitive()
// pattern
.appendPattern("h:mma")
// set Locale that uses "AM" and "PM"
.toFormatter(Locale.ENGLISH);
// now it works
LocalTime test = LocalTime.parse("8:00am", fmt);
Run Code Online (Sandbox Code Playgroud)
问题是语言环境也会影响其他字段(例如,如果您使用月份或星期几名称,或基于周的字段)。
另一个细节是格式化程序仅在解析时不区分大小写。格式化时,它将使用特定于语言环境的符号,在本例中为大写。所以这:
System.out.println(fmt.format(test)); // 8:00AM
Run Code Online (Sandbox Code Playgroud)
印刷:
8:00 AM
为了不依赖于语言环境,您可以使用此字段的自定义文本映射,使用java.time.temporal.ChronoField:
// map of custom text for AM/PM field
Map<Long, String> map = new HashMap<>();
// AM's value is 0
map.put(0L, "am");
// PM's value is 1
map.put(1L, "pm");
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// pattern (hour:minute)
.appendPattern("h:mm")
// use custom text for AM/PM
.appendText(ChronoField.AMPM_OF_DAY, map)
// create formatter, no need to set locale
.toFormatter();
// it also works
LocalTime test = LocalTime.parse("8:00am", fmt);
Run Code Online (Sandbox Code Playgroud)
与之前的格式化程序的不同之处在于它使用自定义文本(小写am和pm)进行解析和格式化。所以这段代码:
System.out.println(fmt.format(test)); // 8:00am
Run Code Online (Sandbox Code Playgroud)
将打印:
8:00 AM
AM/PM令牌*为大写:
LocalTime test = LocalTime.parse("8:00AM", DateTimeFormatter.ofPattern("hh:mma"));
Run Code Online (Sandbox Code Playgroud)
小时的模式定义:
Symbol Meaning Presentation Examples
------ ------------ ------------ --------
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
Run Code Online (Sandbox Code Playgroud)
DateTimeFormatter有关所有可用模式,请参阅javadoc:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
- 编辑
*根据@ Hugo的评论,这与您设置格式化程序的语言环境有关.如果未指定任何内容,则使用JVM默认值.只是发生了绝大多数Locales强制AM/PM令牌为大写:
碰巧的是,对于大多数语言环境,使用大写的AM,因此它适用于大多数人.但它也可以是ga_IE和es_US语言环境,日语中的午前(ja_JP),瑞典语中的fm(sv_SE)以及许多其他语言.我已经在JDK 1.8.0_144中进行了测试,它有160个语言环境 - 其中108个使用AM - 无论如何,如果您的JVM使用其中一个108个语言环境(并且没有人更改此配置),这不是问题
AM/PM 为大写,需要用h一位数来表示小时(需要hh两位数)。喜欢,
LocalTime test = LocalTime.parse("8:00am".toUpperCase(),
DateTimeFormatter.ofPattern("h:mma"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1832 次 |
| 最近记录: |