Durations { public static Duration parseDuration(CharSequence text) { Matcher matcher = PATTERN.matcher(text); if (!matcher.matches()) { throw new DateTimeParseException("Invalid duration", text, 0); } String d = matcher.group("days"); String h = matcher.group("hours"); String m = matcher.group("minutes"); String s = matcher.group("seconds"); if (d == null && h == null && m == null && s == null) { throw new DateTimeParseException("Invalid duration", text, 0); } return Duration .ofDays(d == null ? 0 : Long.parseLong(d)) .plusHours(h == null ? 0 : Long.parseLong(h)) .plusMinutes(m == null ? 0 : Long.parseLong(m)) .plusSeconds(s == null ? 0 : Long.parseLong(s)); }  static Duration parseDuration(CharSequence text); static String formatDuration(Duration duration);  }
@Test public void testValidDurations() throws Exception { assertThat(parseDuration("17d"), is(Duration.ZERO.plusDays(17))); assertThat(parseDuration("17D"), is(Duration.ZERO.plusDays(17))); assertThat(parseDuration(" 17 d "), is(Duration.ZERO.plusDays(17))); assertThat(parseDuration("17h"), is(Duration.ZERO.plusHours(17))); assertThat(parseDuration("17H"), is(Duration.ZERO.plusHours(17))); assertThat(parseDuration(" 17 h "), is(Duration.ZERO.plusHours(17))); assertThat(parseDuration("17m"), is(Duration.ZERO.plusMinutes(17))); assertThat(parseDuration("17M"), is(Duration.ZERO.plusMinutes(17))); assertThat(parseDuration(" 17 m "), is(Duration.ZERO.plusMinutes(17))); assertThat(parseDuration("17s"), is(Duration.ZERO.plusSeconds(17))); assertThat(parseDuration("17S"), is(Duration.ZERO.plusSeconds(17))); assertThat(parseDuration(" 17 s "), is(Duration.ZERO.plusSeconds(17))); assertThat(parseDuration("17s"), is(Duration.ZERO.plusSeconds(17))); assertThat(parseDuration("17S"), is(Duration.ZERO.plusSeconds(17))); assertThat(parseDuration(" 17 s "), is(Duration.ZERO.plusSeconds(17))); assertThat(parseDuration("13m17s"), is(Duration.ZERO.plusMinutes(13).plusSeconds(17))); assertThat(parseDuration(" 13 m 17 s "), is(Duration.ZERO.plusMinutes(13).plusSeconds(17))); assertThat(parseDuration(" 13 m 17 s "), is(Duration.ZERO.plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("13M17S"), is(Duration.ZERO.plusMinutes(13).plusSeconds(17))); assertThat(parseDuration(" 13 M 17 S "), is(Duration.ZERO.plusMinutes(13).plusSeconds(17))); assertThat(parseDuration(" 13 m 17 s "), is(Duration.ZERO.plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("21h13m17s"), is(Duration.ZERO.plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration(" 21h 13m 17s "), is(Duration.ZERO.plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("21H13M17S"), is(Duration.ZERO.plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration(" 21 H 13 M 17 S "), is(Duration.ZERO.plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("3d21h13m17s"), is(Duration.ZERO.plusDays(3).plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("3d 21h 13m 17s "), is(Duration.ZERO.plusDays(3).plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("3D21H13M17S"), is(Duration.ZERO.plusDays(3).plusHours(21).plusMinutes(13).plusSeconds(17))); assertThat(parseDuration("3 D 21 H 13 M 17 S "), is(Duration.ZERO.plusDays(3).plusHours(21).plusMinutes(13).plusSeconds(17))); }
@Test public void testInvalidValidDurations() throws Exception { assertThrows(() -> parseDuration(""), DateTimeParseException.class); assertThrows(() -> parseDuration("17"), DateTimeParseException.class); assertThrows(() -> parseDuration("1 7s"), DateTimeParseException.class); assertThrows(() -> parseDuration("-4s"), DateTimeParseException.class); assertThrows(() -> parseDuration("foobar"), DateTimeParseException.class); }