我正在尝试将String
(YYYY-MM-dd HH:mm
)解析为Date
,但错误的日期比预期错误。
CODE:
Date newDate = null;
String dateTime = "2013-03-18 08:30";
SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-dd HH:mm", Locale.ENGLISH);
df.setLenient(false);
try {
newDate = df.parse(dateTime);
} catch (ParseException e) {
throw new InvalidInputException("Invalid date input.");
}
产地:
Sun Dec 30 08:30:00 EST 2012(错误)
我试过设置Lenient但没有运气。
更新
感谢Sudhanshu的回答,它帮助我解决了Java转换问题。当我从上面的代码输入返回的日期到数据库时,我正确地得到了日期,但时间总是00:00
。
ps.setDate(3, new java.sql.Date(app.getDate().getTime()));
答案 0 :(得分:46)
YYYY应该是yyyy -
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
请在此处查看SimpleDateFormat的文档
Java 6:http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
Java 7:http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
答案 1 :(得分:7)
使用小盒子Y,而不是帽子。即yyyy不是YYYY
检查此处的评论:Java Simple Date Format以及其中引用的其他答案。
答案 2 :(得分:5)
有两个问题。
"yyyy-MM-dd HH:mm"
。TimeStamp
而非Date
。纠正这两件事,你就可以随时间存储和检索日期。
答案 3 :(得分:2)
这是现代的答案。其他答案在2013年写完时是很好的答案。在那之后的一年,现代日期和时间API作为旧课程Date
,SimpleDateFormat
和朋友的替代品而出现。恕我直言,你现在应该使用新的课程。他们对程序员友好得多。
LocalDateTime newDate = null;
String dateTime = "2013-03-18 08:30";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm", Locale.ENGLISH);
try {
newDate = LocalDateTime.parse(dateTime, dtf);
} catch (DateTimeParseException e) {
throw new InvalidInputException("Invalid date input.");
}
除了类名,它与旧代码没有什么不同。通过其他示例会有差异,通常现代类将提供更清晰的代码和更少的错误机会。
对于差异的一点点演示,让我们尝试使用大写YYYY
的格式模式字符串:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm", Locale.ENGLISH);
现在代码抛出java.time.format.DateTimeParseException: Text '2013-03-18 08:30' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MonthOfYear=3, DayOfMonth=18, WeekBasedYear[WeekFields[SUNDAY,1]]=2013},ISO resolved to 08:30 of type java.time.format.Parsed
。我知道,这很长。需要注意的是,它所提到的领域中没有一年,只有一周的基础年份。这是不一样的;你可能现在已经想通了,这正是因为大写Y
是基于周的年份(只有一周的数字),你应该使用小写的y
年。我认为这种行为比旧课程更有帮助:他们给你一个错误的结果,假装一切都很好,让你完全不知道什么是错的。
接下来我知道您希望将日期时间存储到数据库中。在过去,您将转换为适当的java.sql
类型。不再需要。我相信你可以使用JDBC 4.2驱动程序:
ps.setObject(3, newDate);
但是,我还没有用数据库对此进行过测试。请注意,您使用setObject()
代替setDate()
。
答案 4 :(得分:1)
尽管这里不是这种情况,但是请注意SimpleDateFormat
不是线程安全的。因此,在多线程环境中使用时,可能会发生竞争情况并导致错误的解析结果。解决办法是
synchronized
块中使用ThreadLocal
ThreadLocal
的示例:
class MyClass {
private ThreadLocal<SimpleDateFormat> threadLocalFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH));
public void foo(String bar) {
return threadLocalFormat.get().parse(bar);
}
}