>我正在尝试比较来自数据库和Web服务的响应。
response from web services is : 2020-01-07T17:15:00-08:00
response from database is : 2020-01-08 01:15:00.0
如何将它们都转换为通用格式?
或者有没有办法使用子字符串来匹配比较?
这些字符串表示某些格式。比较它们相当于问"这些格式是否相同"——它们不是,这不是你想要测试的(你想测试:这些不同格式的字符串是否仍然代表同一时刻)。
所以,那就这样做吧。首先,将这些字符串(对人类来说是东西)转换为实际正确的时间对象,然后比较它们。
您可以将这些字符串转换为Instant
,它表示时间中的时刻,大概是您在这里寻找的内容,然后一旦您将两者转换为瞬间,您就可以比较这两个时刻。
要将字符串转换为Instant
,请使用DateTimeFormatter
。更多信息:Java time API。
我们不知道。字符串不提供相同的信息,因此来自它们的信息不容易比较。如果您知道第二个字符串中假定的时区,我们将每个时区转换为一个时间点并进行比较。
前一个字符串更容易,因为除了日期和时间之外,它还通知我们与 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()
返回真和equals()
假。这是因为isEqual()
测试两个对象是否表示相同的时间点,而equals()
需要相同的时间点和相同的偏移量才能产生 true。由于这两个对象具有不同的偏移量,因此在这种情况下返回 false。
您的 JDBC 驱动程序或 JPA 实现可能很乐意从数据库中获取日期时间对象而不是字符串,正如我所说,建议这样做。详细信息取决于数据库中使用的数据类型,但您可以在我对不同问题的回答中阅读更多内容,请参阅底部的链接。
链接
- Oracle 教程:日期时间解释如何使用 java.time。
- 维基百科文章:ISO 8601
- 我对从结果集中获取日期以用于java.time类的回答
您可以将时间戳转换为等效的日期格式。Web 服务显示为 ISO,因此您可以将数据库时间戳转换为 ISO,然后最终分析文本以生成可用于比较的日期。
例如:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CompareTimeStamp {
private String webServiceTS = ": 2020-01-07T17:15:00-08:00".replace(": ", "");
private String dataBaseTS = ": 2020-01-08 01:15:00.0".replace(": ", "");
private DateTimeFormatter isoFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
private DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
public static void main(String[] args) {
CompareTimeStamp cts = new CompareTimeStamp();
LocalDateTime webServiceTime = LocalDateTime.parse(cts.webServiceTS, cts.isoFormat);
LocalDateTime dataBaseTime = LocalDateTime.parse(cts.dataBaseTS, cts.format);
/** OPTION 1 -Remove below code if not choosing this option*/
System.out.println("webServiceTime: " + webServiceTime);
System.out.println("dataBaseTime: " + dataBaseTime);
System.out.println(cts.compareTimeStamps(webServiceTime, dataBaseTime) + "n");
/*********************************************************************/
/** OPTION 2 -Remove below code if not choosing this option*/
String webServiceTS = cts.formatTimeStamp(webServiceTime);
String dataBaseTS = cts.formatTimeStamp(dataBaseTime);
System.out.println("webServiceTS: " + webServiceTS);
System.out.println("dataBaseTS: " + dataBaseTS);
System.out.println(cts.compareTimeStamps(webServiceTS, dataBaseTS));
/*********************************************************************/
}
// OPTION 1 - Compares this LocalDateTime with another ensuring that the date-time is the same.
private String compareTimeStamps(LocalDateTime webServiceTime, LocalDateTime dataBaseTime) {
if (webServiceTime.equals(dataBaseTime)) {
return "Time stamp matches";
} else {
return "Time stamp does not match";
}
}
// OPTION 2 - Compares this string to the specified object.
private String compareTimeStamps(String webServiceTS2, String dataBaseTS2) {
if (webServiceTS2.equals(dataBaseTS2)) {
return "Time stamp matches";
} else {
return "Time stamp does not match";
}
}
private String formatTimeStamp(LocalDateTime timeStamp) {
DateTimeFormatter formating = DateTimeFormatter.ofPattern("EEEE, MMM d, yyyy HH:mm:ss a");
String localTimeStamp = formating.format(timeStamp);
return localTimeStamp;
}
}
输出:
webServiceTime: 2020-01-07T17:15
dataBaseTime: 2020-01-08T01:15
Time stamp does not match
webServiceTS: Tuesday, Jan 7, 2020 17:15:00 PM
dataBaseTS: Wednesday, Jan 8, 2020 01:15:00 AM
Time stamp does not match
修改时间戳:
": 2020-01-07T17:15:00-08:00" ": 2020-01-07 17:15:00.0"
输出:
webServiceTime: 2020-01-07T17:15
dataBaseTime: 2020-01-07T17:15
Time stamp matches
webServiceTS: Tuesday, Jan 7, 2020 17:15:00 PM
dataBaseTS: Tuesday, Jan 7, 2020 17:15:00 PM
Time stamp matches