将 period/duration 字符串文字解析为 Java 中的 period/Duration 实例

Mar*_*rwi 1 java time parsing date

我想将任何持续时间/周期字符串文字(采用下面示例中所示的格式)解析为 Java 中的周期/持续时间实例。

我所说的持续时间/期间是指包含基于日期和基于时间的数量的时间量。在 Java 中,Duration单独仅适用于基于时间的数量,如秒、分钟和小时,而Period单独仅适用于基于日期的数量,如年、月和日。

要解析的字符串并不总是包含所有数量。

例子:

  • 29 days 23 hours 59 minutes 20 seconds
  • 4 years 10 months 10 seconds
  • 10 days 9 minutes
  • 1 month

如果可能的话我会怎么做?

Ole*_*.V. 5

将字符串转换为 ISO 8601 格式并解析为 periodDuration

\n

我的想法是使用PeriodDurationThreeTen Extra 项目的类。它结合了您已经提到的Period和类。Duration一个限制是它的parse方法仅接受 ISO 8601 格式,因此我们需要首先将您的字符串转换为该格式。ISO 8601 格式相当于P10DT9M10 天 9 分钟。是P固定的。T如果有一个(小时、分钟、秒)将基于时间的部分与基于日期的部分(年、月、周、日)分开,则标记基于时间的部分的开始。一个很好的结果是,我们总是可以判断是M指月份还是分钟:如果M出现在 之前T或没有T,则表示月份。如果M在 后面T,则表示分钟。我的第一个代码片段将您的字符串转换为 ISO 8601。

\n
    String[] examples = {\n            "29 days 23 hours 59 minutes 20 seconds", \n            "4 years 10 months 10 seconds",\n            "10 days 9 minutes", \n            "1 month" \n    };\n    \n    for (String pds : examples) {\n        // If hours, minutes or seconds are present, put a T before them\n        String temp = pds.replaceFirst("(\\\\d+ *(?:hour|minute|second))", " T $1");\n        // Abbreviate all units to 1 letter; remove spaces\n        temp = temp.replaceAll("([ymwdhms])[a-z]*", "$1").replace(" ", "");\n        // Prepend P\n        String iso = "P" + temp;\n        System.out.println(iso);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

到目前为止的输出是:

\n
\n
P29dT23h59m20s\nP4y10mT10s\nP10dT9m\nP1m\n
Run Code Online (Sandbox Code Playgroud)\n
\n

之后我们应该能够解析:

\n
        PeriodDuration pd = PeriodDuration.parse(iso);\n
Run Code Online (Sandbox Code Playgroud)\n

我还没有安装 ThreeTen Extra,所以在发布之前我没有尝试过最后一行。OP 在评论中报道称,它在 ThreeTen Extra 1.6.0 上就像一个魅力。唯一需要注意的是,解析字符串时单位必须按降序排列,否则会抛出DateTimeParseException.

\n

不要担心 ISO 8601 格式通常是大写的,而你的单位是小写的。该parse方法的文档指出:

\n
\n

这些部分的 ASCII 后缀为“Y”代表年、“M”代表月、\n“W”代表周、“D”代表天、“H”代表小时、“M”代表分钟、“S”代表\ nseconds,接受大写或小写。

\n
\n

编辑:感谢 Arvind Kumar Avinash 的评论,如果您也需要接受大写字母,请(?i)在正则表达式中添加标志表达式以启用不区分大小写的匹配:

\n
        temp = temp.replaceAll("(?i)([ymwdhms])[a-z]*", "$1").replace(" ", "");\n
Run Code Online (Sandbox Code Playgroud)\n

链接

\n\n