// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of intl;

// TODO(efortuna): Customized pattern system -- suggested by i18n needs
// feedback on appropriateness.
/**
 * DateFormat is for formatting and parsing dates in a locale-sensitive
 * manner.
 *
 * It allows the user to choose from a set of standard date time formats as well
 * as specify a customized pattern under certain locales. Date elements that
 * vary across locales include month name, week name, field order, etc.
 * We also allow the user to use any customized pattern to parse or format
 * date-time strings under certain locales. Date elements that vary across
 * locales include month name, weekname, field, order, etc.
 *
 * Formatting dates in the default "en_US" format does not require any
 * initialization. e.g.
 *       print(new DateFormat.yMMMd().format(new Date.now()));
 *
 * But for other locales, the formatting data for the locale must be
 * obtained. This can currently be done
 * in one of three ways, determined by which library you import. In all cases,
 * the "initializeDateFormatting" method must be called and will return a future
 * that is complete once the locale data is available. The result of the future
 * isn't important, but the data for that locale is available to the date
 * formatting and parsing once it completes.
 *
 * The easiest option is that the data may be available locally, imported in a
 * library that contains data for all the locales.
 *       import 'package:intl/date_symbol_data_local.dart';
 *       initializeDateFormatting("fr_FR", null).then((_) => runMyCode());
 *
 * If we are running outside of a browser, we may want to read the data
 * from files in the file system.
 *       import 'package:intl/date_symbol_data_file.dart';
 *       initializeDateFormatting("de_DE", null).then((_) => runMyCode());
 *
 * If we are running in a browser, we may want to read the data from the
 * server using the XmlHttpRequest mechanism.
 *       import 'package:intl/date_symbol_data_http_request.dart';
 *       initializeDateFormatting("pt_BR", null).then((_) => runMyCode());
 *
 * The code in example/basic/basic_example.dart shows a full example of
 * using this mechanism.
 *
 * Once we have the locale data, we need to specify the particular format.
 * This library uses the ICU/JDK date/time pattern specification both for
 * complete format specifications and also the abbreviated "skeleton" form
 * which can also adapt to different locales and is preferred where available.
 *
 * Skeletons: These can be specified either as the ICU constant name or as the
 * skeleton to which it resolves. The supported set of skeletons is as follows.
 * For each skeleton there is a named constructor that can be used to create it.
 * It's also possible to pass the skeleton as a string, but the constructor
 * is preferred.
 * 
 *      ICU Name                   Skeleton
 *      --------                   --------
 *      DAY                          d
 *      ABBR_WEEKDAY                 E
 *      WEEKDAY                      EEEE
 *      ABBR_STANDALONE_MONTH        LLL
 *      STANDALONE_MONTH             LLLL
 *      NUM_MONTH                    M
 *      NUM_MONTH_DAY                Md
 *      NUM_MONTH_WEEKDAY_DAY        MEd
 *      ABBR_MONTH                   MMM
 *      ABBR_MONTH_DAY               MMMd
 *      ABBR_MONTH_WEEKDAY_DAY       MMMEd
 *      MONTH                        MMMM
 *      MONTH_DAY                    MMMMd
 *      MONTH_WEEKDAY_DAY            MMMMEEEEd
 *      ABBR_QUARTER                 QQQ
 *      QUARTER                      QQQQ
 *      YEAR                         y
 *      YEAR_NUM_MONTH               yM
 *      YEAR_NUM_MONTH_DAY           yMd
 *      YEAR_NUM_MONTH_WEEKDAY_DAY   yMEd
 *      YEAR_ABBR_MONTH              yMMM
 *      YEAR_ABBR_MONTH_DAY          yMMMd
 *      YEAR_ABBR_MONTH_WEEKDAY_DAY  yMMMEd
 *      YEAR_MONTH                   yMMMM
 *      YEAR_MONTH_DAY               yMMMMd
 *      YEAR_MONTH_WEEKDAY_DAY       yMMMMEEEEd
 *      YEAR_ABBR_QUARTER            yQQQ
 *      YEAR_QUARTER                 yQQQQ
 *      HOUR24                       H
 *      HOUR24_MINUTE                Hm
 *      HOUR24_MINUTE_SECOND         Hms
 *      HOUR                         j
 *      HOUR_MINUTE                  jm
 *      HOUR_MINUTE_SECOND           jms
 *      HOUR_MINUTE_GENERIC_TZ       jmv
 *      HOUR_MINUTE_TZ               jmz
 *      HOUR_GENERIC_TZ              jv
 *      HOUR_TZ                      jz
 *      MINUTE                       m
 *      MINUTE_SECOND                ms
 *      SECOND                       s
 *
 * Examples Using the US Locale:
 *
 *      Pattern                           Result
 *      ----------------                  -------
 *      new DateFormat.yMd()             -> 7/10/1996
 *      new DateFormat("yMd")            -> 7/10/1996
 *      new DateFormat.yMMMMd("en_US")   -> July 10, 1996
 *      new DateFormat.jm()              -> 5:08 PM
 *      new DateFormat.yMd().add_jm()    -> 7/10/1996 5:08 PM
 *      new DateFormat.Hm()              -> 17:08 // force 24 hour time
 *
 * Explicit Pattern Syntax: Formats can also be specified with a pattern string.
 * This can be used for formats that don't have a skeleton available, but these
 * will not adapt to different locales. For example, in an explicit pattern the 
 * letters "H" and "h" are available for 24 hour and 12 hour time formats 
 * respectively. But there isn't a way in an explicit pattern to get the
 * behaviour of the "j" skeleton, which prints 24 hour or 12 hour time according
 * to the conventions of the locale, and also includes am/pm markers where 
 * appropriate. So it is preferable to use the skeletons.
 *
 * The following characters are available in explicit patterns:
 *
 *     Symbol   Meaning                Presentation        Example
 *     ------   -------                ------------        -------
 *     G        era designator         (Text)              AD
 *     y        year                   (Number)            1996
 *     M        month in year          (Text & Number)     July & 07
 *     L        standalone month       (Text & Number)     July & 07
 *     d        day in month           (Number)            10
 *     c        standalone day         (Number)            10
 *     h        hour in am/pm (1~12)   (Number)            12
 *     H        hour in day (0~23)     (Number)            0
 *     m        minute in hour         (Number)            30
 *     s        second in minute       (Number)            55
 *     S        fractional second      (Number)            978
 *     E        day of week            (Text)              Tuesday
 *     D        day in year            (Number)            189
 *     a        am/pm marker           (Text)              PM
 *     k        hour in day (1~24)     (Number)            24
 *     K        hour in am/pm (0~11)   (Number)            0
 *     z        time zone              (Text)              Pacific Standard Time
 *     Z        time zone (RFC 822)    (Number)            -0800
 *     v        time zone (generic)    (Text)              Pacific Time
 *     Q        quarter                (Text)              Q3
 *     '        escape for text        (Delimiter)         'Date='
 *     ''       single quote           (Literal)           'o''clock'
 *
 * The count of pattern letters determine the format.
 *
 * **Text**:
 * * 5 pattern letters--use narrow form for standalone. Otherwise does not apply
 * * 4 or more pattern letters--use full form,
 * * 3 pattern letters--use short or abbreviated form if one exists
 * * less than 3--use numeric form if one exists
 *
 * **Number**: the minimum number of digits. Shorter numbers are zero-padded to
 * this amount (e.g. if "m" produces "6", "mm" produces "06"). Year is handled
 * specially; that is, if the count of 'y' is 2, the Year will be truncated to
 * 2 digits. (e.g., if "yyyy" produces "1997", "yy" produces "97".) Unlike other
 * fields, fractional seconds are padded on the right with zero.
 *
 * **(Text & Number)**: 3 or over, use text, otherwise use number.
 *
 * Any characters not in the pattern will be treated as quoted text. For
 * instance, characters like ':', '.', ' ', '#' and '@' will appear in the
 * resulting text even though they are not enclosed in single quotes. In our
 * current pattern usage, not all letters have meanings. But those unused
 * letters are strongly discouraged to be used as quoted text without quotes,
 * because we may use other letters as pattern characters in the future.
 *
 * Examples Using the US Locale:
 *
 *     Format Pattern                     Result
 *     --------------                     -------
 *     "yyyy.MM.dd G 'at' HH:mm:ss vvvv"  1996.07.10 AD at 15:08:56 Pacific Time
 *     "EEE, MMM d, ''yy"                 Wed, July 10, '96
 *     "h:mm a"                           12:08 PM
 *     "hh 'o''clock' a, zzzz"            12 o'clock PM, Pacific Daylight Time
 *     "K:mm a, vvv"                      0:00 PM, PT
 *     "yyyyy.MMMMM.dd GGG hh:mm aaa"     01996.July.10 AD 12:08 PM
 *
 * When parsing a date string using the abbreviated year pattern ("yy"),
 * DateFormat must interpret the abbreviated year relative to some
 * century. It does this by adjusting dates to be within 80 years before and 20
 * years after the time the parse function is called. For example, using a
 * pattern of "MM/dd/yy" and a DateParse instance created on Jan 1, 1997,
 * the string "01/11/12" would be interpreted as Jan 11, 2012 while the string
 * "05/04/64" would be interpreted as May 4, 1964. During parsing, only
 * strings consisting of exactly two digits, as defined by {@link
 * java.lang.Character#isDigit(char)}, will be parsed into the default
 * century. Any other numeric string, such as a one digit string, a three or
 * more digit string will be interpreted as its face value.
 *
 * If the year pattern does not have exactly two 'y' characters, the year is
 * interpreted literally, regardless of the number of digits. So using the
 * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
 */

