Какой самый простой способ десериализации времени, читаемого человеком, в Java?
Мне нужно иметь настраиваемое время ожидания для проекта, который читает различные конфигурации из файла YAML.
Я заметил, что java.time.Duration
имеет метод parse, который используется Джексоном для десериализации строк продолжительности. Проблема в том, что он использует форматирование ISO-8601 и ожидает, что продолжительность PnDTnHnMn.nS
формат. В то время как это хорошая идея следовать стандартам, просить людей предоставить время ожидания как PT10M
это не лучший вариант и 10m
является предпочтительным.
Я написал собственный десериализатор для полей длительности, но кажется странным, что Джексон не может справиться с этим по умолчанию.
Какой самый простой способ десериализации человека дружественным 10m
, 5s
а также 1h
в java.time.Duration
используя Jackson ObjectMapper?
1 ответ
"Самый простой" способ десериализации человека дружественным 10m
, 5s
а также 1h
скорее всего, это сочетание регулярных выражений и кода 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