时区会影响java.util.Date.compareTo()结果吗



我有一个程序,它存储FTP服务器中托管的文件的本地副本。该程序每天自动检查文件是否已使用以下代码在服务器上更新:

FTPFile remoteFile = ftpClient.mlistFile(remotePath);
Date remoteDate = remoteFile.getTimestamp().getTime();
BasicFileAttributes localFile = Files.readAttributes(Paths.get(localPath), BasicFileAttributes.class);
Date localDate = new Date(localFile.lastModifiedTime().toMillis());
isUpToDate = localDate.compareTo(remoteDate) > 0;

我和我的同事现在对这个代码有分歧。他说,如果程序在不同的时区执行,这可能不起作用,我说它会起作用,因为Java Date对象不受时区的影响,只有Calendar的实例受影响。我说得对吗?他说得对吗?

时区会影响java.util.Date.compareTo((结果吗?

否。Date唯一比较的是自epoch以来的毫秒数。

这将很容易编写测试:运行相同的代码,将JVM的默认时区设置为不同的值。

不,java.util.Date在时区上并不重要,它始终是Unix epoch值后的毫秒。如果你想把时间放在不同的时区,那么你需要做以下操作——

public static void main(String[] args) {
Date date = new Date();
// Display the instant in three different time zones
TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
System.out.println(date);
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
System.out.println(date);
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Riyadh"));
System.out.println(date);
// Prove that the instant hasn't changed...
System.out.println(date.getTime());
}

java.time

这不是你问的,但我认为这对你来说会很有趣,尤其是很多其他人对这个问题和类似的问题感兴趣。如果您使用现代java日期和时间API java.time中的Instant而不是老式的Date类,那么疑问可能会消失。

FTPFile remoteFile = ftpClient.mlistFile(remotePath);
Instant remoteInstant = remoteFile.getTimestamp().toInstant();
BasicFileAttributes localFile = Files.readAttributes(Paths.get(localPath), BasicFileAttributes.class);
Instant localInstant = localFile.lastModifiedTime().toInstant();
isUpToDate = ! localInstant.isBefore(remoteInstant);

(代码未经测试,请原谅任何拼写错误。(虽然Date有时会假装是时区中的日期和时间(尤其是其令人困惑的toString方法给人的印象(,但我毫不怀疑Instant正是名称所说的,一个时间点,不多也不少。绝对独立于时区。

在我的比较中,我允许瞬间相等。我使用而不是在之前表示相同时间或之后。如果您在自己的代码中要求本地即时消息严格在后面,那么您可以只使用isAfter()

链接

Oracle教程:日期时间解释如何使用java.Time.

最新更新