parse method

DateTime parse (String formattedString)

Constructs a new DateTime instance based on formattedString.

Throws a FormatException if the input cannot be parsed.

The function parses a subset of ISO 8601 which includes the subset accepted by RFC 3339.

The accepted inputs are currently:

This includes the output of both toString and toIso8601String, which will be parsed back into a DateTime object with the same time as the original.

The result is always in either local time or UTC. If a time zone offset other than UTC is specified, the time is converted to the equivalent UTC time.

Examples of accepted strings:

Implementation

// TODO(lrn): restrict incorrect values like  2003-02-29T50:70:80.
// Or not, that may be a breaking change.
static DateTime parse(String formattedString) {
  var re = _parseFormat;
  Match match = re.firstMatch(formattedString);
  if (match != null) {
    int parseIntOrZero(String matched) {
      if (matched == null) return 0;
      return int.parse(matched);
    }

    // Parses fractional second digits of '.(\d{1,6})' into the combined
    // microseconds.
    int parseMilliAndMicroseconds(String matched) {
      if (matched == null) return 0;
      int length = matched.length;
      assert(length >= 1);
      assert(length <= 6);

      int result = 0;
      for (int i = 0; i < 6; i++) {
        result *= 10;
        if (i < matched.length) {
          result += matched.codeUnitAt(i) ^ 0x30;
        }
      }
      return result;
    }

    int years = int.parse(match[1]);
    int month = int.parse(match[2]);
    int day = int.parse(match[3]);
    int hour = parseIntOrZero(match[4]);
    int minute = parseIntOrZero(match[5]);
    int second = parseIntOrZero(match[6]);
    bool addOneMillisecond = false;
    int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]);
    int millisecond =
        milliAndMicroseconds ~/ Duration.microsecondsPerMillisecond;
    int microsecond =
        milliAndMicroseconds.remainder(Duration.microsecondsPerMillisecond);
    bool isUtc = false;
    if (match[8] != null) {
      // timezone part
      isUtc = true;
      if (match[9] != null) {
        // timezone other than 'Z' and 'z'.
        int sign = (match[9] == '-') ? -1 : 1;
        int hourDifference = int.parse(match[10]);
        int minuteDifference = parseIntOrZero(match[11]);
        minuteDifference += 60 * hourDifference;
        minute -= sign * minuteDifference;
      }
    }
    int value = _brokenDownDateToValue(years, month, day, hour, minute,
        second, millisecond, microsecond, isUtc);
    if (value == null) {
      throw new FormatException("Time out of range", formattedString);
    }
    return new DateTime._withValue(value, isUtc: isUtc);
  } else {
    throw new FormatException("Invalid date format", formattedString);
  }
}