class DateFormat {

  /**
   * Creates a new DateFormat, using the format specified by [newPattern]. For
   * forms that match one of our predefined skeletons, we look up the
   * corresponding pattern in [locale] (or in the default locale if none is
   * specified) and use the resulting full format string. This is the
   * preferred usage, but if [newPattern] does not match one of the skeletons,
   * then it is used as a format directly, but will not be adapted to suit
   * the locale.
   *
   * For example, in an en_US locale, specifying the skeleton
   *     new DateFormat.yMEd();
   * or the explicit
   *     new DateFormat('EEE, M/d/y');
   * would produce the same result, a date of the form
   *     Wed, 6/27/2012
   * The first version would produce a different format string if used in
   * another locale, but the second format would always be the same.
   *
   * If [locale] does not exist in our set of supported locales then an
   * [ArgumentError] is thrown.
   */
  DateFormat([String newPattern, String locale]) {
    // TODO(alanknight): It should be possible to specify multiple skeletons eg
    // date, time, timezone all separately. Adding many or named parameters to
    // the constructor seems awkward, especially with the possibility of
    // confusion with the locale. A "fluent" interface with cascading on an
    // instance might work better? A list of patterns is also possible.
    _locale = Intl.verifiedLocale(locale, localeExists);
    addPattern(newPattern);
  }

