Skip to content

Instantly share code, notes, and snippets.

@xsahil03x
Created June 1, 2020 14:57
Show Gist options
  • Save xsahil03x/be1c66d521f7e1f1195a6149c33ba538 to your computer and use it in GitHub Desktop.
Save xsahil03x/be1c66d521f7e1f1195a6149c33ba538 to your computer and use it in GitHub Desktop.
String extension to parse ISO8601 duration String to duration object.
extension StringX on String {
/// Creates a `Duration` object from an ISO8601 formatted string.
///
/// This method parses out a subset of the ISO8601 duration format. As years
/// and months are not of a set length this method does not support that. We
/// are then left with support for weeks, days, hours, minutes and seconds.
Duration get toDuration {
if (!RegExp(
r"^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$")
.hasMatch(this)) {
throw ArgumentError("String does not follow correct format");
}
final weeks = _parseTime(this, "W");
final days = _parseTime(this, "D");
final hours = _parseTime(this, "H");
final minutes = _parseTime(this, "M");
final seconds = _parseTime(this, "S");
return Duration(
days: days + (weeks * 7),
hours: hours,
minutes: minutes,
seconds: seconds,
);
}
/// Private helper method for extracting a time value from the ISO8601 string.
int _parseTime(String duration, String timeUnit) {
final timeMatch = RegExp(r"\d+" + timeUnit).firstMatch(duration);
if (timeMatch == null) {
return 0;
}
final timeString = timeMatch.group(0);
return int.parse(timeString.substring(0, timeString.length - 1));
}
}
@xsahil03x
Copy link
Author

print('P1Y4M3W2DT10H31M'.toDuration); // 562:04:00.000000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment