【问题标题】:Can the time zone affect a java.util.Date.compareTo() result?时区会影响 java.util.Date.compareTo() 结果吗?
【发布时间】:2021-02-18 01:31:47
【问题描述】:

我有一个程序可以存储托管在 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 date ftp


【解决方案1】:

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

没有。 Date 唯一比较的是自纪元以来的毫秒数。

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

【讨论】:

    【解决方案2】:

    不,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());
        }
    

    【讨论】:

      【解决方案3】:

      java.time

      这不是你问的,但我认为这对你来说会很有趣,尤其是对很多其他对此和类似问题感兴趣的人来说。如果您使用来自 java.time(现代 Java 日期和时间 API)的 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 就是这个名字所说的,一个时间点,不多也不少。完全独立于时区。

      在我的比较中,我允许瞬间相等。我用 not before 表示同一时间或之后。如果您需要严格按照您自己的代码中的本地即时进行操作,则可以使用 isAfter()

      链接

      Oracle tutorial: Date Time 解释如何使用 java.time。

      【讨论】:

        猜你喜欢
        • 2016-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-15
        • 2019-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多