这是我将String解析为LocalDateTime
的方法。
public static String formatDate(final String date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS");
LocalDateTime formatDateTime = LocalDateTime.parse(date, formatter);
return formatDateTime.atZone(ZoneId.of("UTC")).toOffsetDateTime().toString();
}
但这仅适用于输入String之类的
2017-11-21 18:11:14.05
但是2017-11-21 18:11:14.057
失败了
与DateTimeParseException
。
如何定义适用于.SS
和.SSS
的格式化程序?
答案 0 :(得分:12)
您需要构建具有指定分数的格式化程序
DateTimeFormatterformatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
.appendFraction(ChronoField.MILLI_OF_SECOND, 2, 3, true) // min 2 max 3
.toFormatter();
LocalDateTime formatDateTime = LocalDateTime.parse(date, formatter);
答案 1 :(得分:3)
根本不需要定义格式化程序。
LocalDateTime.parse(
"2017-11-21 18:11:14.05".replace( " " , "T" )
)
Answer by Sleiman Jneidi特别聪明且高科技,但有一种更简单的方法。
调整输入字符串以符合ISO 8601格式,即java.time类中默认使用的格式。因此,根本不需要指定格式化模式。默认格式化程序可以处理小数秒(零秒(整秒)和九(纳秒))之间的任意数量的十进制数字。
您的输入几乎符合要求。只需用T
替换中间的SPACE即可。
String input = "2017-11-21 18:11:14.05".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );
ldt.toString():2017-11-21T18:11:14.050
答案 2 :(得分:3)
Basil Bourque和Sleiman Jneidi的答案非常好。我只想指出the answer by EMH333也有一点意义:以下对问题中代码的非常简单的修改可以解决您的问题。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.[SSS][SS]");
格式模式字符串中的方括号包含可选部分,因此在小数秒内接受3或2个小数。
可能的缺点:它根本不接受小数(只要有小数点)。
正如我所说,其他解决方案也非常好。你喜欢哪一个主要是品味问题。
答案 3 :(得分:1)
使用Java 8,您可以使用DateTimeFormatterBuilder
和模式。有关更多信息,请参阅this answer
public static String formatDate(final String date) {
DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ofPattern("" + "[yyyy-MM-dd HH:mm:ss.SSS]"
+ "[yyyy-MM-dd HH:mm:ss.SS]"));
DateTimeFormatter formatter = dateTimeFormatterBuilder.toFormatter();
try {
LocalDateTime formatDateTime = LocalDateTime.parse(date, formatter);
return formatDateTime.atZone(ZoneId.of("UTC")).toOffsetDateTime().toString();
} catch (DateTimeParseException e) {
return "";
}
}
答案 4 :(得分:0)
理想情况下,您还要考虑 0 纳秒的时间。如果时间恰好恰好落在 2021-02-28T12:00:15.000Z
上,它实际上可能会被序列化为 2021-02-28T12:00:15Z
(至少,对于像 java.time.OffsetDateTime 这样的东西)。因此,使用以下内容更合适:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS][.SS][.S]");
...如果你需要时区,就像我一样,那么它看起来像这样:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS][.SS][.S]z");
答案 5 :(得分:0)
我曾经参与过一个项目,其中输入可以是任何格式的字符串,如果它是有效格式,我们应该在事先不知道格式的情况下解析它。所以,我想出了一个想法,我们把所有支持的格式列表作为一个属性,然后当 String 进来时,我们尝试用列表中的格式一一解析它,直到我们成功或用完格式(在在这种情况下,我们将字符串变暗以使其不是有效的日期格式)。如果我们解析某些字符串失败并发现它是一个有效字符串,我们可以在不需要更改代码的情况下向我们的属性添加新格式,因此我们可以立即提供对任何新格式的支持,并拥有不同的支持格式集针对不同的客户。另一个问题是美国与欧洲格式 - 所以我们将美国格式和欧洲格式按顺序排列。因此客户可以说如果 String 适合两者,则选择列表中的第一个。因此,美国/欧盟格式支持列表中的格式顺序也是一个问题。这是解释思想和实现的文章的链接(包括格式列表的示例)Java 8 java.time package: parsing any string to date