  /**
   * Return a string representing [date] formatted according to our locale
   * and internal format.
   */
  String format(DateTime date) {
    // TODO(efortuna): read optional TimeZone argument (or similar)?
    var result = new StringBuffer();
    _formatFields.forEach((field) => result.write(field.format(date)));
    return result.toString();
  }

  /**
   * NOT YET IMPLEMENTED.
   *
   * Returns a date string indicating how long ago (3 hours, 2 minutes)
   * something has happened or how long in the future something will happen
   * given a [reference] DateTime relative to the current time.
   */
  String formatDuration(DateTime reference) => '';

  /**
   * NOT YET IMPLEMENTED.
   *
   * Formats a string indicating how long ago (negative [duration]) or how far
   * in the future (positive [duration]) some time is with respect to a
   * reference [date].
   */
  String formatDurationFrom(Duration duration, DateTime date) => '';

  /**
   * Given user input, attempt to parse the [inputString] into the anticipated
   * format, treating it as being in the local timezone. If [inputString] does
   * not match our format, throws a [FormatException]. This will accept dates
   * whose values are not strictly valid, or strings with additional characters
   * (including whitespace) after a valid date. For stricter parsing, use
   * [parseStrict].
   */
  DateTime parse(String inputString, [utc = false]) =>
      _parse(inputString, utc: utc, strict: false);

