解析为 LocalTime 模式 mm:ss.S

Eli*_*jus 2 java parsing duration localtime java-time

如何从字符串中解析 LocalTime,例如 mm:ss.S 格式的“10:38.0”?我很难改变格式。

    public static LocalTime parseTime(String time) {
        return localTime = LocalTime.parse(time, DateTimeFormatter.ofPattern("mm:ss.S"));
    }

Run Code Online (Sandbox Code Playgroud)

出现错误

java.time.format.Parsed java.time.format.DateTimeParseException 类型的 ISO:无法解析文本 '10:38.2':无法从 TemporalAccessor 获取 LocalTime:{MinuteOfHour=10,MicroOfSecond=200000,MilliOfSecond=200,NanoOfSecond =200000000,秒数=38},

Ole*_*.V. 5

java.time.Duration.parse()

\n

正如其他几个人正确而明智地指出的那样,您的示例字符串10:38.0看起来更像是一段时间,一段持续时间。不像一天中午夜过后 10 分钟多一点的时间。所以LocalTime这里使用的类不是正确的。使用Duration。并将字符串解析为Duration对象。

\n

不过,该类Duration仅支持解析 ISO 8601 格式。ISO 8601 格式的PT10M38.0S时间段为 10 分 38.0 秒(或者例如PT10M38SPT10M38.00000S,它们也有效)。有更多方法可以克服这个限制。Arvind Kumar Avinash 已经在他的回答中展示了这一点。我的方法是在解析字符串之前对其进行转换:

\n
public static Duration parseTime(String time) {\n    String iso = time.replaceFirst("^(\\\\d+):(\\\\d+(?:\\\\.\\\\d*)?)$", "PT$1M$2S");\n    return Duration.parse(iso);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

让\xe2\x80\x99s 尝试一下:

\n
    Duration dur = parseTime("10:38.0");\n    System.out.println(dur);\n
Run Code Online (Sandbox Code Playgroud)\n

输出是:

\n
\n

PT10M38S

\n
\n

您会看到Duration打印回来也是 ISO 8601 格式。

\n

根据您想要进行的进一步处理,您可能会在该类的文档中找到许多有用的方法;下方链接。

\n

工作原理time.replaceFirst("^(\\\\d+):(\\\\d+(?:\\\\.\\\\d*)?)$", "PT$1M$2S")我使用正则表达式来匹配您的字符串:

\n
    \n
  • ^:匹配字符串的开头。
  • \n
  • (\\\\d+):匹配一个或多个数字的捕获组。圆括号表示捕获组。我将在下面的替换中需要此功能。
  • \n
  • ::冒号(确实)。
  • \n
  • (\\\\d+(?:\\\\.\\\\d*)?):捕获的一组数字,可选地后跟一个点和零个或多个其他数字。(?:表示我使用的非捕获组的开头,因为我在替换中不需要单独使用它。?在非捕获组之后表示它是可选的(因此38没有分数也适用于秒)。
  • \n
  • $:匹配字符串的结尾
  • \n
\n

在我的替换字符串、和中PT$1M$2S,表示第一个和第二个捕获组所行进的内容,这就是将和插入到结果字符串中以获得 的内容。$1$21038.0PT10M38.0S

\n

使用外部库的更好解决方案:Time4J

\n

使用上面的不平凡的正则表达式来使您的字符串Duration.parse()满足 \xe2\x80\x99t 是完美的解决方案。Time4J 库支持基于模式的持续时间解析。因此,如果您可以容忍外部依赖项,请考虑使用它。详细内容请参阅 Time4J 作者 Meno Hochshield 的回答。

\n

链接

\n\n