spring 引导存储库测试中的日期格式

Date format in the spring boot repository testing

我正在使用以下代码对存储库功能进行集成测试。但是,由于日期格式,它会失败。 SimpleDateFormat 的输出是 'Wed Jan 01 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;

你在做的是Parsing(String to Date),你需要Format(Date to String)。

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是一样的,但是可以不一样。

在我看来,TestBean 被声明为持有一个 java.util.Date,但是从 findById() 编辑的 TestBean 实例却持有一个java.sql.Timestamp。很不幸(如果是真的)

Timestamp 作为 Date 的子 class 实现。这两个 classes 都设计得很糟糕而且已经过时了,我们不应该再使用它们了。尽管存在 subclass 关系,但根据文档我们不应该将 Timestamp 视为一种 Date。将 Timestamp 作为 Date 的子 class 实现是一个真正的 hack。将 Timestamp 放入对象中的 Date 字段是错误的。我也不认为我们应该在我们的模型 bean 中使用 Timestamp 。它仅用于在数据类型为 timestamptimestamp with time zone 的 SQL 数据库列之间传输数据。

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

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

  • 确保该对象包含声明的 Date 对象,而不是 Timestamp
  • 添加 getter 和 setter 那 return 并接受 Instant 而不是 Date 这样你的 class 可以更好使用 java.time 与代码进行互操作。新方法将进行必要的转换。然后使用新的 setter 来设置 toReturn.
  • 中的值

如果你也做不到这些并且你被迫成为黑客的一部分,当然有一些方法可以将 modifiedDate 设置为老式的 Timestamp。我建议:

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

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

链接