我的日期字符串格式如下:"dd/MM/yyyy HH:mm:ss"
。我想从中创建一个Date
对象,并且我正在使用SimpleDateFormat
类。我们的应用程序接受存储在String
数组中的许多不同日期格式。我们所做的是遍历该数组,使用applyPattern
到我们的SimpleDateFormat
对象并尝试parse
给定的日期字符串。如果它抛出异常,我们在数组中尝试下一个日期格式等。
但是我发现parse
类的SimpleDateFormat
方法并不一定要尝试解析整个字符串。如果它从字符串的某些部分成功创建了一个Date对象,那么它将返回它。这里的问题是我们给定的日期字符串包含日期和时间数据,但在我们的第一次parse
尝试中SimpleDateFormat
使用更简单的模式:"dd/MM/yyyy"
。并且因为在解析过程中它在给定的日期字符串中找到匹配日期,所以它在那里停止并创建一个没有时间信息的Date
对象。
有没有办法强制SimpleDateFormat
解析它给出的整个字符串?
String dateString = "01/01/2015 05:30:00";
Date date = null;
for (String format : Constants.DATE_FORMATS) {//String Array that contains many date format strings.
try {
simpleDateFormat.applyPattern(format);//First format applied is "dd/MM/yyyy".
date = simpleDateFormat.parse(dateString);
//No exception thrown it accepts the "dd/MM/yyyy" part of the dateString even though the string itself contains even more data.
}
catch (Exception e) {}
}
//Returns a date object with the time set to 00:00:00
答案 0 :(得分:1)
您可以通过提供ParsePosition
来检查解析了多少输入。 parse
方法更新位置以告诉您解析了多少。
ParsePosition pos = new ParsePosition(0);
date = simpleDateFormat.parse(dateString, pos);
if (pos.getIndex() < dateString.length()) {
// did not parse all of dateString
}
答案 1 :(得分:0)
我认为没有办法强制SimpleDateFormat
解析整个String,但你可以比较格式的长度和输入的长度
String[] formats = new String[] {"dd/MM/yyyy", "dd/MM/yyyy HH:mm:ss"};
String input = "25/09/2015 10:25:31";
Date result = null;
for (String format: formats) {
if (input != null && format.length() == input.length()) {
try {
SimpleDateFormat sdFormat = new SimpleDateFormat(format);
result = sdFormat.parse(input);
break;
}
catch (ParseException e) {
}
}
}
修改强> 另一种方法是使用JodaTime来解析String。
String[] formats = new String[] { "dd/MM/yyyy", "dd/MM/yyyy HH:mm:ss" };
String input = "25/09/2015 10:25:31";
LocalDateTime result = null;
for (String format : formats) {
try {
DateTimeFormatter sdFormat = DateTimeFormat.forPattern(format);
result = sdFormat.parseLocalDateTime(input);
break;
}
catch (IllegalArgumentException e) {
}
}
System.out.println(result);
Date resultDate = result.toDate();
System.out.println(resultDate);
这会给你
2015-09-25T10:25:31.000
Fri Sep 25 10:25:31 CEST 2015
答案 2 :(得分:0)
您可以使用类似的内容而不是Behavior
:
EllipseMorph(BorderedMorph) initialize
如果您解析的字符串与模式的长度不同,则会抛出异常。这应该阻止SimpleDateFormat
解析import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
class StrictDateFormat extends SimpleDateFormat {
private String pattern;
public void applyPattern(String pattern) {
super.applyPattern(pattern);
this.pattern = pattern;
}
@Override
public Date parse(String source) throws ParseException {
if (source.length() != pattern.length()) {
throw new ParseException("Wrong size", pattern.length());
}
return super.parse(source);
}
}
。这个将始终严格,而不仅仅是"01/01/2015 05:30:00"
。
答案 3 :(得分:0)
对于那些想要获得java.util.Date
对象并避免使用第三方库的人,我使用了答案的压缩版本:
for (String format : Constants.DATE_FORMATS) {
try {
return Date.from(LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(format)).atZone(ZoneId.systemDefault()).toInstant());
} catch (DateTimeParseException e) {}
}
使用此代码块,它将使用正确的格式,使用java 8自己的java.time
库,该库可以正确匹配格式。别忘了添加try-catch块! IDE不会要求它,因为DateTimeParseException
是一个运行时异常但我们想要处理它以便进入下一个循环迭代。