解析日期时间字符串中的日期序号指示符 ( st, nd, rd, th )
我检查了SimpleDateFormat
javadoc,但我无法找到一种方法来解析日期格式的序号指示器,如下所示:
Feb 13th 2015 9:00AM
我试过了,但是日子必须数到一半才能正确吗?"MMM dd yyyy hh:mma"
是否可以使用 解析 “13th” 日期而不必截断字符串?SimpleDateFormat
我检查了SimpleDateFormat
javadoc,但我无法找到一种方法来解析日期格式的序号指示器,如下所示:
Feb 13th 2015 9:00AM
我试过了,但是日子必须数到一半才能正确吗?"MMM dd yyyy hh:mma"
是否可以使用 解析 “13th” 日期而不必截断字符串?SimpleDateFormat
Java的SimpleDateFormat不支持序号后缀,但序号后缀只是眼睛糖果 - 它是多余的,可以很容易地删除以允许直接解析:
Date date = new SimpleDateFormat("MMM dd yyyy hh:mma")
.parse(str.replaceAll("(?<=\\d)(st|nd|rd|th)", ""));
替换正则表达式非常简单,因为这些序列不会出现在有效日期的任何其他位置。
要处理将任何语言中任意长度的序号指示符追加为后缀的任何语言,
Date date = new SimpleDateFormat("MMM dd yyyy hh:mma")
.parse(str.replaceAll("(?<=\\d)(?=\\D* \\d+ )\\p{L}+", ""));
有些语言,例如普通话,在序号指示器之前附加,但这也可以使用交替来处理 - 留给读者作为练习:)
Java 8的答案(以及Java 6和7)(因为当2015年提出这个问题时,替代品已经出来了):SimpleDateFormat
DateTimeFormatter parseFormatter = DateTimeFormatter
.ofPattern("MMM d['st']['nd']['rd']['th'] uuuu h:mma", Locale.ENGLISH);
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, parseFormatter);
使用问题的示例日期,这个yedls:
2015-02-13T09:00
在格式模式中,表示可选部件并表示文本部件。因此,该模式表示该数字后面可能跟有 、 、 或 。[]
''
st
nd
rd
th
要在Java 6或7中使用它,您需要ThreeTen Backport。或者对于Android ThreeTenABP。
由于这些后缀对于英语是特殊的,并且其他语言/区域设置在编写日期和时间方面具有完全不同的用法(它们也不使用AM / PM),因此我相信除非您有其他要求,否则您应该尝试仅针对英语日期和时间实现此功能。此外,您应该明确地提供一个讲英语的区域设置,以便它将独立于计算机或JVM的区域设置工作。
我试图将雨果和我自己回答的最佳部分组合成一个重复的问题。在那个重复的问题下,还有更多的java 8答案。上述代码的一个限制是它没有非常严格的验证:您将逃脱甚至.Feb 13rd
Feb 13stndrdth
编辑:我自己最喜欢的是关于序数指标的答案是这个。这是关于格式化的,但我在那里介绍的格式化程序也适用于解析。