DateIntervalFormat = function(
    pattern, opt_dateIntervalSymbols, opt_dateTimeSymbols) {
  asserts.assert(pattern !== undefined, 'Pattern must be defined.');

  /**
   * A reference to a native Intl DateTimeFormat object, only used when
   * USE_ECMASCRIPT_I18N_DATEINTERVALFORMAT is true.
   * @private {?goog.global.Intl.DateTimeFormat}
   */
  this.intlFormatter_ = null;
  // TimeZone information of non-integral hour offset.
  /** @private {number} */
  this.timeZoneMillisecOffset_ = 0;
  /** @private {string} */
  this.tzId_ = '';

  /**
   * Used in place of resolvedOptions timeStyle as workaround.
   * Records timeStyle setting.
   * TODO(user): replace this with resolvedOptions.timeStyle
   * @private {string|undefined}
   */
  this.timeStyle;

  // Note: the ECMAScript implementation cannot parse an arbitrary pattern.
  if ((typeof pattern === 'number') &&
      LocaleFeature.USE_ECMASCRIPT_I18N_DATEINTERVALFORMAT) {
    // Implement using ECMAScript Intl object.
    /**
     * @type {undefined|!DateTimeFormat.IntlOptions}
     * @private @const
     */
    const options = this.getIntlOptions_(pattern);
    this.intlFormatter_ = new Intl.DateTimeFormat(goog.LOCALE, options);
    this.timeStyle = options.timeStyle;
  } else {
    asserts.assert(
        opt_dateIntervalSymbols !== undefined ||
            dateIntervalSymbols.getDateIntervalSymbols() !== undefined,
        'goog.i18n.DateIntervalSymbols or explicit symbols must be defined');
    asserts.assert(
        opt_dateTimeSymbols !== undefined || DateTimeSymbols !== undefined,
        'goog.i18n.DateTimeSymbols or explicit symbols must be defined');
    /**
     * DateIntervalSymbols object that contains locale data required by the
     * formatter.
     * @private @const {!dateIntervalSymbols.DateIntervalSymbols}
     */
    this.dateIntervalSymbols_ =
        opt_dateIntervalSymbols || dateIntervalSymbols.getDateIntervalSymbols();

    /**
     * DateTimeSymbols object that contains locale data required by the
     * formatter's implementation with JavaScript, requiring data and code.
     * @private @const {!DateTimeSymbolsType}
     */
    this.dateTimeSymbols_ = opt_dateTimeSymbols || DateTimeSymbols;

    /**
     * Date interval pattern to use.
     * @private @const {!dateIntervalSymbols.DateIntervalPatternMap}
     */
    this.intervalPattern_ = this.getIntervalPattern_(pattern);

    /**
     * Keys of the available date interval patterns. Used to lookup the key that
     * contains a specific pattern letter (e.g. for ['Myd', 'hms'], the key that
     * contains 'y' is 'Myd').
     * @private @const {!Array<string>}
     */
    this.intervalPatternKeys_ = object.getKeys(this.intervalPattern_);

    // Remove the default pattern's key ('_') from intervalPatternKeys_. Is not
    // necesary when looking up for a key: when no key is found it will always
    // default to the default pattern.
    array.remove(this.intervalPatternKeys_, DEFAULT_PATTERN_KEY_);

    /**
     * Default fallback pattern to use.
     * @private @const {string}
     */
    this.fallbackPattern_ =
        this.dateIntervalSymbols_.FALLBACK || DEFAULT_FALLBACK_PATTERN_;

    // Determine which date should be used with each part of the interval
    // pattern.
    const indexOfFirstDate =
        this.fallbackPattern_.indexOf(FIRST_DATE_PLACEHOLDER_);
    const indexOfSecondDate =
        this.fallbackPattern_.indexOf(SECOND_DATE_PLACEHOLDER_);
    if (indexOfFirstDate < 0 || indexOfSecondDate < 0) {
      throw new Error('Malformed fallback interval pattern');
    }

    /**
     * True if the first date provided should be formatted with the first
     * pattern of the interval pattern.
     * @private @const {boolean}
     */
    this.useFirstDateOnFirstPattern_ = indexOfFirstDate <= indexOfSecondDate;

    /**
     * Map that stores a Formatter_ object per calendar field. Formatters will
     * be instanced on demand and stored on this map until required again.
     * @private @const {!Object<string, !Formatter_>}
     */
    this.formatterMap_ = {};
  }
}
Constructs a DateIntervalFormat object based on the current locale.

@param {number|!dateIntervalSymbols.DateIntervalPatternMap} pattern Pattern
    specification or pattern object.
@param {!dateIntervalSymbols.DateIntervalSymbols=} opt_dateIntervalSymbols
    Optional DateIntervalSymbols to use for this instance rather than the
    global symbols.
@param {!DateTimeSymbolsType=} opt_dateTimeSymbols Optional DateTimeSymbols
    to use for this instance rather than the global symbols.
@constructor
@struct
@final