如何在Java中获取日期的日期模式
我正在用多个日期模式解析日期。我将把日期字符串传递给parsedate方法。我的日期字符串已解析。但是我想得到被解析的日期模式 例如: 输入日期:“2018-04-29” 过程:日期(“2018-04-29”) 输出:成功解析日期如何在Java中获取日期的日期模式,java,date,dateformatter,Java,Date,Dateformatter,我正在用多个日期模式解析日期。我将把日期字符串传递给parsedate方法。我的日期字符串已解析。但是我想得到被解析的日期模式 例如: 输入日期:“2018-04-29” 过程:日期(“2018-04-29”) 输出:成功解析日期 我的期望是得到输入日期为“2018-04-29”的模式为“yyyy-MM-dd”。如何获得它?查看文档后,似乎无法确定哪些可选格式成功。因此,简单的解决方法是构建一组格式化程序进行尝试,并按顺序使用它们,直到成功为止。然而,这很难看:您正在为流控制使用异常 一种解决这
我的期望是得到输入日期为“2018-04-29”的模式为“yyyy-MM-dd”。如何获得它?查看文档后,似乎无法确定哪些可选格式成功。因此,简单的解决方法是构建一组格式化程序进行尝试,并按顺序使用它们,直到成功为止。然而,这很难看:您正在为流控制使用异常 一种解决这个问题的方法。我建议的答案大致如下 一个更简洁的选择可能是将格式用作正则表达式(仅检查可能的候选格式)和实际日期格式(仅解析好的候选格式)。这是以可读性为代价的,并且在解析不明确的格式时仍然会抛出异常,因为正则表达式代码的格式非常简单:
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
最初的代码现在可以写成:
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();
}
}
在进一步复杂化这一点之前,我可能只会使用丑陋的异常作为控制流(第一个代码段),作为重新实现时间解析库的较小危害
免责声明:上述代码未经测试,可能无法按预期编译和/或执行我想我同意Andreas的意见:尝试一下日期字符串以确定其格式非常简单
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
}
请使用问题中的示例字符串进行尝试:
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";
}
}
输出为:
如果您更喜欢动态、自动和可扩展的解决方案:
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
看起来像个傻瓜!时刻:只需检查分隔符的存在:
if(date.indexOf('/')!=-1){/*pattern#3*/}else(date.indexOf('-')!=-1){/*pattern#2*/}else{/*pattern#1*/}
我认为没有办法找出在使用格式化程序
解析后匹配的可选格式。如果需要此信息,则必须单独检查模式。LocalDateTime.parse(date,formatter)
无法工作,因为字符串中没有时间。坚持使用LocalDate
。如此干净和清晰!到目前为止,第二种方法比第一种要好。
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);
}