parseDateTimeISOUTCFast function

DateTime? parseDateTimeISOUTCFast(
  1. String s
)

Parses the ISO-8601 UTC format of DateTime.toUtc().toIso8601String() (how DBSQLiteAdapter stores a DateTime), without a regular expression: YYYY-MM-DD(T| )HH:MM:SS[.f]Z, with 1 to 6 fraction digits.

Returns the same as DateTime.parse (a UTC DateTime) for that format, or null for anything else (to be parsed the usual way).

Implementation

DateTime? parseDateTimeISOUTCFast(String s) {
  final n = s.length;
  // `YYYY-MM-DDTHH:MM:SSZ` (20) to `YYYY-MM-DDTHH:MM:SS.ffffffZ` (27):
  if (n < 20 || n > 27 || s.codeUnitAt(n - 1) != 0x5A /* Z */ ) return null;

  if (s.codeUnitAt(4) != 0x2D /* - */ || s.codeUnitAt(7) != 0x2D) return null;
  final sep = s.codeUnitAt(10);
  if (sep != 0x54 /* T */ && sep != 0x20 /* space */ ) return null;
  if (s.codeUnitAt(13) != 0x3A /* : */ || s.codeUnitAt(16) != 0x3A) {
    return null;
  }

  final year = _parseDigits(s, 0, 4);
  final month = _parseDigits(s, 5, 2);
  final day = _parseDigits(s, 8, 2);
  final hour = _parseDigits(s, 11, 2);
  final minute = _parseDigits(s, 14, 2);
  final second = _parseDigits(s, 17, 2);
  if (year < 0 || month < 0 || day < 0 || hour < 0 || minute < 0) return null;
  if (second < 0) return null;

  var microsecond = 0;
  if (n > 20) {
    // `.` and 1 to 6 digits before the `Z`:
    if (s.codeUnitAt(19) != 0x2E /* . */ || n < 22) return null;
    final count = n - 21;
    var fraction = _parseDigits(s, 20, count);
    if (fraction < 0) return null;
    for (var i = count; i < 6; ++i) {
      fraction *= 10;
    }
    microsecond = fraction;
  }

  return DateTime.utc(year, month, day, hour, minute, second, 0, microsecond);
}