TemporalTime.fromString constructor

TemporalTime.fromString(
  1. String iso8601String
)

Constructs a new TemporalTime from a ISO8601 string adhering to the format: hh:mm hh:mmZ hh:mm:ss hh:mm:ssZ hh:mm:ss.sss hh:mm:ss.sssZ without Z: +hh:mm +hh:mm:ss

Implementation

factory TemporalTime.fromString(String iso8601String) {
  final regExp = RegExp(
    r'^([0-2][0-9]):([0-5][0-9])(:([0-5][0-9])(\.([0-9]{1,9}))?)?((z|Z)|((\+|-)[0-2][0-9]:[0-5][0-9](:[0-5][0-9])?))?',
    caseSensitive: false,
    multiLine: false,
  );

  // Validate
  var regexString = regExp.stringMatch(iso8601String);
  if (regexString == null || regexString != iso8601String) {
    throw const FormatException(
      'Invalid ISO8601 String Input\n\n'
      'Please provide an extended ISO 8601 time string in the format '
      'hh:mm:ss.sss with an optional time zone offset \u00b1hh:mm:ss. '
      '${Temporal.genericDocErrorMessage}',
    );
  }

  // Remove Z
  regexString = iso8601String.replaceAll(RegExp(r'(z|Z)'), '');

  // Extract Time
  final match = regExp.matchAsPrefix(regexString)!;

  final hours = int.parse(match.group(1)!);
  final minutes = int.parse(match.group(2)!);
  final seconds = Temporal.getIntOr0(match.group(4));

  final totalNanoseconds =
      Temporal.getIntOr0(match.group(6)?.padRight(9, '0'));
  final milliseconds = totalNanoseconds ~/ 1000000;
  final microseconds = (totalNanoseconds ~/ 1000) % 1000;
  final nanoseconds = totalNanoseconds % 1000;

  // Extract Offset
  Duration? offset;
  if (match.group(7) != null && match.group(7)!.isNotEmpty) {
    offset = Temporal.offsetToDuration(match.group(7)!);
  } else if (iso8601String.toLowerCase().contains('z')) {
    offset = Duration.zero;
  }

  return TemporalTime._(
    DateTime.utc(
      1970,
      1,
      1,
      hours,
      minutes,
      seconds,
      milliseconds,
      microseconds,
    ),
    nanoseconds: nanoseconds,
    offset: offset,
  );
}