/// ISO-8601 duration (`PT1H30M5S`) ↔ Dart `Duration`. Backend serialises /// `java.time.Duration` in this format; Dart has no builtin parser. class IsoDuration { IsoDuration._(); static final RegExp _pattern = RegExp( r'^P(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$', ); static Duration? fromJson(String? iso) { if (iso == null || iso.isEmpty) return null; final match = _pattern.firstMatch(iso); if (match == null) return null; final hours = int.parse(match.group(1) ?? '0'); final minutes = int.parse(match.group(2) ?? '0'); final secondsRaw = match.group(3) ?? '0'; final secondsValue = double.parse(secondsRaw); return Duration( hours: hours, minutes: minutes, milliseconds: (secondsValue * 1000).round(), ); } static String? toJson(Duration? d) { if (d == null) return null; final hours = d.inHours; final minutes = d.inMinutes.remainder(60); final seconds = d.inSeconds.remainder(60); final buf = StringBuffer('PT'); if (hours > 0) buf.write('${hours}H'); if (minutes > 0) buf.write('${minutes}M'); if (seconds > 0 || (hours == 0 && minutes == 0)) buf.write('${seconds}S'); return buf.toString(); } }