Kri*_*ris 4 java datetime date-parsing java-8 java-time
使用'old',Java 8之前SimpleDateFormat我可以做到:
new java.text.SimpleDateFormat("MMM yyyy", new java.util.Locale("es", "ES")).parse("Mayo 2017")
Run Code Online (Sandbox Code Playgroud)
获取Date具有西班牙月份名称的日期对象.
如何使用Java 8实现相同的功能DateTimeFormatter?
我试过了:
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(new Locale("es", "ES")).ofPattern("MMM yyyy").parse("Mayo 2017")
Run Code Online (Sandbox Code Playgroud)
但只得到一个java.time.format.DateTimeParseException.
小智 9
ofLocalizedDateTime()可以删除调用,因为最后你调用ofPattern(),创建另一个格式ofLocalizedDateTime(FormatStyle.FULL)函数与完全不同的模式(返回的模式与just非常不同month year,所以这不是你想要的).
另一个细节是Mayo完整的月份名称,因此模式必须是MMMM(检查javadoc以获取更多详细信息).此外,DateTimeFormatter默认情况下,只接受小写名称(至少在我使用西班牙语语言环境进行的测试中),因此您必须将格式化程序设置为不区分大小写.
您可以使用以下方法执行此操作java.time.format.DateTimeFormatterBuilder:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// case insensitive
.parseCaseInsensitive()
// pattern with full month name (MMMM)
.appendPattern("MMMM yyyy")
// set locale
.toFormatter(new Locale("es", "ES"));
// now it works
fmt.parse("Mayo 2017");
Run Code Online (Sandbox Code Playgroud)
或者,你可以直接将它解析为一个java.time.YearMonth对象,因为它似乎是这种情况的最佳选择(因为输入只有年和月):
YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
System.out.println(ym); // 2017-05
Run Code Online (Sandbox Code Playgroud)
当输入没有所有字段时,SimpleDateFormat只需为它们使用一些默认值.在这种情况下,输入只有年和月,因此解析后的数字Date将等于解析的月/年,但是日期将设置为1,时间设置为午夜(在JVM默认时区).
新API对此非常严格,除非您告诉它,否则不会创建默认值.配置它的方法之一是使用parseDefaulting了java.time.temporal.ChronoField:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// case insensitive
.parseCaseInsensitive()
// pattern with full month name (MMMM)
.appendPattern("MMMM yyyy")
// default value for day of month
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
// default value for hour
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
// default value for minute
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
// set locale
.toFormatter(new Locale("es", "ES"));
Run Code Online (Sandbox Code Playgroud)
使用此功能,您可以将其解析为a LocalDateTime,并将缺少的字段分配给相应的默认值:
LocalDateTime dt = LocalDateTime.parse("Mayo 2017", fmt);
System.out.println(dt); // 2017-05-01T00:00
Run Code Online (Sandbox Code Playgroud)
如果您需要获取java.util.Date与创建的值相同的值,则SimpleDateFormat可以将其转换LocalDateTime为JVM默认时区,然后将其转换为Date:
Date javaUtilDate = Date.from(dt.atZone(ZoneId.systemDefault()).toInstant());
Run Code Online (Sandbox Code Playgroud)
请注意,我必须明确使用JVM默认时区(ZoneId.systemDefault()),这是由使用的隐含SimpleDateFormat.
另一种方法是手动设置值中的YearMonth值:
// in this case, the formatter doesn't need the default values
YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
ZonedDateTime z = ym
// set day of month to 1
.atDay(1)
// midnight at JVM default timezone
.atStartOfDay(ZoneId.systemDefault());
Date javaUtilDate = date.from(z.toInstant());
Run Code Online (Sandbox Code Playgroud)
即使在运行时,也可以在不事先通知的情况下更改默认时区,因此最好始终明确指出您正在使用的时区.
API使用IANA时区名称(始终采用格式Region/City,如America/New_York或Europe/Berlin),因此您可以调用ZoneId.of("America/New_York")示例.避免使用3个字母的缩写(如CST或PST),因为它们不明确且不标准.
您可以通过调用获取可用时区列表(并选择最适合您系统的时区)ZoneId.getAvailableZoneIds().
| 归档时间: |
|
| 查看次数: |
2353 次 |
| 最近记录: |