java 将 SimpleDateFormat 转换为 DateTimeFormatter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42903391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert SimpleDateFormat to DateTimeFormatter
提问by Remlap21
So when trying to replace some legacy code using SimpleDateFormat and Date, to use java.time.DateTimeFormatter and LocalDate I ran into a problem. The two date formats are not equivalent. At this point I must say I know the two date types are not the same but the scenario I am in means I never care about the time aspect so can ignore it.
因此,当尝试使用 SimpleDateFormat 和 Date 替换一些遗留代码时,要使用 java.time.DateTimeFormatter 和 LocalDate 我遇到了问题。这两种日期格式是不等价的。在这一点上,我必须说我知道这两种日期类型不一样,但我所处的场景意味着我从不关心时间方面,所以可以忽略它。
public Date getDate(String value) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
try {
return dateFormat.parse(value);
} catch (ParseException e) {
return null;
}
}
public LocalDate getLocalDate(String value) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
try {
return LocalDate.parse(value, formatter);
} catch (DateTimeParseException e) {
return null;
}
}
public void testDates() {
getDate("03/07/2016"); // Sun Jul 03 00:00:00 BST 2016
getDate("3/7/2016"); // Sun Jul 03 00:00:00 BST 2016
getDate("3/7/2016 00:00:00"); // Sun Jul 03 00:00:00 BST 2016
getDate("3/7/2016 00:00:00.0+0100"); // Sun Jul 03 00:00:00 BST 2016
getDate("3/7/2016T00:00:00.0+0100"); // Sun Jul 03 00:00:00 BST 2016
getLocalDate("03/07/2016"); // 2016-07-03
getLocalDate("3/7/2016"); // null
getLocalDate("3/7/2016 00:00:00"); // null
getLocalDate("3/7/2016 00:00:00.0+0100"); // null
getLocalDate("3/7/2016T00:00:00.0+0100"); // null
}
As you can see when the same pattern is used in both formatters the DateTimeFormatter ends up producing nulls where you'd expect to see dates equivalent to that of SDF. In this scenario I would expect the unrequired data to be dropped but it isn't.
正如您所看到的,当在两个格式化程序中使用相同的模式时,DateTimeFormatter 最终会生成空值,您希望看到的日期与 SDF 的日期相同。在这种情况下,我希望删除不需要的数据,但事实并非如此。
So, how do we create a robust date/time parser?!
那么,我们如何创建一个健壮的日期/时间解析器?!
回答by Remlap21
So there may be other answers to this but what I came up caters for the most extreme case I have. Firstly I reduced dd/MM to d/M. This denotes the minimum number of expected characters so will parse double digits completely fine. Note you could also use new DateTimeFormatterBuilder().parseLenient() but this seemed unnecessary.
因此,对此可能还有其他答案,但我提出的答案适合我遇到的最极端的情况。首先我将 dd/MM 减少到 d/M。这表示预期字符的最小数量,因此将完全解析两位数。请注意,您也可以使用 new DateTimeFormatterBuilder().parseLenient() 但这似乎没有必要。
Secondly I decided to use the optional clause in the format pattern itself. This allows you to specify which parts may not be provided which is exactly the case I was trying to solve.
其次,我决定在格式模式本身中使用可选子句。这允许您指定可能不提供哪些部分,这正是我试图解决的情况。
Leaving us with:
留给我们:
DateTimeFormatter.ofPattern("d/M/yyyy[' ']['T'][H:mm[:ss[.S]]][X]");
This will now handle providing a date with or without time including a T separator, seconds, millis and zone offset.
这将处理提供带或不带时间的日期,包括 T 分隔符、秒、毫秒和区域偏移。
With any luck this helps someone else!
运气好的话,这可以帮助别人!
private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy[' ']['T'][H:mm[:ss[.S]]][X]");
public LocalDate getRobustLocalDate(String value) {
try {
return LocalDate.parse(value, formatter);
} catch (DateTimeParseException e) {
return null;
}
}
@Test
public void testDates() {
getRobustLocalDate("03/07/2016"); // 2016-07-03
getRobustLocalDate("3/7/2016"); // 2016-07-03
getRobustLocalDate("3/7/2016 00:00:00"); // 2016-07-03
getRobustLocalDate("3/7/2016 00:00:00.0+0100"); // 2016-07-03
getRobustLocalDate("3/7/2016T00:00:00.0+0100"); // 2016-07-03
}