Skip to content

Commit

Permalink
feat: add helper to convert a duration to a IsoDuration #11
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-virkus committed Feb 25, 2024
1 parent b4409d6 commit 6e38913
Showing 1 changed file with 47 additions and 10 deletions.
57 changes: 47 additions & 10 deletions lib/src/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1315,13 +1315,15 @@ class Period {
if (!endText.startsWith('P')) {
return null;
}

return IsoDuration.parse(endText);
}

static Period parse(String textValue) {
final startDate = _parseStartDate(textValue);
final duration = _parseDuration(textValue);
final endDate = _parseEndDate(textValue);

return Period(startDate, duration: duration, endDate: endDate);
}
}
Expand Down Expand Up @@ -1354,8 +1356,11 @@ class IsoDuration {
final bool isNegativeDuration;

static _DurationSection _parseSection(
String content, int startIndex, String designatur,
{int maxIndex = -1}) {
String content,
int startIndex,
String designatur, {
int maxIndex = -1,
}) {
final index = content.indexOf(designatur, startIndex);
if (index == -1 || (maxIndex != -1 && index > maxIndex)) {
return _DurationSection(0, startIndex);
Expand All @@ -1368,6 +1373,7 @@ class IsoDuration {
if (parsed == null) {
throw FormatException('Invalid duration: $content (for part [$text])');
}

return _DurationSection(parsed, index + 1);
}

Expand Down Expand Up @@ -1437,10 +1443,11 @@ class IsoDuration {
/// The `days` are converted by assuming 365 days per year and 30 days per month: `days: years * 365 + months * 30 + weeks * 7 + days`
/// Compare [addTo] for a better handling of this duration.
Duration toDuration() => Duration(
days: years * 365 + months * 30 + weeks * 7 + days,
hours: hours,
minutes: minutes,
seconds: seconds);
days: years * 365 + months * 30 + weeks * 7 + days,
hours: hours,
minutes: minutes,
seconds: seconds,
);

/// Adds this duration to the given [input] DateTime.
///
Expand All @@ -1455,10 +1462,12 @@ class IsoDuration {
final intermediate = DateTime(y, m, input.day, input.hour, input.minute,
input.second, input.millisecond, input.microsecond);
final duration = Duration(
days: weeks * 7 + days,
hours: hours,
minutes: minutes,
seconds: seconds);
days: weeks * 7 + days,
hours: hours,
minutes: minutes,
seconds: seconds,
);

return intermediate.add(duration);
}

Expand Down Expand Up @@ -1523,6 +1532,34 @@ class IsoDuration {
}
}

/// Allows to handle durations
extension DurationExtension on Duration {
/// Converts this duration to an ISO 8601 compliant duration.
IsoDuration toIso() {
final isNegativeDuration = isNegative;

// Convert the absolute value of each duration component
final years = inDays ~/ 365;
final months = (inDays % 365) ~/ 30;
final weeks = ((inDays % 365) % 30) ~/ 7;
final days = ((inDays % 365) % 30) % 7;
final hours = inHours % 24;
final minutes = inMinutes % 60;
final seconds = inSeconds % 60;

return IsoDuration(
years: years,
months: months,
weeks: weeks,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
isNegativeDuration: isNegativeDuration,
);
}
}

/// To specify the free or busy time type.
///
/// Compare [ParameterType.freeBusyTimeType], [FreeBusyType]
Expand Down

0 comments on commit 6e38913

Please sign in to comment.