【问题标题】:DateTimeFormatter cannot be applied to (java.util.Date)DateTimeFormatter 不能应用于 (java.util.Date)
【发布时间】:2020-08-25 05:02:25
【问题描述】:

我决定使用 DateTimeFormatter 而不是 SimpleDateFormat,因为我听说 SimpleDateFormat 不是线程安全的。我在常量文件中声明了 DateTimeFormatter,如下所示。

public static final DateTimeFormatter GENERAL_TZ_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");

在我的类文件中,我的实现是这样的。

String value = Constant.GENERAL_TZ_FORMATTER.format(new Date(date.get()));

但似乎这不是正确的实现。因为它说 DateTimeFormatter 中的格式 (java.time.temporal.TemporalAccessor) 不能应用于 (java.util.Date) 并返回类似这样的错误,“java.incompatible.types: java.util.Date cannot be converted to java.time.temporal.TemporalAccessor

我正在为此进行背景调查,但仍在努力寻找解决问题的最佳方法。我想知道您对此的想法,它将帮助我找到更好的解决方案。非常感谢您的建议。谢谢。

【问题讨论】:

  • DateTimeFormatter 是 java new time API 的一部分。如果您想使用DateTimeFormatter,则应考虑使用LocalDateTime 而不是java.util.Date
  • 类似String value = Constant.GENERAL_TZ_FORMATTER.format(LocalDateTime.now());

标签: java exception datetime-format simpledateformat


【解决方案1】:

new Date(date.get()) 意味着date.get() 返回一个long 与毫秒-since-epoch。

由于您使用的是来自新 Java Time API 的DateTimeFormatter,因此您必须为其提供来自同一 API 的日期对象。 Instant 就是这样一个对象,可以使用毫秒值创建。

但是,您使用的格式字符串不能与Instant 一起使用,因此您首先需要将其转换为相关时区的ZonedDateTime。在下面的代码中,我们假设您需要 JVM 的默认时区,这是旧的 java.util.Date API 会使用的。

long epochMilli = 1598336543358L;

DateTimeFormatter GENERAL_TZ_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");

Instant instant = Instant.ofEpochMilli(epochMilli);
ZonedDateTime dateTime = instant.atZone(ZoneId.systemDefault());
String value = GENERAL_TZ_FORMATTER.format(dateTime);
       // or:  dateTime.format(GENERAL_TZ_FORMATTER)
System.out.println(value);

由于我在美国东部时区,我得到:

2020-08-25 02:22:23 EDT

作为一个单独的语句,您可以将其编写如下,但您可能会将其格式化为多行以使其更易于阅读。

// Single line
String value = Instant.ofEpochMilli(epochMilli).atZone(ZoneId.systemDefault()).format(GENERAL_TZ_FORMATTER);
// Formatted for readability
String value = Instant.ofEpochMilli(epochMilli)
                      .atZone(ZoneId.systemDefault())
                      .format(GENERAL_TZ_FORMATTER);

【讨论】:

    【解决方案2】:

    DateTimeFormatter 是 java new time API 的一部分。如果您想使用DateTimeFormatter,则应考虑使用LocalDateTime 而不是java.util.Date

    您可以在您的情况下使用DateTimeFormator,如下所示:

    String value = Constant.GENERAL_TZ_FORMATTER.format(LocalDateTime.now());
    

    【讨论】:

    • 没用,因为它会导致java.time.DateTimeException: Unable to extract ZoneId from temporal 2020-08-25T02:32:37.624048
    【解决方案3】:
    class Constant {
        public static final SimpleDateFormat GENERAL_TZ_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
    
        public static void main(String[] args) {
            String value = Constant.GENERAL_TZ_FORMATTER.format(new Date());
            System.out.println(value);
        }
    }
    

    如上所述,您可以使用 SimpleDateFormat

    更多关于 SimpleDateFormat 的内容,关注link你会有所了解

    【讨论】:

    • 但是,在 Java 8+ 中编写新代码时,强烈建议不要这样做。新代码应该使用新的 Java Time API,因为旧的 Date API 被认为是过时的(因为它有缺陷)。替换 java.util.Date 的使用会比替换 DateTimeFormatter 的使用更好。
    • 我不是投反对票的人,但我的猜测是,由于我在评论中提到的原因,它被投反对票。告诉人们使用旧的过时 API 并不是一个有用的答案,尤其是当您甚至没有在答案中警告它时,并且因为 OP 显然可以/想要使用较新的 API。
    • 问题开始时(明智地)声明提问者不想使用SimpleDateFormat,因为它不是线程安全的。通过使用该类,您可以准确地向他提供他从一开始就试图避免的多线程程序中的错误。此外SimpleDateFormat 是一个臭名昭著的班级麻烦制造者,正如@Andreas 指出的那样,早已过时。
    猜你喜欢
    • 1970-01-01
    • 2017-09-17
    • 2022-01-03
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    相关资源
    最近更新 更多