从数据库加载后,Java Date toString以不同的格式

时间:2017-02-03 09:36:00

标签: java mysql date

如何在Java持久化之前和之后以可靠的方式比较日期? 我面临的问题是:当我创建一个新的java.util.Date实例时,它的toString()方法返回一个值,包括星期几和时区:

nblock

当我在数据库表中保留此日期(EDIT:Date对象)并将其加载回实体时,toString方法返回不同的格式,具体取决于数据库类型:

Fri Feb 03 10:15:31 CET 2017

我并不总是能访问格式化程序,因为toString方法可能会被我的应用程序中的另一个toString方法隐式调用。

这些问题对我而言:

  1. Date对象如何知道使用时要选择的格式 的toString?
  2. 如何控制新的Date对象     首先代表一个日期(即没有时间分数的一天)?
  3. 比较中持久对象的日期的最佳做法是什么? 在从一个对象加载之前和对象之间进行单元测试     数据库?

1 个答案:

答案 0 :(得分:2)

使用对象,而不是字符串

不要使用字符串将数据传入/传出数据库。使用对象。这是JDBC的目的,从数据库的数据类型转换为Java的数据类型(类)。

使用java.time,而不是遗留类

不要使用遗留日期时间类,例如java.util.Date,因为它们非常麻烦,令人困惑和有缺陷。现在遗留下来,取代java.time类。

  

使用toString时,Date对象如何知道要选择哪种格式?

toString使用的格式是硬编码的,未选中。您总是从该方法获得相同的格式。而且格式选择较差,而现代图书馆和协议使用标准的ISO 8601格式。

java.time.Date中许多糟糕的设计选择中有toString方法的行为,它将JVM的当前默认时区应用于实际为UTC的值。这会产生一个实际上不存在的时区的错觉。

最好避免这些字符串。在Java和数据库之间传递和获取对象而不是字符串。调用PreparedStatement::setObjectResultSet::getObject方法可以使用LocalDateInstant和其他此类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类提供了比较方法,例如compareToisAfterisBeforeisEqual。其他课程类似。

这在Stack Exchange上已经涵盖很多次。请搜索类别名称,例如LocalDateInstantOffsetDateTimeZonedDateTimeZoneIdjava.sql.Timestamp