【问题标题】:Trouble formatting date in Java [duplicate]Java中的日期格式化问题[重复]
【发布时间】:2020-12-30 18:44:44
【问题描述】:

我尝试了几种使用 Java Joda Time、使用语言环境和 commons-lang 的日期时间的方法,但无法格式化此日期。

输入

Mon Dec 28 15:18:16 UTC 2020

输出

所需的输出格式yyyy-MM-dd HH:mm:ss.SSS

当我使用像 EEE MMM dd HH:mm:ss Z YYYY 这样的格式模式时,日期已经过了几天,时区似乎完全错误。

格式化程序:

  private static final DateTimeFormatter DATE_TIME_FORMATTER =
    DateTimeFormatter
      .ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
      .withLocale(Locale.US)
      .withZone(ZoneId.systemDefault());
DateUtils.parseDate (Optional
        .ofNullable(record)
        .map(CustomerModel::getCustomerAudit)
        .map(customerAudit::getCreated)
        .map(auditItem::getDate).get ().toString (), "EEE MMM dd HH:mm:ss YYYY")

【问题讨论】:

  • 输入是什么,代码是什么,输出是什么?
  • @luk2302 使用给定的输入更新了期望输出。
  • 您能添加输入使用哪种类型的类吗? (字符串、LocalDate、LocalDateTime)
  • @OneCricketeer 添加了更多代码
  • 你需要 commons-lang 吗? java.time 类应该可以正常工作

标签: java date datetime


【解决方案1】:

在调试解析问题时,如果可能,逆向操作并生成您应该解析的文本,以验证解析规则,即日期格式字符串。这适用于日期解析、JAXB 解析和任何其他双向(反)序列化操作。它使查找转换规则问题变得更加容易。

所以,让我们检查问题中的格式字符串,以及显示的日期值:

ZonedDateTime dateTime = ZonedDateTime.of(2020, 12, 28, 15, 18, 16, 0, ZoneOffset.UTC);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z YYYY", Locale.US);
System.out.println(dateTime.format(fmt));

输出

Mon Dec 28 15:18:16 +0000 2021

哎呀!这不符合预期的输出,也就是我们想要解析的输入:

Mon Dec 28 15:18:16 UTC 2020

那么到底出了什么问题?

  1. 年份是错误的,因为它应该是 uuuu(年份),而不是 YYYY(基于周的年份)。

  2. 时区错误,因为Z 确实支持文本表示。请改用VVz

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.US);

ZonedDateTime dateTime = ZonedDateTime.parse("Mon Dec 28 15:18:16 UTC 2020", fmt);
System.out.println(dateTime);
System.out.println(dateTime.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS")));

输出

2020-12-28T15:18:16Z[UTC]
2020-12-28 15:18:16.000

如您所见,它现在解析正确。

【讨论】:

  • 这也可以与 2020-12-28T15:18:17.461525Z[Etc/UTC] 之类的东西一起使用吗?我对这些 UTC 类型值感到困惑。
  • @Ryan 该文本是ZonedDateTime 的自然格式,因此只需调用parse(text) 方法,例如ZonedDateTime.parse("2020-12-28T15:18:17.461525Z[Etc/UTC]")
【解决方案2】:

问题中的代码意义不大:

  • 它使用toString()Date 值格式化为文本,只是为了尝试将其解析回来。

  • 它使用Optional 进行简单的空处理(不鼓励这样做),但随后无条件调用get(),这意味着null 值无论如何都会抛出异常。

代码应该是:

record.getCustomerAudit().getCreated().getDate().toInstant()

这当然会让整个问题变得毫无意义。

【讨论】:

  • 即使是同一个问题的两个好答案。
  • @OleV.V.是的,它们也是完全不同的答案,这就是为什么我创建了两个不同的答案。
【解决方案3】:

对我来说很好。

String s = "Mon Dec 28 15:18:16 UTC 2020";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss VV yyyy",
                                                          Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(s, formatter);
formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
System.out.println(zdt.format(formatter));

输出是

2020-12-28 15:18:16.000

我错过了什么吗?

【讨论】:

  • 这也可以与 2020-12-28T15:18:17.461525Z[Etc/UTC] 之类的东西一起使用吗?我对这些 UTC 类型值感到困惑。
  • @Ryan with 是什么意思?这个答案中的zdt2020-12-28T15:18:16Z[UTC],它有点接近,显然它没有微秒。如果您能更准确地告诉我们什么让您感到困惑,我们想解释一下。
【解决方案4】:

您尝试过 SimpleDateFormat 吗?

String dateString = "Mon Dec 28 15:18:16 UTC 2020";

SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);

System.out.println(output.format(input.parse(dateString)));

有时区:

String dateString = "Mon Dec 28 15:18:16 UTC 2020";

SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd z HH:mm:ss.SSS");
input.setTimeZone(TimeZone.getTimeZone("UTC"));
output.setTimeZone(TimeZone.getTimeZone("UTC"));

System.out.println(output.format(input.parse(dateString)));

【讨论】:

  • 请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中做得更好。 OP 已经在使用 java.time。 DarkMatter,你正在向我们展示我们永远不想再去的方向。
  • 智慧之言?老实说,我不知道。事实是我鄙视日期/时间转换并像瘟疫一样避免它。也许在这方面时间已经过去了(这算双关语吗?)而我已经过去了。但是,SimpleDateFormat 一直对我很有帮助。但是,如果您愿意,请随时编辑我的答案并向后代添加警告。 (在我的辩护中,我想补充一下,我的答案并不是第一个。)很好满足@OleV.V.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-23
  • 2019-02-19
  • 2021-01-20
  • 2013-06-25
  • 2011-06-07
  • 2013-06-03
相关资源
最近更新 更多