- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
使用“旧的”Java 8 之前的 SimpleDateFormat
我可以:
new java.text.SimpleDateFormat("MMM yyyy", new java.util.Locale("es", "ES")).parse("Mayo 2017")
获取具有西类牙月份名称的日期的 Date
对象。
如何使用 Java 8 和 DateTimeFormatter
实现同样的效果?
我试过:
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(new Locale("es", "ES")).ofPattern("MMM yyyy").parse("Mayo 2017")
但只得到一个java.time.format.DateTimeParseException
。
最佳答案
可以删除对 ofLocalizedDateTime()
的调用,因为最后您调用了 ofPattern()
,创建了另一个具有完全不同模式的格式化程序(并返回了模式by ofLocalizedDateTime(FormatStyle.FULL)
与 month year
非常不同,因此这并不是您真正想要的)。
另一个细节是 Mayo
是完整的月份名称,因此模式必须是 MMMM
(check the 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");
可选地,您可以直接将它解析为 java.time.YearMonth
对象,因为它似乎是这种情况的最佳选择(因为输入只有年和月):
YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
System.out.println(ym); // 2017-05
当输入不包含所有字段时,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"));
有了这个,您可以将它解析为 LocalDateTime
,缺失的字段将被分配给相应的默认值:
LocalDateTime dt = LocalDateTime.parse("Mayo 2017", fmt);
System.out.println(dt); // 2017-05-01T00:00
如果你需要得到一个与SimpleDateFormat
创建的值相同的java.util.Date
,你可以转换这个LocalDateTime
到 JVM 默认时区,然后将其转换为 Date
:
Date javaUtilDate = Date.from(dt.atZone(ZoneId.systemDefault()).toInstant());
请注意,我必须明确使用 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());
默认时区 can be changed without notice, even at runtime ,因此最好始终明确说明您使用的是哪一个。
API 使用 IANA timezones names (始终采用 Region/City
格式,例如 America/New_York
或 Europe/Berlin
),因此您可以调用 ZoneId.of ("America/New_York")
例如。避免使用 3 个字母的缩写(如 CST
或 PST
),因为它们是 ambiguous and not standard .
您可以通过调用 ZoneId.getAvailableZoneIds()
获取可用时区列表(并选择最适合您系统的时区)。
关于java - 使用 Java 8 DateTimeFormatter 和西类牙月份名称进行解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46305245/
我是 Android 的新手,我想根据我的相机获取方向。如何根据我的相机获取方向信息?你能给出一个想法吗? 最佳答案 TYPE_ORIENTATION 已弃用 我们不能再使用方向传感器了,我们可以串联
我想知道矩阵除对角线之外的 4 个主要区域的条件。 例如下面的矩阵 A=[1,2,3,4,5; 6,7,8,9,10; 11,12,13,14,15; 16,17,18,19,20;
let latitude: = 36.6839559; let longitude = 3.6217802; 此API需要东西南北参数 const API = `http://api.geonames
我是一名优秀的程序员,十分优秀!