我有字符串格式的日期,我想解析它到util日期.
var date ="03/11/2013"
Run Code Online (Sandbox Code Playgroud)
我正在解析这个:
new SimpleDateFormat("MM/dd/yyyy").parse(date)
Run Code Online (Sandbox Code Playgroud)
但奇怪的是,如果我传递"03-08- 201309 hjhkjhk "或"03- 88 -2013"或43 -88-201378" ,它不会引发错误,它分析它.
为此,我必须编写正则表达式模式以检查日期的输入是否正确.但为什么会这样呢?
代码:
scala> val date="03/88/201309 hjhkjhk"
date: java.lang.String = 03/88/201309 hjhkjhk
scala> new SimpleDateFormat("MM/dd/yyyy").parse(date)
res5: java.util.Date = Mon May 27 00:00:00 IST 201309
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 56
你应该使用DateFormat.setLenient(false):
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
df.setLenient(false);
df.parse("03/88/2013"); // Throws an exception
Run Code Online (Sandbox Code Playgroud)
我不确定会抓住你想要的一切 - 我似乎记得即使setLenient(false)它比你想象的更宽松 - 但它应该抓住无效的月份数字.
我认为它不会捕获尾随文本,例如"03/01/2013 sjsjsj".您可能会使用parse其接受a 的重载ParsePosition,然后在解析完成后检查当前的解析索引:
ParsePosition position = new ParsePosition(0);
Date date = dateFormat.parse(text, position);
if (position.getIndex() != text.length()) {
// Throw an exception or whatever else you want to do
}
Run Code Online (Sandbox Code Playgroud)
您还应该查看Joda Time API,这可能会允许更严格的解释 - 并且无论如何都是一个通常更干净的日期/时间API.
乔恩·斯凯特(Jon Skeet)的答案是正确的,在2013年撰写时是一个很好的答案。
但是,您在问题中使用的类SimpleDateFormat和Date现在早已过时,因此,如果今天有人遇到类似的问题,恕我直言,最好的答案是改为使用现代Java日期和时间API。
抱歉,我无法编写Scala代码,因此您将不得不使用Java。我在用
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy");
Run Code Online (Sandbox Code Playgroud)
格式字母与您的问题相同,尽管含义略有不同。DateTimeFormatter如我们将看到的,从字面上接受模式字母的数量。现在我们尝试:
System.out.println(LocalDate.parse(date, parseFormatter));
Run Code Online (Sandbox Code Playgroud)
结果:
"03/11/2013"被2013-03-11按预期解析。我使用了现代LocalDate类,该类表示没有日期的日期,正是我们在这里需要的。"03/88/2013 hjhkjhk"会给出一条DateTimeParseException消息Text '03/88/2013 hjhkjhk' could not be parsed, unparsed text found at index 10。相当精确,不是吗?不过,现代的API具有仅解析字符串部分的方法(如果我们想要的话)。"03/88/201309"给Text '03/88/201309' could not be parsed at index 6。我们要求输入4位数字的年份并给它6位数字,这导致了异议。显然,它会在尝试将88解释为一个月的某天之前检测到并报告此错误。"03/88/2013"给出Text '03/88/2013' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 88。再次,请享受消息的内容丰富。"03-08-2013"(用连字符而不是斜杠)给出Text '03-08-2013' could not be parsed at index 2,这并不奇怪。索引2是第一个连字符所在的位置。乔恩·斯凯特(Jon Skeet)解释说,过时的SimpleDateFormat可能是宽容的,也可能是宽容的。这也是正确的DateTimeFormatter,实际上,它具有3种而不是2种解析器样式,分别称为“宽松”,“智能”和“严格”。但是,由于许多程序员并不了解这一点,所以我认为他们做出了一个很好的选择,即不将“宽大”作为默认值(“智能”为默认值)。
如果我们想宽大格式化程序怎么办?
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy")
.withResolverStyle(ResolverStyle.LENIENT);
Run Code Online (Sandbox Code Playgroud)
现在它也解析"03/88/2013"为2013-05-27。我相信这也是旧班级也会做的:从3月初算起88天为5月27日。其他错误消息仍然相同。换句话说,它仍然反对未解析的文本,6位数字的年份和连字符。
问:我可以在Java版本中使用现代API吗?
如果至少使用Java 6,则可以。
| 归档时间: |
|
| 查看次数: |
17395 次 |
| 最近记录: |