如何在Java持久化之前和之后以可靠的方式比较日期? 我面临的问题是:当我创建一个新的java.util.Date实例时,它的toString()方法返回一个值,包括星期几和时区:
nblock
当我在数据库表中保留此日期(EDIT:Date对象)并将其加载回实体时,toString方法返回不同的格式,具体取决于数据库类型:
Fri Feb 03 10:15:31 CET 2017
我并不总是能访问格式化程序,因为toString方法可能会被我的应用程序中的另一个toString方法隐式调用。
这些问题对我而言:
答案 0 :(得分:2)
不要使用字符串将数据传入/传出数据库。使用对象。这是JDBC的目的,从数据库的数据类型转换为Java的数据类型(类)。
不要使用遗留日期时间类,例如java.util.Date
,因为它们非常麻烦,令人困惑和有缺陷。现在遗留下来,取代java.time类。
使用toString时,Date对象如何知道要选择哪种格式?
toString
使用的格式是硬编码的,未选中。您总是从该方法获得相同的格式。而且格式选择较差,而现代图书馆和协议使用标准的ISO 8601格式。
java.time.Date
中许多糟糕的设计选择中有toString
方法的行为,它将JVM的当前默认时区应用于实际为UTC的值。这会产生一个实际上不存在的时区的错觉。
最好避免这些字符串。在Java和数据库之间传递和获取对象而不是字符串。调用PreparedStatement::setObject
和ResultSet::getObject
方法可以使用LocalDate
,Instant
和其他此类java.time对象。
LocalDate ld = myResultSet.getObject( … );
如果您的JDBC driver尚未符合JDBC 4.2,并且无法直接处理java.time对象,请回过头来简要地使用java.sql类型。通过调用添加到旧类的新方法,立即将这些java.sql对象转换为java.time对象。
java.sql.Date myJavaSqlDate = myResultSet.getDate( … );
java.time.LocalDate ld = myJavaSqlDate.toLocalDate();
如何控制新的Date对象,它应该首先代表一个日期(即没有时间分数的一天)?
使用LocalDate
类获取仅限日期的值,而不包含时间和没有时区。这映射到SQL标准DATE
类型的等效项。您应该使用仅日期类型来定义数据库中的列。
在对象从数据库加载之前和之后的单元测试中比较持久对象的日期的最佳做法是什么?
LocalDate
类提供了比较方法,例如compareTo
,isAfter
,isBefore
和isEqual
。其他课程类似。
这在Stack Exchange上已经涵盖很多次。请搜索类别名称,例如LocalDate
,Instant
,OffsetDateTime
,ZonedDateTime
,ZoneId
和java.sql.Timestamp
。