diff --git a/lib/src/parse/parse.dart b/lib/src/parse/parse.dart index 7e732ae..4b25c71 100644 --- a/lib/src/parse/parse.dart +++ b/lib/src/parse/parse.dart @@ -129,6 +129,68 @@ Duration parseTime(String input) { microseconds: microseconds); } +Duration parseTimeLoose(String input) { + final parts = input.split(':'); + if (parts.length != 3 && parts.length != 2) { + throw const FormatException('Invalid time format'); + } + + final isNegative = input.startsWith('-'); + if (isNegative) { + input = input.substring(1); + } + + late final int days; + late final int hours; + late final int minutes; + late final int seconds; + late final int milliseconds; + late final int microseconds; + + if (parts.length == 3) { + final p = parts[2].split('.'); + + if (p.length == 2) { + // If fractional seconds is passed, but less than 6 digits + // Pad out to the right so we can calculate the ms/us correctly + final p2 = int.parse(p[1].padRight(6, '0')).abs(); + + microseconds = p2 % 1000; + milliseconds = p2 ~/ 1000; + seconds = int.parse(p[0]).abs(); + } else if (p.length == 1) { + microseconds = 0; + milliseconds = 0; + seconds = int.parse(p[0]).abs(); + } else { + throw const FormatException('Invalid time format'); + } + } else { + microseconds = 0; + milliseconds = 0; + seconds = 0; + } + + minutes = int.parse(parts[1]).abs(); + + { + final p = int.parse(parts[0]).abs(); + + hours = p % 24; + days = p ~/ 24; + } + + final duration = Duration( + days: days, + hours: hours, + minutes: minutes, + seconds: seconds, + milliseconds: milliseconds, + microseconds: microseconds); + + return (isNegative) ? -duration : duration; +} + Duration? tryParseDuration(String input) { try { return parseDuration(input); @@ -145,6 +207,14 @@ Duration? tryParseTime(String input) { } } +Duration? tryParseTimeLoose(String input) { + try { + return parseTime(input); + } catch (_) { + return null; + } +} + Duration? tryParseDurationAny(String input) { try { return parseDuration(input); diff --git a/test/parse/time_test.dart b/test/parse/time_test.dart index 39d8be1..c261901 100644 --- a/test/parse/time_test.dart +++ b/test/parse/time_test.dart @@ -19,4 +19,23 @@ void main() { expect(parseTime('245:09:08.12').toString(), '245:09:08.120000'); }); }); + + group('parse time loose', () { + test('standard', () { + expect(parseTimeLoose('245:09:08.007006').toString(), '245:09:08.007006'); + }); + + test('negative', () { + expect( + parseTimeLoose('-245:09:08.007006').toString(), '-245:09:08.007006'); + }); + + test('without microseconds', () { + expect(parseTimeLoose('245:09:08').toString(), '245:09:08.000000'); + }); + + test('without seconds', () { + expect(parseTimeLoose('245:09').toString(), '245:09:00.000000'); + }); + }); }