Parses a human-readable duration (e.g, "10m", "3h", "14d") into seconds. Formats supported: ms: milliseconds s: seconds m: minutes h: hours d: days w: weeks n: month (30 days)</l
(final String duration)
| 185 | * @throws IllegalArgumentException if the interval was malformed. |
| 186 | */ |
| 187 | public static final long parseDuration(final String duration) { |
| 188 | if (duration == null || duration.isEmpty()) { |
| 189 | throw new IllegalArgumentException("Cannot parse null or empty duration"); |
| 190 | } |
| 191 | |
| 192 | long interval; |
| 193 | long multiplier; |
| 194 | double temp; |
| 195 | int unit = 0; |
| 196 | while (Character.isDigit(duration.charAt(unit))) { |
| 197 | unit++; |
| 198 | if (unit >= duration.length()) { |
| 199 | throw new IllegalArgumentException("Invalid duration, must have an " |
| 200 | + "integer and unit: " + duration); |
| 201 | } |
| 202 | } |
| 203 | try { |
| 204 | interval = Long.parseLong(duration.substring(0, unit)); |
| 205 | } catch (NumberFormatException e) { |
| 206 | throw new IllegalArgumentException("Invalid duration (number): " + duration); |
| 207 | } |
| 208 | if (interval <= 0) { |
| 209 | throw new IllegalArgumentException("Zero or negative duration: " + duration); |
| 210 | } |
| 211 | switch (duration.toLowerCase().charAt(duration.length() - 1)) { |
| 212 | case 's': |
| 213 | if (duration.charAt(duration.length() - 2) == 'm') { |
| 214 | return interval; |
| 215 | } |
| 216 | multiplier = 1; break; // seconds |
| 217 | case 'm': multiplier = 60; break; // minutes |
| 218 | case 'h': multiplier = 3600; break; // hours |
| 219 | case 'd': multiplier = 3600 * 24; break; // days |
| 220 | case 'w': multiplier = 3600 * 24 * 7; break; // weeks |
| 221 | case 'n': multiplier = 3600 * 24 * 30; break; // month (average) |
| 222 | case 'y': multiplier = 3600 * 24 * 365; break; // years (screw leap years) |
| 223 | default: throw new IllegalArgumentException("Invalid duration (suffix): " + duration); |
| 224 | } |
| 225 | multiplier *= 1000; |
| 226 | temp = (double)interval * multiplier; |
| 227 | if (temp > Long.MAX_VALUE) { |
| 228 | throw new IllegalArgumentException("Duration must be < Long.MAX_VALUE ms: " + duration); |
| 229 | } |
| 230 | return interval * multiplier; |
| 231 | } |
| 232 | |
| 233 | /** |
| 234 | * Returns the suffix or "units" of the duration as a string. The result will |