将您的字符串转换为 ISO 8601 格式并解析为 PeriodDuration
我的想法是使用PeriodDurationThreeTen Extra 项目的类。它结合了您已经提到的Period和类。Duration一个限制是它的parse方法只接受 ISO 8601 格式,所以我们需要先将你的字符串转换成那种格式。ISO 8601 格式就像P10DT9M10 天 9 分钟。P是固定的。T如果有一个(小时、分钟、秒)将它与基于日期的部分(年、月、周、天)分开,则标记基于时间的部分的开始。一个很好的结果是,我们总是可以分辨是M几个月还是分钟:如果M在之前T或没有T,它意味着几个月。如果M之后T, 表示分钟。我的第一个代码段将您的字符串转换为 ISO 8601。
String[] examples = {
"29 days 23 hours 59 minutes 20 seconds",
"4 years 10 months 10 seconds",
"10 days 9 minutes",
"1 month"
};
for (String pds : examples) {
// If hours, minutes or seconds are present, put a T before them
String temp = pds.replaceFirst("(\\d+ *(?:hour|minute|second))", " T $1");
// Abbreviate all units to 1 letter; remove spaces
temp = temp.replaceAll("([ymwdhms])[a-z]*", "$1").replace(" ", "");
// Prepend P
String iso = "P" + temp;
System.out.println(iso);
}
到目前为止的输出是:
P29dT23h59m20s
P4y10mT10s
P10dT9m
P1m
在此之后,我们应该能够解析:
PeriodDuration pd = PeriodDuration.parse(iso);
我还没有安装 ThreeTen Extra,所以在发布之前我没有尝试过最后一行。OP 在评论中报告说,它就像 ThreeTen Extra 1.6.0 的魅力。唯一需要注意的是,解析字符串时单位必须按降序排列,否则会抛出DateTimeParseException.
不必担心 ISO 8601 格式通常以大写形式给出,而您的单位则以小写形式给出。该parse方法的文档指出:
这些部分的 ASCII 后缀为“Y”表示年,“M”表示月,“W”表示周,“D”表示天,“H”表示小时,“M”表示分钟,“S”表示秒,已接受大写或小写。
编辑:感谢 Arvind Kumar Avinash 的评论,如果您也需要接受大写字母,请在正则表达式中添加(?i)标志表达式以启用不区分大小写的匹配:
temp = temp.replaceAll("(?i)([ymwdhms])[a-z]*", "$1").replace(" ", "");
链接