春季启动存储库测试中的日期格式



我使用以下代码对存储库功能进行集成测试。但是,由于日期形式,它将失败。SimpleDateFormat 的输出是"星期三 1 月 1 日 10:10:10 MST 2020",但数据库中的日期是"2020-01-01 10:10:10.0"。他们有什么简单的方法来解决这个问题吗?

Optional<TestBean> testBean = testBeanRepository.findById(1L);
TestBean toReturn = new TestBean();
toReturn.setAccountNumber(123456789);
toReturn.setId(1L);
toReturn.setCustomerName("Peter");
toReturn.setModifiedDate(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").parse("2020-01-01 10:10:10"));
assertThat(testBean)
.isPresent()
.hasValue(toReturn);

这就是我定义修改日期(java.util.date(的方式:

@Column(name = "MODIFIED_DATE_TIME") 
@NotNull 
@Temporal(TemporalType.TIMESTAMP) 
private Date modifiedDate;

在我看来,TestBean被声明为持有java.util.Date,但从findById()返回的TestBean实例反而持有java.sql.Timestamp。这是非常不幸的(如果这是真的(。

Timestamp作为Date的子类实现。这两个类都设计不佳且早已过时,我们不应该再使用它们了。尽管存在子类关系,但根据文档,我们不应Timestamp视为一种Date。将Timestamp实现为Date的子类是一个真正的黑客。将Timestamp放入对象的Date字段中是错误的。我也不认为我们应该在我们的模型豆中使用Timestamp。它仅用于将数据传入和传出数据类型为timestamptimestamp with time zone的 SQL 数据库列。

因此,好的解决方案是:更改TestBean类以保存属于 java.time 类(现代 Java 日期和时间 API(的现代日期时间对象。编辑:由于您在 MySQL 中的数据类型是datetime,因此 Java 中的最佳匹配是LocalDateTimeLocalDateTime是一天中没有时区或 UTC 偏移量的日期和时间。

如果无法更改TestBean类中声明的类型,仍有一些可能的改进:

  • 确保对象包含声明要执行的Date对象,而不是Timestamp
  • 添加一个返回并接受Instant而不是Date的 getter 和 setter,以便您的类可以使用 java.time 更好地与代码进行互操作。新方法将进行必要的转换。然后使用新的资源库在toReturn中设置值。

如果您也无法做到这一点并且被迫成为黑客的一部分,那么当然有办法modifiedDate设置为老式Timestamp。我建议:

toReturn.setModifiedDate(Timestamp.from(Instant.parse("2020-01-01T17:10:10Z")));

我把时间定为17:10:10。此时间采用 UTC(用Z表示(。我假设您问题中提到的 MST 是北美山区标准时间(不是马来西亚标准时间?(,如果是这样,则此时间对应于您所在时区所需的

10:10:10。

链接

  • Oracle 教程:日期时间解释如何使用 java.time。
  • java.sql.Timestamp文档

你正在做的是解析(字符串到日期(,你需要格式化(日期到字符串(。

SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Optional<TestBean> testBean = testBeanRepository.findById(1L);
TestBean toReturn = new TestBean();
toReturn.setAccountNumber(123456789);
toReturn.setId(1L);
toReturn.setCustomerName("Peter");
toReturn.setModifiedDate(writeFormat.format(readFormat.parse("2020-01-01 10:10:10")));
assertThat(testBean)
.isPresent()
.hasValue(toReturn);

在这里,readFormatwriteFormat是相同的,但它们可以不同。

最新更新