我需要在Java中解析“2010年1月10日”格式的日期。我该怎么做呢?
如何处理尾随日期数字的ordinal indicators、st
、nd
、rd
或th
?
发布于 2011-01-18 09:21:21
这是可行的:
String s = "January 10th, 2010";
DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy");
System.out.println("" + dateFormat.parse(s.replaceAll("(?:st|nd|rd|th),", "")));
但您需要确保使用正确的Locale
来正确解析月份名称。
我知道您可以在SimpleDateFormat
模式中包含常规文本。但是,在这种情况下,文本依赖于信息,实际上与解析过程无关。
这实际上是我能想到的最简单的解决方案。但我很乐意被人误导。
您可以通过执行类似以下操作来避免其中一条评论中暴露出的陷阱:
String s = "January 10th, 2010";
DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy");
System.out.println("" + dateFormat.parse(s.replaceAll("(?<= \\d+)(?:st|nd|rd|th),(?= \\d+$)", "")));
例如,这将允许您不匹配Jath,uary 10 2010
。
发布于 2019-07-19 17:13:42
我想贡献一下现代的答案。您应该使用java.time,而不是现在投票最多的两个答案中使用的SimpleDateFormat
类,它是现代Java date and time API。它提供了几个很好的解决方案。
简单的解决方案
我们首先定义一个用于解析的格式化程序:
private static final DateTimeFormatter PARSING_FORMATTER = DateTimeFormatter.ofPattern(
"MMMM d['st']['nd']['rd']['th'], uuuu", Locale.ENGLISH);
然后我们像这样使用它:
String dateString = "January 10th, 2010";
LocalDate date = LocalDate.parse(dateString, PARSING_FORMATTER);
System.out.println("Parsed date: " + date);
输出为:
解析日期: 2010-01-10
格式模式字符串中的方括号[]
包含可选部分,单引号包含文字文本。因此,d['st']['nd']['rd']['th']
意味着在月日之后可能会有st
、nd
、rd
和/或th
。
更可靠的解决方案
上面的方法有几个限制是
它接受任何序数指示符,例如,格式化程序用于解析的10st
甚至10stndrdth
.
January 10stndrdth, 2010
).如果您希望更好地验证序号指示符,或者希望将日期重新格式化为字符串,则可以按以下方式构建格式化程序:
private static final DateTimeFormatter FORMATTING_AND_PARSING_FORMATTER;
static {
Map<Long, String> ordinalNumbers = new HashMap<>(42);
ordinalNumbers.put(1L, "1st");
ordinalNumbers.put(2L, "2nd");
ordinalNumbers.put(3L, "3rd");
ordinalNumbers.put(21L, "21st");
ordinalNumbers.put(22L, "22nd");
ordinalNumbers.put(23L, "23rd");
ordinalNumbers.put(31L, "31st");
for (long d = 1; d <= 31; d++) {
ordinalNumbers.putIfAbsent(d, "" + d + "th");
}
FORMATTING_AND_PARSING_FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("MMMM ")
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(", uuuu")
.toFormatter(Locale.ENGLISH);
}
这将解析与上面相同的日期字符串。让我们也尝试一下格式化:
System.out.println("Formatted back using the same formatter: "
+ date.format(FORMATTING_AND_PARSING_FORMATTER));
使用相同的格式化程序重新格式化: 2010年1月10日
链接
发布于 2011-01-18 10:04:01
您可以将nd
等设置为SimpleDateFormat中的文字。您可以定义四种所需的格式并尝试它们。首先从th
开始,因为我猜这种情况会更经常发生。如果使用ParseException
失败,请尝试下一个。如果所有操作都失败,则抛出ParseException。这里的代码只是一个概念。在现实生活中,您可能不会每次都生成新的格式,并且可能会考虑线程安全性。
public static Date hoolaHoop(final String dateText) throws ParseException
{
ParseException pe=null;
String[] sss={"th","nd","rd","st"};
for (String special:sss)
{
SimpleDateFormat sdf=new SimpleDateFormat("MMMM d'"+special+",' yyyy");
try{
return sdf.parse(dateText);
}
catch (ParseException e)
{
// remember for throwing later
pe=e;
}
}
throw pe;
}
public static void main (String[] args) throws java.lang.Exception
{
String[] dateText={"January 10th, 2010","January 1st, 2010","January 2nd, 2010",""};
for (String dt:dateText) {System.out.println(hoolaHoop(dt))};
}
输出:
Sun Jan 10 00:00:00 GMT 2010
Fri 01 GMT 2010 00:00:00
星期六1月2日格林尼治时间2010 00:00:00
线程"main“java.text.ParseException中出现异常:无法分析日期:"”
当然,"th","nd","rd","st"
只适用于使用英语的语言环境。请记住这一点。在法国,我猜是"re","nd"
等等。
https://stackoverflow.com/questions/4722289
复制相似问题