【问题标题】:Java DateTimeFormatter parsing with special charactersJava DateTimeFormatter 用特殊字符解析
【发布时间】:2020-09-25 12:59:53
【问题描述】:

我在正确使用DataTimeFormatter 解析日期时间String 时遇到了一些麻烦,格式为:

20200915095318.883[-4:EDT]

我有一个DateTimeFormatter 模式可以生成这种格式,但它不能解析相同的字符串。该模式是:

yyyyMMddHHmmss.SSS'['x':'z']'

如果还有其他更适合此类需求的 DateTime 解析库,我也会很乐意考虑这些库。现在,当我遇到此 DateTime 字符串并手动构建其部分时,我的解决方案是一次性的正则表达式匹配器。这太恶心了。

【问题讨论】:

  • 抛出了什么异常?你能发布错误信息吗?
  • 如果能看到能重现问题的简洁代码集也很好。
  • 我认为这是偏移量的格式,支持的格式(根据JavaDocs of DateTimeFormatter+0000; -08; -0830; -08:30; -083015; -08:30:15,因此不支持-4 的偏移量,它需要前导零。现在取决于可以提供 DateTimeFormatterBuilder 的人来解析没有前导零的偏移量。可能有可能,可能不可能,还不知道......
  • I have a DateTimeFormatter pattern that works to produce this format, but it doesn't work to parse the same String. That pattern is: yyyyMMddHHmmss.SSS'['x':'z']' - 这是不正确的。此格式化程序不会产生单个数字的偏移量(即没有日期时间字符串中缺少的前导零)。
  • 似乎需要一次性代码,因为需要 DateTimeFormatterBuilder。我会这样做,而不是正则表达式解决方案,但它仍然是一个很臭的解决方案。我很感激帮助。每个人都确认问题在于人们发挥创造力而不是使用行业标准。

标签: java datetime


【解决方案1】:

java.time,我认为您已经在使用的现代 Java 日期和时间 API,确实是最适合这项工作的库。这从 Java 9 开始有效:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuuMMddHHmmss")
            .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
            .appendLiteral('[')
            .appendOffset("+Hmm", "+0")
            .appendLiteral(':')
            .appendZoneText(TextStyle.SHORT)
            .appendLiteral(']')
            .toFormatter(Locale.ENGLISH);
    
    String s = "20200915095318.883[-4:EDT]";
    
    OffsetDateTime odt = OffsetDateTime.parse(s, formatter);
    ZonedDateTime zdt = ZonedDateTime.parse(s, formatter);
    
    if (odt.getOffset().equals(zdt.getOffset())) {
        System.out.println(odt);
        System.out.println(zdt);
    } else {
        System.out.println("Something’s wrong here");
    }

输出是:

2020-09-15T09:53:18.883-04:00
2020-09-15T09:53:18.883-04:00[America/New_York]

解析成OffsetDateTime 使用偏移量-4,而解析成ZonedDateTime 使用时区缩写EDT。我检查两人是否同意抵消,否则我不知道他们中的哪一个该相信。在您的示例字符串中,他们确实同意。

我将+Hmm 作为模式传递给appendOffset()。其他选择包括+H+H:mm+Hmmss+H:mm:ss。小写mmss 表示偏移量的分钟和秒是可选的。如果偏移量不是整数小时,您应该根据偏移量的外观进行选择。

从 Java 9 开始是什么意思? java.time、DateTimeFormatterBuilder 和它的 appendOffset 方法都在 Java 8 中,但只有在 Java 9 之后,该方法才接受一个模式,其中只有一个 H 一个数字小时。

【讨论】:

【解决方案2】:

您唯一的问题是字符串中的-4 需要前导零,正如@deHaar 在他的comment 中指出的那样,即

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS'['x':'z']'");
LocalDateTime ldt = LocalDateTime.parse("20200915095318.883[-04:EDT]", formatter);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    相关资源
    最近更新 更多