  /**
   * Given user input, attempt to parse the [inputString] "loosely" into the
   * anticipated format, accepting some variations from the strict format.
   *
   * If [inputString]
   * is accepted by [parseStrict], just return the result. If not, attempt to
   * parse it, but accepting either upper or
   * lower case, allowing delimiters to be missing and replaced or
   * supplemented with whitespace,
   * and allowing arbitrary amounts of whitespace wherever whitespace is
   * permitted. Note that this does not allow trailing characters, the way
   * [parse] does. It also does not allow leading whitespace on delimiters,
   * and does not allow alternative names for months or weekdays other than
   * those the format knows about. The restrictions are quite arbitrary and
   * it's not known how well they'll work for locales that aren't English-like.
   *
   * If [inputString] does not parse, this throws a
   * [FormatException].
   *
   * For example, this will accept
   *
   *       new DateFormat.yMMMd("en_US").parseLoose("SEp   3 2014");
   *       new DateFormat.yMd("en_US").parseLoose("09    03/2014");
   *
   * It will NOT accept
   *
   *      // "Sept" is not a valid month name.
   *      new DateFormat.yMMMd("en_US").parseLoose("Sept 3, 2014");
   *      // Delimiters can't have leading whitespace.
   *      new DateFormat.yMd("en_US").parseLoose("09 / 03 / 2014");
   */
  DateTime parseLoose(String inputString, [utc = false]) {
    try {
      return _parse(inputString, utc: utc, strict: true);
    } on FormatException {
      return _parseLoose(inputString.toLowerCase(), utc);
    }
  }

  _parseLoose(String inputString, bool utc) {
    var dateFields = new _DateBuilder();
    if (utc) dateFields.utc = true;
    var stream = new _Stream(inputString);
    _formatFields.forEach((f) => f.parseLoose(stream, dateFields));
    if (!stream.atEnd()) {
      throw new FormatException(
          "Characters remaining after date parsing in $inputString");
    }
    dateFields.verify(inputString);
    return dateFields.asDate();
  }

  /**
   * Given user input, attempt to parse the [inputString] into the anticipated
   * format, treating it as being in the local timezone. If [inputString] does
   * not match our format, throws a [FormatException]. This will reject dates
   * whose values are not strictly valid, even if the
   * DateTime constructor will accept them. It will also rejct strings with
   * additional characters (including whitespace) after a valid date. For
   * looser parsing, use [parse].
   */
  DateTime parseStrict(String inputString, [utc = false]) =>
      _parse(inputString, utc: utc, strict: true);

  DateTime _parse(String inputString, {utc: false, strict: false}) {
    // TODO(alanknight): The Closure code refers to special parsing of numeric
    // values with no delimiters, which we currently don't do. Should we?
    var dateFields = new _DateBuilder();
    if (utc) dateFields.utc = true;
    var stream = new _Stream(inputString);
    _formatFields.forEach((f) => f.parse(stream, dateFields));
    if (strict && !stream.atEnd()) {
      throw new FormatException(
          "Characters remaining after date parsing in $inputString");
    }
    if (strict) dateFields.verify(inputString);
    return dateFields.asDate();
  }

  /**
   * Given user input, attempt to parse the [inputString] into the anticipated
   * format, treating it as being in UTC.
   *
   * The canonical Dart style name
   * is [parseUtc], but [parseUTC] is retained
   * for backward-compatibility.
   */
  DateTime parseUTC(String inputString) => parse(inputString, true);

  /**
   * Given user input, attempt to parse the [inputString] into the anticipated
   * format, treating it as being in UTC.
   *
   * The canonical Dart style name
   * is [parseUtc], but [parseUTC] is retained
   * for backward-compatibility.
   */
  DateTime parseUtc(String inputString) => parse(inputString, true);

  /**
   * Return the locale code in which we operate, e.g. 'en_US' or 'pt'.
   */
  String get locale => _locale;

  /**
   * Returns a list of all locales for which we have date formatting
   * information.
   */
  static List<String> allLocalesWithSymbols() => dateTimeSymbols.keys.toList();

