时区会影响 java.util.Date.compareTo() 结果吗?
Can the time zone affect a java.util.Date.compareTo() result?
我有一个程序可以存储 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 的实例受时区影响。我对吗 ?他说得对吗?
Can the time zone affect a java.util.Date.compareTo() result?
没有。 Date
唯一比较的是自纪元以来的毫秒数。
编写测试很容易:运行相同的代码,将 JVM 的默认时区设置为不同的值。
不,java.util.Date
与时区无关,它始终是 milliseconds-since-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.time 中的 Instant
而不是 old-fashioned Date
class,现代的 Java 日期和时间 API.
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
就是顾名思义,一个时间点,不多也不少。完全不受时区限制。
在我的比较中,我允许瞬间相等。我使用 not before 表示 同时或在 之后。如果您需要像在您自己的代码中一样严格遵守本地即时信息,则可以只使用 isAfter()
。
Link
Oracle tutorial: Date Time 解释如何使用 java.time.
我有一个程序可以存储 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 的实例受时区影响。我对吗 ?他说得对吗?
Can the time zone affect a java.util.Date.compareTo() result?
没有。 Date
唯一比较的是自纪元以来的毫秒数。
编写测试很容易:运行相同的代码,将 JVM 的默认时区设置为不同的值。
不,java.util.Date
与时区无关,它始终是 milliseconds-since-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.time 中的 Instant
而不是 old-fashioned Date
class,现代的 Java 日期和时间 API.
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
就是顾名思义,一个时间点,不多也不少。完全不受时区限制。
在我的比较中,我允许瞬间相等。我使用 not before 表示 同时或在 之后。如果您需要像在您自己的代码中一样严格遵守本地即时信息,则可以只使用 isAfter()
。
Link
Oracle tutorial: Date Time 解释如何使用 java.time.