我们不知道。字符串不提供相同的信息,因此来自它们的信息不易比较。如果您知道第二个字符串中假定的时区,我们将每个时区转换为一个时间点并进行比较。
前一个字符串更容易,因为除了日期和时间之外,它还通知我们与 UTC 的偏移量(时区偏移量)。所以有了这个字符串,我们可以识别一个时间点。此外,该字符串采用 ISO 8601 格式。 java.time 类,现代 Java 日期和时间 API,将 ISO 8601 格式(或其最常见的变体)解析为默认格式,即没有任何显式格式化程序。
String responseFromWs = "2020-01-07T17:15:00-08:00";
OffsetDateTime odtFromWs = OffsetDateTime.parse(responseFromWs);
System.out.println(odtFromWs);
到目前为止的输出是:
2020-01-07T17:15-08:00
它看起来很像输入(仅省略了00 秒)。这是因为OffsetDateTime 还打印回 ISO 8601 格式(根据该格式,秒数是可选的)。重要的是我们有一个日期时间对象,可以用于进一步处理,例如与其他日期时间对象进行比较。
第二个字符串(来自数据库的字符串)的问题是我们不知道隐含的偏移量。常见的建议包括将日期和时间以 UTC 格式存储在数据库中,并且不要将其作为字符串从数据库中获取,而是作为适当的日期时间对象,例如我们之前使用的 OFfsetDateTime。
如果您知道字符串是 UTC 格式并且我们现在依赖该字符串:
DateTimeFormatter dbFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
String responseFromDatabase = "2020-01-08 01:15:00.0";
OffsetDateTime odtFromDb = LocalDateTime
.parse(responseFromDatabase, dbFormatter)
.atOffset(ZoneOffset.UTC);
System.out.println(odtFromDb);
2020-01-08T01:15Z
现在我们有两个OffsetDateTime 对象。他们有比较方法:
System.out.println("Before: " + odtFromWs.isBefore(odtFromDb));
System.out.println("After: " + odtFromWs.isAfter(odtFromDb));
System.out.println("Same time: " + odtFromWs.isEqual(odtFromDb));
System.out.println("Equal: " + odtFromWs.equals(odtFromDb));
Before: false
After: false
Same time: true
Equal: false
isEqual() 返回 true 和 equals() false,您可能会感到惊讶。这是因为isEqual() 测试这两个对象是否表示相同的时间点,它们会这样做,而equals() 需要相同的时间点和相同的偏移量,才能产生真值。由于两个对象有不同的偏移量,在这种情况下它返回 false。
您的 JDBC 驱动程序或 JPA 实现可能会很乐意从数据库中获取日期时间对象,而不是字符串,正如我所说的,建议这样做。详细信息取决于数据库中使用的数据类型,但您可以在我对不同问题的回答中阅读更多信息,请参阅底部的链接。
链接