【问题标题】:Java: Parse multiple String Date Time format into LocalDateTime/Date/CalenderJava:将多个字符串日期时间格式解析为 LocalDateTime/Date/Calendar
【发布时间】:2020-01-23 07:49:02
【问题描述】:

我正在尝试将字符串日期时间解析为 Java 中的 LocalDateTimeDate。 我可能会得到像12/21/2020 12:12:12 PM1/12/2020 2:6:8 PM10/2/2020 10:50:8 AM 这样的输入

我尝试在DateTimeFormatterDateTimeFormatBuilder 下使用不同类型的模式,它们可以工作。蛮力方法Where I am Hard coding different combination of pattern。这是从链接复制的代码:

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;

class Main {
    public static void main(String[] args) {
        // many combinations
        final String DATE_FORMATS = "[MM/dd/yyyy HH:mm:ss a][M/dd/yyyy H:mm:ss a]";
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_FORMATS);

        System.out.println(dateFormatter.parse("12/21/2020 11:12:12 AM"));
        System.out.println(dateFormatter.parse("1/12/2020 2:54:55 AM"));
    }
}

由于我无法控制输入,还有其他解决方案吗?单一模式,我可以在Formatter 中使用而不是多重组合?还是先接收后修改输入再解析更好?

【问题讨论】:

  • 我们如何告诉您是否有与您未在此处显示的解决方案不同的解决方案?请编辑您的问题并添加您的版本,谢谢!
  • 请告诉我们您尝试了什么,您期望什么以及发生了什么!
  • 说话便宜,看代码!
  • “蛮力法”是什么意思?将String 解析为java.time 类之一的标准方法是DateTimeFormatter。请出示minimal reproducible example 证明您遇到的问题。
  • 至于你的问题,你在寻找什么样的解决方案?如果您有多种可能的格式,那么您将需要多个模式或一个可以处理所有不同模式的模式(如果可能的话)。更好的选择是控制输入并要求它是某种格式。

标签: java datetime java-8 datetime-format


【解决方案1】:

tl;博士

LocalDateTime.parse(dateTimeString, DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a");
足以满足您所有的日期时间示例。


以下示例能够通过使用 LocalDateTime.parse 而不是 DateTimeFormatter.parse 来解析所有示例日期时间 Strings,它们是不同的:

public static void main(String[] args) {
    String first = "12/21/2020 12:12:12 PM";
    String second = "1/12/2020 2:6:8 PM";
    String third = "10/2/2020 10:50:8 AM";

    DateTimeFormatter dtf = DateTimeFormatter
            .ofPattern("[MM/dd/yyyy HH:mm:ss a][M/dd/yyyy h:m:s a][MM/d/yyyy HH:mm:s a]");

    System.out.println(LocalDateTime.parse(first, dtf));
    System.out.println(LocalDateTime.parse(second, dtf));
    System.out.println(LocalDateTime.parse(third, dtf));
}

看看使用的第二个/中间模式,它使用h(小写字母)而不是H(大写字母),因为一天的上午/下午将来自大写@987654328 @ 也是如此,这将导致第二个日期时间样本 "1/12/2020 2:6:8 PM" 发生冲突,其中 02:06:08 被视为 AM,但在模式中随后是 PM。

我的解决方案的输出是这样的:

2020-12-21T12:12:12
2020-01-12T14:06:08
2020-10-02T10:50:08

正确地将时间解析为 PM (14 = 02 PM)。

注意:
不要将此DateTimeFormatter 用于输出LocalDateTime.format(DateTimeFormatter),因为它会返回定义的所有三种格式...
很丑:10/02/2020 10:50:08 AM10/02/2020 10:50:8 AM10/2/2020 10:50:8 AM

【讨论】:

  • 模式DateTimeFormatter dtf = DateTimeFormatter.ofPattern("[M/d/yyyy h:m:s a]"); 适用于所有不同的组合。如果我们这样做LocalDateTime.parse
  • @Thilakraj 好的,谢谢,很高兴知道。我没有只检查一个模式,而是使用了所有模式。将其编辑为答案!
【解决方案2】:

我处理了一个类似的问题,我需要在事先不知道格式的情况下解析一个字符串。我写了一篇关于这个想法和实现的文章。以下是文章的引述:

所以我想出的解决方案是将一组格式存储在属性文件中,当需要解析字符串时,会从文件中读取格式并尝试解析字符串,每种格式都按顺序进行,直到被解析成功或直到我们用完格式。此解决方案的优点是,如果您发现未成功解析的有效字符串,您需要做的就是向属性文件添加新格式,并且不需要重新编译和重新部署。同样,您可以通过这种方式设置优先级:例如,如果美国日期格式比欧洲日期格式更可取,只需将美国格式放在首位,并且仅放在欧洲日期格式之后。同样在 java 8 中,格式字符串允许使用 '[]' 表示的可选格式部分。因此,实际上可以将几种格式组合成一个带有可选部分的格式。例如,而不是

MM/dd/yyyy
MM-dd-yyyy
MM.dd.yyyy

你可以写

MM['/']['-']['.']dd['/']['-']['.']yyyy


这是完整的链接article

【讨论】:

  • @deHaar - 非常感谢。顺便说一句,我在同一个网站上还有其他一些文章。另外,如果您能对文章发表简短评论,我将非常感激
  • 目前我还没有找到好的评论词,但我喜欢使用平台 like-function ;-)
  • 虽然内容丰富,但在我看来与所提出的问题并不十分相关。
猜你喜欢
  • 2019-09-14
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 1970-01-01
相关资源
最近更新 更多