如何在java中获取日期的日期模式

uoifb46i  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(255)
public void parsedate(String date) {
    DateTimeFormatter formatter = null;

    formatter = new DateTimeFormatterBuilder()
            .appendOptional(DateTimeFormatter.ofPattern("yyyyMMdd"))
            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            .appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy")).toFormatter();
    TemporalAccessor parse = formatter.parse(date);
    System.out.println("original" + date);

    return LocalDateTime.parse(date, formatter);
}

    String[] strDates = new String[]{
            "20180429",
            "2018-04-29",
            "04/29/2018",
            "01/20/1999",
            "1899-12-25",
            "2020-02-29", // leap year future
            "00010101",
            "19160229" // leap year past
    };

    for(String date: strDates) {
        parsedate(date);
    }

我正在用多种日期模式解析日期。我将把日期字符串传递给parsedate方法。我的日期字符串已解析。但是我想得到被解析的日期的模式。
例子:
输入日期:“2018-04-29”处理:解析日期(“2018-04-29”)输出:解析成功日期
我的期望是得到输入日期为“2018-04-29”的模式为“yyyy-mm-dd”。如何得到它?

rkttyhzu

rkttyhzu1#

我想我同意安德烈亚斯的意见:尝试一下日期字符串来确定其格式非常简单。

public static String getPattern(String dateString) {
    if (dateString.length() == 8) { // compact format
        return "uuuuMMdd";
    } else if (dateString.charAt(2) == '/') {
        return "MM/dd/uuuu";
    } else {
        return "uuuu-MM-dd";
    }
}

使用问题中的示例字符串进行尝试:

String[] strDates = new String[]{
            "20180429",
            "2018-04-29",
            "04/29/2018",
            "01/20/1999",
            "1899-12-25",
            "2020-02-29", // leap year this year
            "00010101",
            "19160229" // leap year past
    };

    for(String date: strDates) {
        String pattern = getPattern(date);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        LocalDate parsedDate = LocalDate.parse(date, formatter);
        System.out.format("%-10s pattern: %-10s parsed: %s%n", date, pattern, parsedDate);
    }

输出为:

20180429   pattern: uuuuMMdd   parsed: 2018-04-29
2018-04-29 pattern: uuuu-MM-dd parsed: 2018-04-29
04/29/2018 pattern: MM/dd/uuuu parsed: 2018-04-29
01/20/1999 pattern: MM/dd/uuuu parsed: 1999-01-20
1899-12-25 pattern: uuuu-MM-dd parsed: 1899-12-25
2020-02-29 pattern: uuuu-MM-dd parsed: 2020-02-29
00010101   pattern: uuuuMMdd   parsed: 0001-01-01
19160229   pattern: uuuuMMdd   parsed: 1916-02-29

如果您更喜欢动态、自动和可扩展的解决方案:

private static final String[] formatPatterns = { "uuuuMMdd", "uuuu-MM-dd", "MM/dd/uuuu" };

public static String getPattern(String dateString) {
    for (String pattern : formatPatterns) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
            LocalDate.parse(dateString, formatter);
            // If we ended up here, using the pattern was successful
            return pattern;
        } catch (DateTimeParseException dtpe) {
            // Do nothing, try next pattern
        }
    }
    throw new IllegalArgumentException("We don’t know the format pattern string for " + dateString);
}
aamkag61

aamkag612#

在查看了文档之后,似乎无法确定哪些可选格式成功了。因此,简单的解决方法是构建一个格式化程序集合来尝试,并按顺序使用它们,直到成功为止。但是,这很难看:您正在使用异常来进行流控制

LocalDateTime time = null;
DateTimeFormatter goodFormatter = null;
for (DateTimeFormatter formatter : formats) {
    try {
        time = LocalDateTime.parse(date, formatter);
        goodFormatter = formatter;
        break;
    } catch (DateTimeParseException dtpe) {
        // not really exceptional - bad coding practice
    }
}
// if goodFormatter != null, there you have it

现有的一个问题就是这样处理这个问题的。我建议的答案与其中一个答案大致相同。
一个更简洁的选择可能是将您的格式同时用作正则表达式(仅检查可能的候选格式)和实际日期格式(仅解析好的候选格式)。这是以可读性为代价的,并且在解析不明确的格式时仍然会抛出异常,因为regex代码的格式非常简单:

enum FormatCandidate {
    YMD("yyyyMMdd"),
    YMD_DASHED("yyyy-MM-dd"),
    MDY_SLASHED("MM/dd/yyyy");

    private final Pattern pattern;
    public final DateTimeFormatter formatter;  // immutable & thread safe

    FormatCandidate(String format) {
        // THIS ONLY WORKS FOR SIMPLE EXAMPLES; modify for more complex ones!
        this.pattern = Pattern.compile(format
              .replaceAll("[-/]", "\\\0")  // preserved characters
              .replaceAll("[yMd]","\\d")   // digits
        ));
        this.formatter = new DateTimeFormatterBuilder()
              .appendPattern(format).toFormatter();
    }

    // this should really be available in the DateTimeFormatter class
    public boolean canParse(String date) {
        return pattern.matcher(date).matches();
    }
}

最初的代码现在可以写成:

DateTimeFormatter goodFormatter = null;
for (FormatCandidate candidate : FormatCandidate.values()) {
    if (candidate.canParse(date)) {
       goodFormatter = candidate.format;
       break;
    }
}

LocalDateTime time = null;   
try {
    time = LocalDateTime.(date, candidate.formatter);
} catch (DateTimeParseException dtpe) {
    // now we can complain, saying that date does not match this particular
    // expected output
}

在进一步复杂化这一点之前,我可能会使用丑陋的异常作为控制流(第一个代码段),作为重新实现时间解析库的一个较小的缺点。
免责声明:以上代码未经测试,可能无法按预期编译和/或执行

相关问题