  /**
   * The named constructors for this class are all conveniences for creating
   * instances using one of the known "skeleton" formats, and having code
   * completion support for discovering those formats.
   * So,
   *     new DateFormat.yMd("en_US")
   * is equivalent to
   *     new DateFormat("yMd", "en_US")
   * To create a compound format you can use these constructors in combination
   * with the add_ methods below. e.g.
   *     new DateFormat.yMd().add_Hms();
   * If the optional [locale] is omitted, the format will be created using the
   * default locale in [Intl.systemLocale].
   */
  DateFormat.d([locale]) : this("d", locale);
  DateFormat.E([locale]) : this("E", locale);
  DateFormat.EEEE([locale]) : this("EEEE", locale);
  DateFormat.LLL([locale]) : this("LLL", locale);
  DateFormat.LLLL([locale]) : this("LLLL", locale);
  DateFormat.M([locale]) : this("M", locale);
  DateFormat.Md([locale]) : this("Md", locale);
  DateFormat.MEd([locale]) : this("MEd", locale);
  DateFormat.MMM([locale]) : this("MMM", locale);
  DateFormat.MMMd([locale]) : this("MMMd", locale);
  DateFormat.MMMEd([locale]) : this("MMMEd", locale);
  DateFormat.MMMM([locale]) : this("MMMM", locale);
  DateFormat.MMMMd([locale]) : this("MMMMd", locale);
  DateFormat.MMMMEEEEd([locale]) : this("MMMMEEEEd", locale);
  DateFormat.QQQ([locale]) : this("QQQ", locale);
  DateFormat.QQQQ([locale]) : this("QQQQ", locale);
  DateFormat.y([locale]) : this("y", locale);
  DateFormat.yM([locale]) : this("yM", locale);
  DateFormat.yMd([locale]) : this("yMd", locale);
  DateFormat.yMEd([locale]) : this("yMEd", locale);
  DateFormat.yMMM([locale]) : this("yMMM", locale);
  DateFormat.yMMMd([locale]) : this("yMMMd", locale);
  DateFormat.yMMMEd([locale]) : this("yMMMEd", locale);
  DateFormat.yMMMM([locale]) : this("yMMMM", locale);
  DateFormat.yMMMMd([locale]) : this("yMMMMd", locale);
  DateFormat.yMMMMEEEEd([locale]) : this("yMMMMEEEEd", locale);
  DateFormat.yQQQ([locale]) : this("yQQQ", locale);
  DateFormat.yQQQQ([locale]) : this("yQQQQ", locale);
  DateFormat.H([locale]) : this("H", locale);
  DateFormat.Hm([locale]) : this("Hm", locale);
  DateFormat.Hms([locale]) : this("Hms", locale);
  DateFormat.j([locale]) : this("j", locale);
  DateFormat.jm([locale]) : this("jm", locale);
  DateFormat.jms([locale]) : this("jms", locale);
  DateFormat.jmv([locale]) : this("jmv", locale);
  DateFormat.jmz([locale]) : this("jmz", locale);
  DateFormat.jv([locale]) : this("jv", locale);
  DateFormat.jz([locale]) : this("jz", locale);
  DateFormat.m([locale]) : this("m", locale);
  DateFormat.ms([locale]) : this("ms", locale);
  DateFormat.s([locale]) : this("s", locale);

  /**
   * The "add_*" methods append a particular skeleton to the format, or set
   * it as the only format if none was previously set. These are primarily
   * useful for creating compound formats. For example
   *       new DateFormat.yMd().add_Hms();
   * would create a date format that prints both the date and the time.
   */
  DateFormat add_d() => addPattern("d");
  DateFormat add_E() => addPattern("E");
  DateFormat add_EEEE() => addPattern("EEEE");
  DateFormat add_LLL() => addPattern("LLL");
  DateFormat add_LLLL() => addPattern("LLLL");
  DateFormat add_M() => addPattern("M");
  DateFormat add_Md() => addPattern("Md");
  DateFormat add_MEd() => addPattern("MEd");
  DateFormat add_MMM() => addPattern("MMM");
  DateFormat add_MMMd() => addPattern("MMMd");
  DateFormat add_MMMEd() => addPattern("MMMEd");
  DateFormat add_MMMM() => addPattern("MMMM");
  DateFormat add_MMMMd() => addPattern("MMMMd");
  DateFormat add_MMMMEEEEd() => addPattern("MMMMEEEEd");
  DateFormat add_QQQ() => addPattern("QQQ");
  DateFormat add_QQQQ() => addPattern("QQQQ");
  DateFormat add_y() => addPattern("y");
  DateFormat add_yM() => addPattern("yM");
  DateFormat add_yMd() => addPattern("yMd");
  DateFormat add_yMEd() => addPattern("yMEd");
  DateFormat add_yMMM() => addPattern("yMMM");
  DateFormat add_yMMMd() => addPattern("yMMMd");
  DateFormat add_yMMMEd() => addPattern("yMMMEd");
  DateFormat add_yMMMM() => addPattern("yMMMM");
  DateFormat add_yMMMMd() => addPattern("yMMMMd");
  DateFormat add_yMMMMEEEEd() => addPattern("yMMMMEEEEd");
  DateFormat add_yQQQ() => addPattern("yQQQ");
  DateFormat add_yQQQQ() => addPattern("yQQQQ");
  DateFormat add_H() => addPattern("H");
  DateFormat add_Hm() => addPattern("Hm");
  DateFormat add_Hms() => addPattern("Hms");
  DateFormat add_j() => addPattern("j");
  DateFormat add_jm() => addPattern("jm");
  DateFormat add_jms() => addPattern("jms");
  DateFormat add_jmv() => addPattern("jmv");
  DateFormat add_jmz() => addPattern("jmz");
  DateFormat add_jv() => addPattern("jv");
  DateFormat add_jz() => addPattern("jz");
  DateFormat add_m() => addPattern("m");
  DateFormat add_ms() => addPattern("ms");
  DateFormat add_s() => addPattern("s");

