parse static method
Parses the given textValue
into a duration.
The formmat is defined as P[n]Y[n]M[n]DT[n]H[n]M[n]S
Example: P3WT1H
means 3 weeks and 1 hour.
Compare https://en.wikipedia.org/wiki/ISO_8601#Durations
Implementation
static IsoDuration parse(String textValue) {
/// Note ISO_8601 allows floating numbers, compare https://en.wikipedia.org/wiki/ISO_8601#Durations,
/// but even the validator https://icalendar.org/validator.html does not accept floating numbers.
/// So this implementation expects integers, too
if (!(textValue.startsWith('P') || textValue.startsWith('-P'))) {
throw FormatException(
'duration content needs to start with P, $textValue is invalid');
}
final isNegativeDuration = textValue.startsWith('-');
if (isNegativeDuration) {
textValue = textValue.substring(1);
}
var years = 0, months = 0, weeks = 0, days = 0;
var startIndex = 1;
if (!textValue.startsWith('PT')) {
final timeIndex = textValue.indexOf('T');
final yearsResult = _parseSection(textValue, startIndex, 'Y');
startIndex = yearsResult.index;
years = yearsResult.result;
final monthsResult = _parseSection(textValue, startIndex, 'M',
maxIndex: timeIndex); // M can also stand for minutes after the T
startIndex = monthsResult.index;
months = monthsResult.result;
final weeksResult = _parseSection(textValue, startIndex, 'W');
startIndex = weeksResult.index;
weeks = weeksResult.result;
final daysResult = _parseSection(textValue, startIndex, 'D');
startIndex = daysResult.index;
days = daysResult.result;
}
var hours = 0, minutes = 0, seconds = 0;
if (startIndex < textValue.length && textValue[startIndex] == 'T') {
startIndex++;
final hoursResult = _parseSection(textValue, startIndex, 'H');
hours = hoursResult.result;
startIndex = hoursResult.index;
final minutesResult = _parseSection(textValue, startIndex, 'M');
minutes = minutesResult.result;
startIndex = minutesResult.index;
final secondsResult = _parseSection(textValue, startIndex, 'S');
seconds = secondsResult.result;
}
return IsoDuration(
years: years,
months: months,
weeks: weeks,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds,
isNegativeDuration: isNegativeDuration,
);
}