在Java中反序列化人类可读持续时间的最简单方法是什么?

问题描述 投票:1回答:1

我需要为项目设置可配置的超时,从YAML文件中读取不同的配置。

我注意到java.time.Duration有方法parse,杰克逊用它来反序列化持续时间字符串。问题是它使用ISO-8601格式并期望持续时间具有PnDTnHnMn.nS格式。虽然遵循标准是一个好主意,但要求人们提供超时,因为PT10M不是最佳选择,而10m是首选。

我确实为持续时间字段编写了一个自定义反序列化器,但奇怪的是杰克逊默认情况下无法处理这个问题。

使用Jackson ObjectMapper将人类友好的10m5s1h反序列化为java.time.Duration的最简单方法是什么?

java jackson deserialization duration jackson-modules
1个回答
2
投票

将人类友好的10m5s1h反序列化的“最简单”方法可能是正则表达式和Java代码的组合。

public static Duration parseHuman(String text) {
    Matcher m = Pattern.compile("\\s*(?:(\\d+)\\s*(?:hours?|hrs?|h))?" +
                                "\\s*(?:(\\d+)\\s*(?:minutes?|mins?|m))?" +
                                "\\s*(?:(\\d+)\\s*(?:seconds?|secs?|s))?" +
                                "\\s*", Pattern.CASE_INSENSITIVE)
                       .matcher(text);
    if (! m.matches())
        throw new IllegalArgumentException("Not valid duration: " + text);
    int hours = (m.start(1) == -1 ? 0 : Integer.parseInt(m.group(1)));
    int mins  = (m.start(2) == -1 ? 0 : Integer.parseInt(m.group(2)));
    int secs  = (m.start(3) == -1 ? 0 : Integer.parseInt(m.group(3)));
    return Duration.ofSeconds((hours * 60L + mins) * 60L + secs);
}

测试

System.out.println(parseHuman("1h"));
System.out.println(parseHuman("1 hour 200 minutes"));
System.out.println(parseHuman("3600 secs"));
System.out.println(parseHuman("2h3m4s"));

产量

PT1H
PT4H20M
PT1H
PT2H3M4S
© www.soinside.com 2019 - 2024. All rights reserved.