  /**
   * For each of the skeleton formats we also allow the use of the corresponding
   * ICU constant names.
   */
  static const String ABBR_MONTH = 'MMM';
  static const String DAY = 'd';
  static const String ABBR_WEEKDAY = 'E';
  static const String WEEKDAY = 'EEEE';
  static const String ABBR_STANDALONE_MONTH = 'LLL';
  static const String STANDALONE_MONTH = 'LLLL';
  static const String NUM_MONTH = 'M';
  static const String NUM_MONTH_DAY = 'Md';
  static const String NUM_MONTH_WEEKDAY_DAY = 'MEd';
  static const String ABBR_MONTH_DAY = 'MMMd';
  static const String ABBR_MONTH_WEEKDAY_DAY = 'MMMEd';
  static const String MONTH = 'MMMM';
  static const String MONTH_DAY = 'MMMMd';
  static const String MONTH_WEEKDAY_DAY = 'MMMMEEEEd';
  static const String ABBR_QUARTER = 'QQQ';
  static const String QUARTER = 'QQQQ';
  static const String YEAR = 'y';
  static const String YEAR_NUM_MONTH = 'yM';
  static const String YEAR_NUM_MONTH_DAY = 'yMd';
  static const String YEAR_NUM_MONTH_WEEKDAY_DAY = 'yMEd';
  static const String YEAR_ABBR_MONTH = 'yMMM';
  static const String YEAR_ABBR_MONTH_DAY = 'yMMMd';
  static const String YEAR_ABBR_MONTH_WEEKDAY_DAY = 'yMMMEd';
  static const String YEAR_MONTH = 'yMMMM';
  static const String YEAR_MONTH_DAY = 'yMMMMd';
  static const String YEAR_MONTH_WEEKDAY_DAY = 'yMMMMEEEEd';
  static const String YEAR_ABBR_QUARTER = 'yQQQ';
  static const String YEAR_QUARTER = 'yQQQQ';
  static const String HOUR24 = 'H';
  static const String HOUR24_MINUTE = 'Hm';
  static const String HOUR24_MINUTE_SECOND = 'Hms';
  static const String HOUR = 'j';
  static const String HOUR_MINUTE = 'jm';
  static const String HOUR_MINUTE_SECOND = 'jms';
  static const String HOUR_MINUTE_GENERIC_TZ = 'jmv';
  static const String HOUR_MINUTE_TZ = 'jmz';
  static const String HOUR_GENERIC_TZ = 'jv';
  static const String HOUR_TZ = 'jz';
  static const String MINUTE = 'm';
  static const String MINUTE_SECOND = 'ms';
  static const String SECOND = 's';

  /** The locale in which we operate, e.g. 'en_US', or 'pt'. */
  String _locale;

  /**
   * The full template string. This may have been specified directly, or
   * it may have been derived from a skeleton and the locale information
   * on how to interpret that skeleton.
   */
  String _pattern;

  /**
   * We parse the format string into individual [_DateFormatField] objects
   * that are used to do the actual formatting and parsing. Do not use
   * this variable directly, use the getter [_formatFields].
   */
  List<_DateFormatField> _formatFieldsPrivate;

  /**
   * Getter for [_formatFieldsPrivate] that lazily initializes it.
   */
  get _formatFields {
    if (_formatFieldsPrivate == null) {
      if (_pattern == null) _useDefaultPattern();
      _formatFieldsPrivate = parsePattern(_pattern);
    }
    return _formatFieldsPrivate;
  }

  /**
   * We are being asked to do formatting without having set any pattern.
   * Use a default.
   */
  _useDefaultPattern() {
    add_yMMMMd();
    add_jms();
  }

