parseDuration function

Duration parseDuration(
  1. String input
)

Parses a human-readable duration string (e.g., '1h 30m', '2 days', '45s') into a Dart Duration. Supports both short (h, m, s) and long (hours, minutes, seconds, etc.) unit forms. Throws FormatException for invalid input.

Implementation

Duration parseDuration(String input) {
  if (input.trim().isEmpty) throw FormatException('Empty duration string');
  final pattern = RegExp(r'(\d+(?:[\.,]\d+)?)\s*(ms|milliseconds?|us|microseconds?|y(?:ears?)?|d(?:ays?)?|h(?:ours?)?|m(?:in(?:ute)?s?)?|s(?:ec(?:ond)?s?)?)', caseSensitive: false);
  final matches = pattern.allMatches(input);
  if (matches.isEmpty) throw FormatException('Invalid duration format: $input');

  int years = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0, microseconds = 0;

  for (final match in matches) {
    final valueStr = match.group(1)!.replaceAll(',', '.');
    final value = double.tryParse(valueStr);
    if (value == null) throw FormatException('Invalid number in duration: $valueStr');
    final unit = match.group(2)!.toLowerCase();
    if (unit.startsWith('ms')) {
      milliseconds += value.round();
    } else if (unit.startsWith('us')) {
      microseconds += value.round();
    } else if (unit.startsWith('y')) {
      years += value.round();
    } else if (unit.startsWith('d')) {
      days += value.round();
    } else if (unit.startsWith('h')) {
      hours += value.round();
    } else if (unit.startsWith('m')) {
      minutes += value.round();
    } else if (unit.startsWith('s')) {
      seconds += value.round();
    } else {
      throw FormatException('Unknown duration unit: $unit');
    }
  }

  // Dart Duration does not support years, so convert years to days (approximate, 365 days per year)
  days += years * 365;

  return Duration(
    days: days,
    hours: hours,
    minutes: minutes,
    seconds: seconds,
    milliseconds: milliseconds,
    microseconds: microseconds,
  );
}