  /**
   * A series of regular expressions used to parse a format string into its
   * component fields.
   */
  static List<RegExp> _matchers = [
    // Quoted String - anything between single quotes, with escaping
    //   of single quotes by doubling them.
    // e.g. in the pattern "hh 'o''clock'" will match 'o''clock'
    new RegExp("^\'(?:[^\']|\'\')*\'"),
    // Fields - any sequence of 1 or more of the same field characters.
    // e.g. in "hh:mm:ss" will match hh, mm, and ss. But in "hms" would
    // match each letter individually.
    new RegExp(
        "^(?:G+|y+|M+|k+|S+|E+|a+|h+|K+|H+|c+|L+|Q+|d+|D+|m+|s+|v+|z+|Z+)"),
    // Everything else - A sequence that is not quotes or field characters.
    // e.g. in "hh:mm:ss" will match the colons.
    new RegExp("^[^\'GyMkSEahKHcLQdDmsvzZ]+")
  ];

  /**
   * Set our pattern, appending it to any existing patterns. Also adds a single
   * space to separate the two.
   */
  _appendPattern(String inputPattern, [String separator = ' ']) {
    _pattern =
        _pattern == null ? inputPattern : "$_pattern$separator$inputPattern";
  }

  /**
   * Add [inputPattern] to this instance as a pattern. If there was a previous
   * pattern, then this appends to it, separating the two by [separator].
   * [inputPattern] is first looked up in our list of known skeletons.
   * If it's found there, then use the corresponding pattern for this locale.
   * If it's not, then treat [inputPattern] as an explicit pattern.
   */
  DateFormat addPattern(String inputPattern, [String separator = ' ']) {
    // TODO(alanknight): This is an expensive operation. Caching recently used
    // formats, or possibly introducing an entire "locale" object that would
    // cache patterns for that locale could be a good optimization.
    // If we have already parsed the format fields, reset them.
    _formatFieldsPrivate = null;
    if (inputPattern == null) return this;
    if (!_availableSkeletons.containsKey(inputPattern)) {
      _appendPattern(inputPattern, separator);
    } else {
      _appendPattern(_availableSkeletons[inputPattern], separator);
    }
    return this;
  }

  /** Return the pattern that we use to format dates.*/
  get pattern => _pattern;

  /** Return the skeletons for our current locale. */
  Map get _availableSkeletons => dateTimePatterns[locale];

  /**
   * Return the [DateSymbol] information for the locale. This can be useful
   * to find lists like the names of weekdays or months in a locale, but
   * the structure of this data may change, and it's generally better to go
   * through the [format] and [parse] APIs. If the locale isn't present, or
   * is uninitialized, returns null;
   */
  DateSymbols get dateSymbols => dateTimeSymbols[_locale];

  /**
   * Set the locale. If the locale can't be found, we also look up
   * based on alternative versions, e.g. if we have no 'en_CA' we will
   * look for 'en' as a fallback. It will also translate en-ca into en_CA.
   * Null is also considered a valid value for [newLocale], indicating
   * to use the default.
   */
  _setLocale(String newLocale) {
    _locale = Intl.verifiedLocale(newLocale, localeExists);
  }

  /**
   * Return true if the locale exists, or if it is null. The null case
   * is interpreted to mean that we use the default locale.
   */
  static bool localeExists(localeName) {
    if (localeName == null) return false;
    return dateTimeSymbols.containsKey(localeName);
  }

  static List get _fieldConstructors => [
    (pattern, parent) => new _DateFormatQuotedField(pattern, parent),
    (pattern, parent) => new _DateFormatPatternField(pattern, parent),
    (pattern, parent) => new _DateFormatLiteralField(pattern, parent)
  ];

  /** Parse the template pattern and return a list of field objects.*/
  List parsePattern(String pattern) {
    if (pattern == null) return null;
    return _parsePatternHelper(pattern).reversed.toList();
  }

  /** Recursive helper for parsing the template pattern. */
  List _parsePatternHelper(String pattern) {
    if (pattern.isEmpty) return [];

    var matched = _match(pattern);
    if (matched == null) return [];

    var parsed =
        _parsePatternHelper(pattern.substring(matched.fullPattern().length));
    parsed.add(matched);
    return parsed;
  }

  /** Find elements in a string that are patterns for specific fields.*/
  _DateFormatField _match(String pattern) {
    for (var i = 0; i < _matchers.length; i++) {
      var regex = _matchers[i];
      var match = regex.firstMatch(pattern);
      if (match != null) {
        return _fieldConstructors[i](match.group(0), this);
      }
    }
  }
}
