/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.gwt.i18n.client;

import com.google.gwt.i18n.client.constants.DateTimeConstants;
import com.google.gwt.i18n.client.impl.DateRecord;
import com.google.gwt.i18n.client.impl.cldr.DateTimeFormatInfoImpl_en;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Formats and parses dates and times using locale-sensitive patterns.
 * 
 * <h3>Patterns</h3>
 * 
 * <table>
 * <tr>
 * <th>Symbol</th>
 * <th>Meaning</th>
 * <th>Presentation</th>
 * <th>Example</th>
 * </tr>
 * 
 * <tr>
 * <td><code>G</code></td>
 * <td>era designator</td>
 * <td>Text</td>
 * <td><code>AD</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>y</code></td>
 * <td>year</td>
 * <td>Number</td>
 * <td><code>1996</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>L</code></td>
 * <td>standalone month in year</td>
 * <td>Text or Number</td>
 * <td><code>July (or) 07</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>M</code></td>
 * <td>month in year</td>
 * <td>Text or Number</td>
 * <td><code>July (or) 07</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>d</code></td>
 * <td>day in month</td>
 * <td>Number</td>
 * <td><code>10</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>h</code></td>
 * <td>hour in am/pm (1-12)</td>
 * <td>Number</td>
 * <td><code>12</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>H</code></td>
 * <td>hour in day (0-23)</td>
 * <td>Number</td>
 * <td><code>0</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>m</code></td>
 * <td>minute in hour</td>
 * <td>Number</td>
 * <td><code>30</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>s</code></td>
 * <td>second in minute</td>
 * <td>Number</td>
 * <td><code>55</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>S</code></td>
 * <td>fractional second</td>
 * <td>Number</td>
 * <td><code>978</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>E</code></td>
 * <td>day of week</td>
 * <td>Text</td>
 * <td><code>Tuesday</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>c</code></td>
 * <td>standalone day of week</td>
 * <td>Text</td>
 * <td><code>Tuesday</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>a</code></td>
 * <td>am/pm marker</td>
 * <td>Text</td>
 * <td><code>PM</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>k</code></td>
 * <td>hour in day (1-24)</td>
 * <td>Number</td>
 * <td><code>24</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>K</code></td>
 * <td>hour in am/pm (0-11)</td>
 * <td>Number</td>
 * <td><code>0</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>z</code></td>
 * <td>time zone</td>
 * <td>Text</td>
 * <td><code>Pacific Standard Time(see comment)</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>Z</code></td>
 * <td>time zone (RFC 822)</td>
 * <td>Text</td>
 * <td><code>-0800(See comment)</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>v</code></td>
 * <td>time zone id</td>
 * <td>Text</td>
 * <td><code>America/Los_Angeles(See comment)</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>'</code></td>
 * <td>escape for text</td>
 * <td>Delimiter</td>
 * <td><code>'Date='</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>''</code></td>
 * <td>single quote</td>
 * <td>Literal</td>
 * <td><code>'o''clock'</code></td>
 * </tr>
 * </table>
 * 
 * <p>
 * The number of pattern letters influences the format, as follows:
 * </p>
 * 
 * <dl>
 * <dt>Text</dt>
 * <dd>if 4 or more, then use the full form; if less than 4, use short or
 * abbreviated form if it exists (e.g., <code>"EEEE"</code> produces
 * <code>"Monday"</code>, <code>"EEE"</code> produces <code>"Mon"</code>)</dd>
 * 
 * <dt>Number</dt>
 * <dd>the minimum number of digits. Shorter numbers are zero-padded to this
 * amount (e.g. if <code>"m"</code> produces <code>"6"</code>, <code>"mm"</code>
 * produces <code>"06"</code>). Year is handled specially; that is, if the count
 * of 'y' is 2, the Year will be truncated to 2 digits. (e.g., if
 * <code>"yyyy"</code> produces <code>"1997"</code>, <code>"yy"</code> produces
 * <code>"97"</code>.) Unlike other fields, fractional seconds are padded on the
 * right with zero.</dd>
 * 
 * <dt>Text or Number</dt>
 * <dd>3 or more, use text, otherwise use number. (e.g. <code>"M"</code>
 * produces <code>"1"</code>, <code>"MM"</code> produces <code>"01"</code>,
 * <code>"MMM"</code> produces <code>"Jan"</code>, and <code>"MMMM"</code>
 * produces <code>"January"</code>.  Some pattern letters also treat a count
 * of 5 specially, meaning a single-letter abbreviation: <code>L</code>,
 * <code>M</code>, <code>E</code>, and <code>c</code>.</dd>
 * </dl>
 * 
 * <p>
 * Any characters in the pattern that are not in the ranges of ['<code>a</code>
 * '..'<code>z</code>'] and ['<code>A</code>'..'<code>Z</code>'] will be treated
 * as quoted text. For instance, characters like '<code>:</code>', '
 * <code>.</code>', '<code> </code>' (space), '<code>#</code>' and '
 * <code>@</code>' will appear in the resulting time text even they are not
 * embraced within single quotes.
 * </p>
 * 
 * <p>
 * [Time Zone Handling] Web browsers don't provide all the information we need
 * for proper time zone formating -- so GWT has a copy of the required data, for
 * your convenience. For simpler cases, one can also use a fallback
 * implementation that only keeps track of the current timezone offset. These
 * two approaches are called, respectively, Common TimeZones and Simple
 * TimeZones, although both are implemented with the same TimeZone class.
 * 
 * "TimeZone createTimeZone(String timezoneData)" returns a Common TimeZone
 * object, and "TimeZone createTimeZone(int timeZoneOffsetInMinutes)" returns a
 * Simple TimeZone object. The one provided by OS fall into to Simple TimeZone
 * category. For formatting purpose, following table shows the behavior of GWT
 * DateTimeFormat.
 * </p>
 * <table>
 * <tr>
 * <th>Pattern</th>
 * <th>Common TimeZone</th>
 * <th>Simple TimeZone</th>
 * </tr>
 * <tr>
 * <td>z, zz, zzz</td>
 * <td>PDT</td>
 * <td>UTC-7</td>
 * </tr>
 * <tr>
 * <td>zzzz</td>
 * <td>Pacific Daylight Time</td>
 * <td>UTC-7</td>
 * </tr>
 * <tr>
 * <td>Z, ZZ</td>
 * <td>-0700</td>
 * <td>-0700</td>
 * </tr>
 * <tr>
 * <td>ZZZ</td>
 * <td>-07:00</td>
 * <td>-07:00</td>
 * </tr>
 * <tr>
 * <td>ZZZZ</td>
 * <td>GMT-07:00</td>
 * <td>GMT-07:00</td>
 * </tr>
 * <tr>
 * <td>v, vv, vvv, vvvv</td>
 * <td>America/Los_Angeles</td>
 * <td>Etc/GMT+7</td>
 * </tr>
 * </table>
 * 
 * <h3>Parsing Dates and Times</h3>
 * <p>
 * The pattern does not need to specify every field.  If the year, month, or
 * day is missing from the pattern, the corresponding value will be taken from
 * the current date.  If the month is specified but the day is not, the day will
 * be constrained to the last day within the specified month.  If the hour,
 * minute, or second is missing, the value defaults to zero.
 * </p>
 * 
 * <p>
 * As with formatting (described above), the count of pattern letters determines
 * the parsing behavior.
 * </p>
 * 
 * <dl>
 * <dt>Text</dt>
 * <dd>4 or more pattern letters--use full form, less than 4--use short or
 * abbreviated form if one exists. In parsing, we will always try long format,
 * then short.</dd>
 * 
 * <dt>Number</dt>
 * <dd>the minimum number of digits.</dd>
 * 
 * <dt>Text or Number</dt>
 * <dd>3 or more characters means use text, otherwise use number</dd>
 * </dl>
 * 
 * <p>
 * Although the current pattern specification doesn't not specify behavior for
 * all letters, it may in the future. It is strongly discouraged to use
 * unspecified letters as literal text without quoting them.
 * </p>
 * <p>
 * [Note on TimeZone] The time zone support for parsing is limited. Only
 * standard GMT and RFC format are supported. Time zone specification using time
 * zone id (like America/Los_Angeles), time zone names (like PST, Pacific
 * Standard Time) are not supported. Normally, it is too much a burden for a
 * client application to load all the time zone symbols. And in almost all those
 * cases, it is a better choice to do such parsing on server side through
 * certain RPC mechanism. This decision is based on particular use cases we have
 * studied; in principle, it could be changed in future versions.
 * </p>
 * 
 * <h3>Examples</h3>
 * <table>
 * <tr>
 * <th>Pattern</th>
 * <th>Formatted Text</th>
 * </tr>
 * 
 * <tr>
 * <td><code>"yyyy.MM.dd G 'at' HH:mm:ss vvvv"</code></td>
 * <td><code>1996.07.10 AD at 15:08:56 America/Los_Angeles</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>"EEE, MMM d, ''yy"</code></td>
 * <td><code>Wed, July 10, '96</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>"h:mm a"</code></td>
 * <td><code>12:08 PM</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>"hh 'o''clock' a, zzzz"</code></td>
 * <td><code> 12 o'clock PM, Pacific Daylight Time</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>"K:mm a, vvvv"</code></td>
 * <td><code> 0:00 PM, America/Los_Angeles</code></td>
 * </tr>
 * 
 * <tr>
 * <td><code>"yyyyy.MMMMM.dd GGG hh:mm aaa"</code></td>
 * <td><code>01996.July.10 AD 12:08 PM</code></td>
 * </tr>
 * </table>
 * 
 * <h3>Additional Parsing Considerations</h3>
 * <p>
 * When parsing a date string using the abbreviated year pattern (
 * <code>"yy"</code>), the parser 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 parser instance is created. For example,
 * using a pattern of <code>"MM/dd/yy"</code> and a <code>DateTimeFormat</code>
 * object created on Jan 1, 1997, the string <code>"01/11/12"</code> would be
 * interpreted as Jan 11, 2012 while the string <code>"05/04/64"</code> 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. If the year pattern does not have
 * exactly two 'y' characters, the year is interpreted literally, regardless of
 * the number of digits. For example, using the pattern
 * <code>"MM/dd/yyyy"</code>, "01/11/12" parses to Jan 11, 12 A.D.
 * </p>
 * 
 * <p>
 * When numeric fields abut one another directly, with no intervening delimiter
 * characters, they constitute a run of abutting numeric fields. Such runs are
 * parsed specially. For example, the format "HHmmss" parses the input text
 * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to
 * parse "1234". In other words, the leftmost field of the run is flexible,
 * while the others keep a fixed width. If the parse fails anywhere in the run,
 * then the leftmost field is shortened by one character, and the entire run is
 * parsed again. This is repeated until either the parse succeeds or the
 * leftmost field is one character in length. If the parse still fails at that
 * point, the parse of the run fails.
 * </p>
 * 
 * <p>
 * In the current implementation, timezone parsing only supports
 * <code>GMT:hhmm</code>, <code>GMT:+hhmm</code>, and <code>GMT:-hhmm</code>.
 * </p>
 * 
 * <h3>Example</h3> {@example com.google.gwt.examples.DateTimeFormatExample}
 * 
 */
@SuppressWarnings("deprecation")
public class DateTimeFormat {

  /**
   * Predefined date/time formats -- see {@link CustomDateTimeFormat} if you
   * need some format that isn't supplied here.
   */
  public enum PredefinedFormat {
    // TODO(jat): Javadoc to explain these formats

    /**
     * ISO 8601 date format, fixed across all locales.
     * <p>Example: {@code 2008-10-03T10:29:40.046-04:00}
     * <p>http://code.google.com/p/google-web-toolkit/issues/detail?id=3068
     * <p>http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/date_and_time_format.htm
     */
    ISO_8601,

    /**
     * RFC 2822 date format, fixed across all locales.
     * <p>Example: {@code Thu, 20 May 2010 17:54:50 -0700}
     * <p>http://tools.ietf.org/html/rfc2822#section-3.3
     */
    RFC_2822,

    DATE_FULL,
    DATE_LONG,
    DATE_MEDIUM,
    DATE_SHORT,

    TIME_FULL,
    TIME_LONG,
    TIME_MEDIUM,
    TIME_SHORT,

    DATE_TIME_FULL,
    DATE_TIME_LONG,
    DATE_TIME_MEDIUM,
    DATE_TIME_SHORT,

    DAY,
    HOUR_MINUTE,
    HOUR_MINUTE_SECOND,
    HOUR24_MINUTE,
    HOUR24_MINUTE_SECOND,
    MINUTE_SECOND,
    MONTH,
    MONTH_ABBR,
    MONTH_ABBR_DAY,
    MONTH_DAY,
    MONTH_NUM_DAY,
    MONTH_WEEKDAY_DAY,
    YEAR,
    YEAR_MONTH,
    YEAR_MONTH_ABBR,
    YEAR_MONTH_ABBR_DAY,
    YEAR_MONTH_DAY,
    YEAR_MONTH_NUM,
    YEAR_MONTH_NUM_DAY,
    YEAR_MONTH_WEEKDAY_DAY,
    YEAR_QUARTER,
    YEAR_QUARTER_ABBR,
  }

  /**
   * Class PatternPart holds a "compiled" pattern part.
   */
  private static class PatternPart {
    public String text;
    public int count; // 0 has a special meaning, it stands for literal
    public boolean abutStart;

    public PatternPart(String txt, int cnt) {
      text = txt;
      count = cnt;
      abutStart = false;
    }
  }

  private static final int NUMBER_BASE = 10;
  private static final int JS_START_YEAR = 1900;

  private static final Map<String, DateTimeFormat> cache;

  private static final int NUM_MILLISECONDS_IN_DAY = 24 * 60 * 60000;

  private static final String PATTERN_CHARS = "GyMLdkHmsSEcDahKzZv";

  // Note: M & L must be the first two characters
  private static final String NUMERIC_FORMAT_CHARS = "MLydhHmsSDkK";

  private static final String WHITE_SPACE = " \t\r\n";

  private static final String GMT = "GMT";
  private static final String UTC = "UTC";

  private static final int MINUTES_PER_HOUR = 60;

  private static final String RFC2822_PATTERN = "EEE, d MMM yyyy HH:mm:ss Z";
  private static final String ISO8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZ";

  static {
    cache = new HashMap<String, DateTimeFormat>();
  }

  /**
   * Get a DateTimeFormat instance for a predefined format.
   * 
   * <p>See {@link CustomDateTimeFormat} if you need a localized format that is
   * not supported here.
   * 
   * @param predef {@link PredefinedFormat} describing desired format
   * @return a DateTimeFormat instance for the specified format
   */
  public static DateTimeFormat getFormat(PredefinedFormat predef) {
    if (usesFixedEnglishStrings(predef)) {
      String pattern;
      switch (predef) {
        case RFC_2822:
          pattern = RFC2822_PATTERN;
          break;
        case ISO_8601:
          pattern = ISO8601_PATTERN;
          break;
        default:
          throw new IllegalStateException("Unexpected predef type " + predef);
      }
      return getFormat(pattern, new DateTimeFormatInfoImpl_en());
    }
    DateTimeFormatInfo dtfi = getDefaultDateTimeFormatInfo();
    String pattern;
    switch (predef) {
      case DATE_FULL:
        pattern = dtfi.dateFormatFull();
        break;
      case DATE_LONG:
        pattern = dtfi.dateFormatLong();
        break;
      case DATE_MEDIUM:
        pattern = dtfi.dateFormatMedium();
        break;
      case DATE_SHORT:
        pattern = dtfi.dateFormatShort();
        break;
      case DATE_TIME_FULL:
        pattern = dtfi.dateTimeFull(dtfi.timeFormatFull(),
            dtfi.dateFormatFull());
        break;
      case DATE_TIME_LONG:
        pattern = dtfi.dateTimeLong(dtfi.timeFormatLong(),
            dtfi.dateFormatLong());
        break;
      case DATE_TIME_MEDIUM:
        pattern = dtfi.dateTimeMedium(dtfi.timeFormatMedium(),
            dtfi.dateFormatMedium());
        break;
      case DATE_TIME_SHORT:
        pattern = dtfi.dateTimeShort(dtfi.timeFormatShort(),
            dtfi.dateFormatShort());
        break;
      case DAY:
        pattern = dtfi.formatDay();
        break;
      case HOUR24_MINUTE:
        pattern = dtfi.formatHour24Minute();
        break;
      case HOUR24_MINUTE_SECOND:
        pattern = dtfi.formatHour24MinuteSecond();
        break;
      case HOUR_MINUTE:
        pattern = dtfi.formatHour12Minute();
        break;
      case HOUR_MINUTE_SECOND:
        pattern = dtfi.formatHour12MinuteSecond();
        break;
      case MINUTE_SECOND:
        pattern = dtfi.formatMinuteSecond();
        break;
      case MONTH:
        pattern = dtfi.formatMonthFull();
        break;
      case MONTH_ABBR:
        pattern = dtfi.formatMonthAbbrev();
        break;
      case MONTH_ABBR_DAY:
        pattern = dtfi.formatMonthAbbrevDay();
        break;
      case MONTH_DAY:
        pattern = dtfi.formatMonthFullDay();
        break;
      case MONTH_NUM_DAY:
        pattern = dtfi.formatMonthNumDay();
        break;
      case MONTH_WEEKDAY_DAY:
        pattern = dtfi.formatMonthFullWeekdayDay();
        break;
      case TIME_FULL:
        pattern = dtfi.timeFormatFull();
        break;
      case TIME_LONG:
        pattern = dtfi.timeFormatLong();
        break;
      case TIME_MEDIUM:
        pattern = dtfi.timeFormatMedium();
        break;
      case TIME_SHORT:
        pattern = dtfi.timeFormatShort();
        break;
      case YEAR:
        pattern = dtfi.formatYear();
        break;
      case YEAR_MONTH:
        pattern = dtfi.formatYearMonthFull();
        break;
      case YEAR_MONTH_ABBR:
        pattern = dtfi.formatYearMonthAbbrev();
        break;
      case YEAR_MONTH_ABBR_DAY:
        pattern = dtfi.formatYearMonthAbbrevDay();
        break;
      case YEAR_MONTH_DAY:
        pattern = dtfi.formatYearMonthFullDay();
        break;
      case YEAR_MONTH_NUM:
        pattern = dtfi.formatYearMonthNum();
        break;
      case YEAR_MONTH_NUM_DAY:
        pattern = dtfi.formatYearMonthNumDay();
        break;
      case YEAR_MONTH_WEEKDAY_DAY:
        pattern = dtfi.formatYearMonthWeekdayDay();
        break;
      case YEAR_QUARTER:
        pattern = dtfi.formatYearQuarterFull();
        break;
      case YEAR_QUARTER_ABBR:
        pattern = dtfi.formatYearQuarterShort();
        break;
      default:
        throw new IllegalArgumentException("Unexpected predefined format "
            + predef);
    }
    return getFormat(pattern, dtfi);
  }

  /**
   * Returns a DateTimeFormat object using the specified pattern. If you need to
   * format or parse repeatedly using the same pattern, it is highly recommended
   * that you cache the returned <code>DateTimeFormat</code> object and reuse it
   * rather than calling this method repeatedly.
   * 
   * <p>Note that the pattern supplied is used as-is -- for example, if you
   * supply "MM/dd/yyyy" as the pattern, that is the order you will get the
   * fields, even in locales where the order is different.  It is recommended to
   * use {@link #getFormat(PredefinedFormat)} instead -- if you use this method,
   * you are taking responsibility for localizing the patterns yourself.
   * 
   * @param pattern string to specify how the date should be formatted
   * 
   * @return a <code>DateTimeFormat</code> object that can be used for format or
   *         parse date/time values matching the specified pattern
   * 
   * @throws IllegalArgumentException if the specified pattern could not be
   *           parsed
   */
  public static DateTimeFormat getFormat(String pattern) {
    return getFormat(pattern, getDefaultDateTimeFormatInfo());
  }

  /**
   * Retrieve the DateTimeFormat object for full date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_FULL} instead
   */
  @Deprecated
  public static DateTimeFormat getFullDateFormat() {
    return getFormat(PredefinedFormat.DATE_FULL);
  }

  /**
   * Retrieve the DateTimeFormat object for full date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_TIME_FULL} instead
   */
  @Deprecated
  public static DateTimeFormat getFullDateTimeFormat() {
    return getFormat(PredefinedFormat.DATE_TIME_FULL);
  }

  /**
   * Retrieve the DateTimeFormat object for full time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#TIME_FULL} instead
   */
  @Deprecated
  public static DateTimeFormat getFullTimeFormat() {
    return getFormat(PredefinedFormat.TIME_FULL);
  }

  /**
   * Retrieve the DateTimeFormat object for long date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_LONG} instead
   */
  @Deprecated
  public static DateTimeFormat getLongDateFormat() {
    return getFormat(PredefinedFormat.DATE_LONG);
  }

  /**
   * Retrieve the DateTimeFormat object for long date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_TIME_LONG} instead
   */
  @Deprecated
  public static DateTimeFormat getLongDateTimeFormat() {
    return getFormat(PredefinedFormat.DATE_TIME_LONG);
  }

  /**
   * Retrieve the DateTimeFormat object for long time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#TIME_LONG} instead
   */
  @Deprecated
  public static DateTimeFormat getLongTimeFormat() {
    return getFormat(PredefinedFormat.TIME_LONG);
  }

  /**
   * Retrieve the DateTimeFormat object for medium date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_MEDIUM} instead
   */
  @Deprecated
  public static DateTimeFormat getMediumDateFormat() {
    return getFormat(PredefinedFormat.DATE_MEDIUM);
  }

  /**
   * Retrieve the DateTimeFormat object for medium date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_TIME_MEDIUM} instead
   */
  @Deprecated
  public static DateTimeFormat getMediumDateTimeFormat() {
    return getFormat(PredefinedFormat.DATE_TIME_MEDIUM);
  }

  /**
   * Retrieve the DateTimeFormat object for medium time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#TIME_MEDIUM} instead
   */
  @Deprecated
  public static DateTimeFormat getMediumTimeFormat() {
    return getFormat(PredefinedFormat.TIME_MEDIUM);
  }

  /**
   * Retrieve the DateTimeFormat object for short date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_SHORT} instead
   */
  @Deprecated
  public static DateTimeFormat getShortDateFormat() {
    return getFormat(PredefinedFormat.DATE_SHORT);
  }

  /**
   * Retrieve the DateTimeFormat object for short date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#DATE_TIME_SHORT} instead
   */
  @Deprecated
  public static DateTimeFormat getShortDateTimeFormat() {
    return getFormat(PredefinedFormat.DATE_TIME_SHORT);
  }

  /**
   * Retrieve the DateTimeFormat object for short time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   * @deprecated use {@link #getFormat(PredefinedFormat)} with
   *     {@link PredefinedFormat#TIME_SHORT} instead
   */
  @Deprecated
  public static DateTimeFormat getShortTimeFormat() {
    return getFormat(PredefinedFormat.TIME_SHORT);
  }

  /**
   * Internal factory method that provides caching.
   * 
   * @param pattern
   * @param dtfi
   * @return DateTimeFormat instance
   */
  protected static DateTimeFormat getFormat(String pattern,
      DateTimeFormatInfo dtfi) {
    DateTimeFormatInfo defaultDtfi = getDefaultDateTimeFormatInfo();
    DateTimeFormat dtf = null;
    if (dtfi == defaultDtfi) {
      dtf = cache.get(pattern);
    }
    if (dtf == null) {
      dtf = new DateTimeFormat(pattern, dtfi);
      if (dtfi == defaultDtfi) {
        cache.put(pattern, dtf);
      }
    }
    return dtf;
  }

  private static DateTimeFormatInfo getDefaultDateTimeFormatInfo() {
    return LocaleInfo.getCurrentLocale().getDateTimeFormatInfo();
  }

  /**
   * Returns true if the predefined format is one that specifies always using
   * English names/separators.
   * <p>This should be a method on PredefinedFormat, but that would defeat the
   * enum optimizations GWT is currently capable of.
   * @param predef
   * @return true if the specified format requires English names/separators
   */
  private static boolean usesFixedEnglishStrings(PredefinedFormat predef) {
    switch (predef) {
      case RFC_2822:
        return true;
      case ISO_8601:
        return true;
      default:
        return false;
    }
  }

  private final ArrayList<PatternPart> patternParts = new ArrayList<PatternPart>();

  private final DateTimeFormatInfo dateTimeFormatInfo;

  private final String pattern;

  /**
   * Constructs a format object using the specified pattern and the date time
   * constants for the default locale.
   * 
   * @param pattern string pattern specification
   */
  protected DateTimeFormat(String pattern) {
    this(pattern, getDefaultDateTimeFormatInfo());
  }

  /**
   * Constructs a format object using the specified pattern and user-supplied
   * date time constants.
   * 
   * @param pattern string pattern specification
   * @param dateTimeConstants locale specific symbol collection
   * @deprecated use {@link #DateTimeFormat(String, DateTimeFormatInfo)}
   */
  @Deprecated
  protected DateTimeFormat(String pattern, DateTimeConstants dateTimeConstants) {
    this(pattern, new DateTimeFormatInfoAdapter(dateTimeConstants));
  }

  /**
   * Constructs a format object using the specified pattern and user-supplied
   * date time constants.
   * 
   * @param pattern string pattern specification
   * @param dtfi DateTimeFormatInfo instance to use
   */
  protected DateTimeFormat(String pattern, DateTimeFormatInfo dtfi) {
    this.pattern = pattern;
    this.dateTimeFormatInfo = dtfi;

    /*
     * Even though the pattern is only compiled for use in parsing and parsing
     * is far less common than formatting, the pattern is still parsed eagerly
     * here to fail fast in case the pattern itself is malformed.
     */
    parsePattern(pattern);
  }

  /**
   * Format a date object.
   * 
   * @param date the date object being formatted
   * 
   * @return string representation for this date in desired format
   */
  public String format(Date date) {
    TimeZone timeZone = TimeZone.createTimeZone(date.getTimezoneOffset());
    return format(date, timeZone);
  }

  /**
   * Format a date object using specified time zone.
   * 
   * @param date the date object being formatted
   * @param timeZone a TimeZone object that holds time zone information
   * 
   * @return string representation for this date in the format defined by this
   *         object
   */
  public String format(Date date, TimeZone timeZone) {
    // We use the Date class to calculate each date/time field in order
    // to maximize performance and minimize code size.
    // JavaScript only provides an API for rendering local time (in the os time
    // zone). Here we want to render time in any timezone. So suppose we try to
    // render the date (20:00 GMT0000, or 16:00 GMT-0400, or 12:00 GMT-0800) for
    // time zone GMT-0400, and OS has time zone GMT-0800. By adding the
    // difference between OS time zone (GMT-0800) and target time zone
    // (GMT-0400) to "date", we end up with 16:00 GMT-0800. This date object
    // has the same date/time fields (year, month, date, hour, minutes, etc)
    // in GMT-0800 as original date in our target time zone (GMT-0400). We
    // just need to take care of time zone display, but that's needed anyway.

    // Things get a little bit more tricky when a daylight time transition
    // happens. For example, if the OS timezone is America/Los_Angeles,
    // it is just impossible to have a Date represent 2006/4/2 02:30, because
    // 2:00 to 3:00 on that day does not exist in US Pacific time zone because
    // of the daylight time switch.

    // But we can use 2 separate date objects, one to represent 2006/4/2, one
    // to represent 02:30. Of course, for the 2nd date object its date can be
    // any other day in that year, except 2006/4/2. So we end up have 3 Date
    // objects: one for resolving "Year, month, day", one for time within that
    // day, and the original date object, which is needed for figuring out
    // actual time zone offset.

    int diff = (date.getTimezoneOffset() - timeZone.getOffset(date)) * 60000;
    Date keepDate = new Date(date.getTime() + diff);
    Date keepTime = keepDate;
    if (keepDate.getTimezoneOffset() != date.getTimezoneOffset()) {
      if (diff > 0) {
        diff -= NUM_MILLISECONDS_IN_DAY;
      } else {
        diff += NUM_MILLISECONDS_IN_DAY;
      }
      keepTime = new Date(date.getTime() + diff);
    }

    StringBuffer toAppendTo = new StringBuffer(64);
    int j, n = pattern.length();
    for (int i = 0; i < n;) {
      char ch = pattern.charAt(i);
      if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
        // ch is a date-time pattern character to be interpreted by subFormat().
        // Count the number of times it is repeated.
        for (j = i + 1; j < n && pattern.charAt(j) == ch; ++j) {
        }
        subFormat(toAppendTo, ch, j - i, date, keepDate, keepTime, timeZone);
        i = j;
      } else if (ch == '\'') {
        // Handle an entire quoted string, included embedded
        // doubled apostrophes (as in 'o''clock').

        // i points after '.
        ++i;

        // If start with '', just add ' and continue.
        if (i < n && pattern.charAt(i) == '\'') {
          toAppendTo.append('\'');
          ++i;
          continue;
        }

        // Otherwise add the quoted string.
        boolean trailQuote = false;
        while (!trailQuote) {
          // j points to next ' or EOS.
          j = i;
          while (j < n && pattern.charAt(j) != '\'') {
            ++j;
          }

          if (j >= n) {
            // Trailing ' (pathological).
            throw new IllegalArgumentException("Missing trailing \'");
          }

          // Look ahead to detect '' within quotes.
          if (j + 1 < n && pattern.charAt(j + 1) == '\'') {
            ++j;
          } else {
            trailQuote = true;
          }
          toAppendTo.append(pattern.substring(i, j));
          i = j + 1;
        }
      } else {
        // Append unquoted literal characters.
        toAppendTo.append(ch);
        ++i;
      }
    }

    return toAppendTo.toString();
  }

  /**
   * Retrieve the pattern used in this DateTimeFormat object.
   * 
   * @return pattern string
   */
  public String getPattern() {
    return pattern;
  }

  /**
   * Parses text to produce a {@link Date} value. An
   * {@link IllegalArgumentException} is thrown if either the text is empty or
   * if the parse does not consume all characters of the text.
   * 
   * Dates are parsed leniently, so invalid dates will be wrapped around as
   * needed. For example, February 30 will wrap to March 2.
   * 
   * @param text the string being parsed
   * @return a parsed date/time value
   * @throws IllegalArgumentException if the entire text could not be converted
   *           into a number
   */
  public Date parse(String text) throws IllegalArgumentException {
    return parse(text, false);
  }

  /**
   * This method modifies a {@link Date} object to reflect the date that is
   * parsed from an input string.
   * 
   * Dates are parsed leniently, so invalid dates will be wrapped around as
   * needed. For example, February 30 will wrap to March 2.
   * 
   * @param text the string that need to be parsed
   * @param start the character position in "text" where parsing should start
   * @param date the date object that will hold parsed value
   * 
   * @return 0 if parsing failed, otherwise the number of characters advanced
   */
  public int parse(String text, int start, Date date) {
    return parse(text, start, date, false);
  }

  /**
   * Parses text to produce a {@link Date} value. An
   * {@link IllegalArgumentException} is thrown if either the text is empty or
   * if the parse does not consume all characters of the text.
   * 
   * Dates are parsed strictly, so invalid dates will result in an
   * {@link IllegalArgumentException}.
   * 
   * @param text the string being parsed
   * @return a parsed date/time value
   * @throws IllegalArgumentException if the entire text could not be converted
   *           into a number
   */
  public Date parseStrict(String text) throws IllegalArgumentException {
    return parse(text, true);
  }

  /**
   * This method modifies a {@link Date} object to reflect the date that is
   * parsed from an input string.
   * 
   * Dates are parsed strictly, so invalid dates will return 0. For example,
   * February 30 will return 0 because February only has 28 days.
   * 
   * @param text the string that need to be parsed
   * @param start the character position in "text" where parsing should start
   * @param date the date object that will hold parsed value
   * 
   * @return 0 if parsing failed, otherwise the number of characters advanced
   */
  public int parseStrict(String text, int start, Date date) {
    return parse(text, start, date, true);
  }

  /**
   * Method append current content in buf as pattern part if there is any, and
   * clear buf for next part.
   * 
   * @param buf pattern part text specification
   * @param count pattern part repeat count
   */
  private void addPart(StringBuffer buf, int count) {
    if (buf.length() > 0) {
      patternParts.add((new PatternPart(buf.toString(), count)));
      buf.setLength(0);
    }
  }

  /**
   * Formats (0..11) Hours field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void format0To11Hours(StringBuffer buf, int count, Date date) {
    int value = date.getHours() % 12;
    zeroPaddingNumber(buf, value, count);
  }

  /**
   * Formats (0..23) Hours field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void format0To23Hours(StringBuffer buf, int count, Date date) {
    int value = date.getHours();
    zeroPaddingNumber(buf, value, count);
  }

  /**
   * Formats (1..12) Hours field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void format1To12Hours(StringBuffer buf, int count, Date date) {
    int value = date.getHours() % 12;
    if (value == 0) {
      zeroPaddingNumber(buf, 12, count);
    } else {
      zeroPaddingNumber(buf, value, count);
    }
  }

  /**
   * Formats (1..24) Hours field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void format24Hours(StringBuffer buf, int count, Date date) {
    int value = date.getHours();
    if (value == 0) {
      zeroPaddingNumber(buf, 24, count);
    } else {
      zeroPaddingNumber(buf, value, count);
    }
  }

  /**
   * Formats AM/PM field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param date hold the date object to be formatted
   */
  private void formatAmPm(StringBuffer buf, Date date) {
    if (date.getHours() >= 12 && date.getHours() < 24) {
      buf.append(dateTimeFormatInfo.ampms()[1]);
    } else {
      buf.append(dateTimeFormatInfo.ampms()[0]);
    }
  }

  /**
   * Formats Date field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatDate(StringBuffer buf, int count, Date date) {
    int value = date.getDate();
    zeroPaddingNumber(buf, value, count);
  }

  /**
   * Formats Day of week field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatDayOfWeek(StringBuffer buf, int count, Date date) {
    int value = date.getDay();
    if (count == 5) {
      buf.append(dateTimeFormatInfo.weekdaysNarrow()[value]);
    } else if (count == 4) {
      buf.append(dateTimeFormatInfo.weekdaysFull()[value]);
    } else {
      buf.append(dateTimeFormatInfo.weekdaysShort()[value]);
    }
  }

  /**
   * Formats Era field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatEra(StringBuffer buf, int count, Date date) {
    int value = date.getYear() >= -JS_START_YEAR ? 1 : 0;
    if (count >= 4) {
      buf.append(dateTimeFormatInfo.erasFull()[value]);
    } else {
      buf.append(dateTimeFormatInfo.erasShort()[value]);
    }
  }

  /**
   * Formats Fractional seconds field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatFractionalSeconds(StringBuffer buf, int count, Date date) {
    /*
     * Fractional seconds should be left-justified, ie. zero must be padded from
     * left. For example, if the value in milliseconds is 5, and the count is 3,
     * the output will be "005".
     * 
     * Values with less than three digits are rounded to the desired number of
     * places, but the rounded values are truncated at 9 or 99 in order to avoid
     * changing the values of seconds.
     */
    long time = date.getTime();
    int value;
    if (time < 0) {
      value = 1000 - (int) (-time % 1000);
      if (value == 1000) {
        value = 0;
      }
    } else {
      value = (int) (time % 1000);
    }
    if (count == 1) {
      value = Math.min((value + 50) / 100, 9); // Round to 100ms, clamp to 9
      buf.append((char) ('0' + value));
    } else if (count == 2) {
      value = Math.min((value + 5) / 10, 99); // Round to 10ms, clamp to 99
      zeroPaddingNumber(buf, value, 2);
    } else {
      zeroPaddingNumber(buf, value, 3);

      if (count > 3) {
        zeroPaddingNumber(buf, 0, count - 3);
      }
    }
  }

  /**
   * Formats Minutes field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatMinutes(StringBuffer buf, int count, Date date) {
    int value = date.getMinutes();
    zeroPaddingNumber(buf, value, count);
  }

  /**
   * Formats Month field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatMonth(StringBuffer buf, int count, Date date) {
    int value = date.getMonth();
    switch (count) {
      case 5:
        buf.append(dateTimeFormatInfo.monthsNarrow()[value]);
        break;
      case 4:
        buf.append(dateTimeFormatInfo.monthsFull()[value]);
        break;
      case 3:
        buf.append(dateTimeFormatInfo.monthsShort()[value]);
        break;
      default:
        zeroPaddingNumber(buf, value + 1, count);
    }
  }

  /**
   * Formats Quarter field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatQuarter(StringBuffer buf, int count, Date date) {
    int value = date.getMonth() / 3;
    if (count < 4) {
      buf.append(dateTimeFormatInfo.quartersShort()[value]);
    } else {
      buf.append(dateTimeFormatInfo.quartersFull()[value]);
    }
  }

  /**
   * Formats Seconds field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatSeconds(StringBuffer buf, int count, Date date) {
    int value = date.getSeconds();
    zeroPaddingNumber(buf, value, count);
  }

  /**
   * Formats Standalone weekday field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatStandaloneDay(StringBuffer buf, int count, Date date) {
    int value = date.getDay();
    if (count == 5) {
      buf.append(dateTimeFormatInfo.weekdaysNarrowStandalone()[value]);
    } else if (count == 4) {
      buf.append(dateTimeFormatInfo.weekdaysFullStandalone()[value]);
    } else if (count == 3) {
      buf.append(dateTimeFormatInfo.weekdaysShortStandalone()[value]);
    } else {
      zeroPaddingNumber(buf, value, 1);
    }
  }

  /**
   * Formats Standalone Month field according to pattern specified.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatStandaloneMonth(StringBuffer buf, int count, Date date) {
    int value = date.getMonth();
    if (count == 5) {
      buf.append(dateTimeFormatInfo.monthsNarrowStandalone()[value]);
    } else if (count == 4) {
      buf.append(dateTimeFormatInfo.monthsFullStandalone()[value]);
    } else if (count == 3) {
      buf.append(dateTimeFormatInfo.monthsShortStandalone()[value]);
    } else {
      zeroPaddingNumber(buf, value + 1, count);
    }
  }

  /**
   * Formats Timezone field.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatTimeZone(StringBuffer buf, int count, Date date,
      TimeZone timeZone) {
    if (count < 4) {
      buf.append(timeZone.getShortName(date));
    } else {
      buf.append(timeZone.getLongName(date));
    }
  }

  /**
   * Formats Timezone field following RFC.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date hold the date object to be formatted
   */
  private void formatTimeZoneRFC(StringBuffer buf, int count, Date date,
      TimeZone timeZone) {
    if (count < 3) {
      buf.append(timeZone.getRFCTimeZoneString(date));
    } else if (count == 3) {
      buf.append(timeZone.getISOTimeZoneString(date));
    } else {
      buf.append(timeZone.getGMTString(date));
    }
  }

  /**
   * Formats Year field according to pattern specified. Javascript Date object
   * seems incapable handling 1BC and year before. It can show you year 0 which
   * does not exists. following we just keep consistent with javascript's
   * toString method. But keep in mind those things should be unsupported.
   * 
   * @param buf where formatted string will be appended to
   * @param count number of time pattern char repeats; this controls how a field
   *     should be formatted; 2 is treated specially with the last two digits of
   *     the year, while more than 2 digits are zero-padded
   * @param date hold the date object to be formatted
   */
  private void formatYear(StringBuffer buf, int count, Date date) {
    int value = date.getYear() + JS_START_YEAR;
    if (value < 0) {
      value = -value;
    }
    switch (count) {
      case 1: // no padding
        buf.append(value);
        break;
      case 2: // last 2 digits of year, zero-padded
        zeroPaddingNumber(buf, value % 100, 2);
        break;
      default: // anything else is zero-padded
        zeroPaddingNumber(buf, value, count);
        break;
    }
  }

  /**
   * Method getNextCharCountInPattern calculate character repeat count in
   * pattern.
   * 
   * @param pattern describe the format of date string that need to be parsed
   * @param start the position of pattern character
   * @return repeat count
   */
  private int getNextCharCountInPattern(String pattern, int start) {
    char ch = pattern.charAt(start);
    int next = start + 1;
    while (next < pattern.length() && pattern.charAt(next) == ch) {
      ++next;
    }
    return next - start;
  }

  /**
   * Method identifies the start of a run of abutting numeric fields. Take the
   * pattern "HHmmss" as an example. We will try to parse 2/2/2 characters of
   * the input text, then if that fails, 1/2/2. We only adjust the width of the
   * leftmost field; the others remain fixed. This allows "123456" => 12:34:56,
   * but "12345" => 1:23:45. Likewise, for the pattern "yyyyMMdd" we try 4/2/2,
   * 3/2/2, 2/2/2, and finally 1/2/2. The first field of connected numeric
   * fields will be marked as abutStart, its width can be reduced to accomodate
   * others.
   */
  private void identifyAbutStart() {
    // 'abut' parts are continuous numeric parts. abutStart is the switch
    // point from non-abut to abut.
    boolean abut = false;

    int len = patternParts.size();
    for (int i = 0; i < len; i++) {
      if (isNumeric(patternParts.get(i))) {
        // If next part is not following abut sequence, and isNumeric.
        if (!abut && i + 1 < len && isNumeric(patternParts.get(i + 1))) {
          abut = true;
          patternParts.get(i).abutStart = true;
        }
      } else {
        abut = false;
      }
    }
  }

  /**
   * Method checks if the pattern part is a numeric field.
   * 
   * @param part pattern part to be examined
   * @return <code>true</code> if the pattern part is numberic field
   */
  private boolean isNumeric(PatternPart part) {
    if (part.count <= 0) {
      return false;
    }
    int i = NUMERIC_FORMAT_CHARS.indexOf(part.text.charAt(0));
    // M & L (index 0 and 1) are only numeric if there are less than 3 chars
    return (i > 1 || (i >= 0 && part.count < 3));
  }

  /**
   * Method attempts to match the text at a given position against an array of
   * strings. Since multiple strings in the array may match (for example, if the
   * array contains "a", "ab", and "abc", all will match the input string
   * "abcd") the longest match is returned.
   * 
   * @param text the time text being parsed
   * @param start where to start parsing
   * @param data the string array to parsed
   * @param pos to receive where the match stopped
   * @return the new start position if matching succeeded; a negative number
   *         indicating matching failure
   */
  private int matchString(String text, int start, String[] data, int[] pos) {
    int count = data.length;

    // There may be multiple strings in the data[] array which begin with
    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
    // We keep track of the longest match, and return that. Note that this
    // unfortunately requires us to test all array elements.
    int bestMatchLength = 0, bestMatch = -1;
    String textInLowerCase = text.substring(start).toLowerCase();
    for (int i = 0; i < count; ++i) {
      int length = data[i].length();
      // Always compare if we have no match yet; otherwise only compare
      // against potentially better matches (longer strings).
      if (length > bestMatchLength
          && textInLowerCase.startsWith(data[i].toLowerCase())) {
        bestMatch = i;
        bestMatchLength = length;
      }
    }
    if (bestMatch >= 0) {
      pos[0] = start + bestMatchLength;
    }
    return bestMatch;
  }

  /**
   * Parses text to produce a {@link Date} value. An
   * {@link IllegalArgumentException} is thrown if either the text is empty or
   * if the parse does not consume all characters of the text.
   * 
   * If using lenient parsing, certain invalid dates and times will be parsed.
   * For example, February 32nd would be parsed as March 4th in lenient mode,
   * but would throw an exception in non-lenient mode.
   * 
   * @param text the string being parsed
   * @param strict true to be strict when parsing, false to be lenient
   * @return a parsed date/time value
   * @throws IllegalArgumentException if the entire text could not be converted
   *           into a number
   */
  private Date parse(String text, boolean strict) {
    Date curDate = new Date();
    Date date = new Date(curDate.getYear(), curDate.getMonth(),
        curDate.getDate());
    int charsConsumed = parse(text, 0, date, strict);
    if (charsConsumed == 0 || charsConsumed < text.length()) {
      throw new IllegalArgumentException(text);
    }
    return date;
  }

  /**
   * This method parses the input string and fills its value into a {@link Date}
   * .
   * 
   * If using lenient parsing, certain invalid dates and times will be parsed.
   * For example, February 32nd would be parsed as March 4th in lenient mode,
   * but would return 0 in non-lenient mode.
   * 
   * @param text the string that need to be parsed
   * @param start the character position in "text" where parsing should start
   * @param date the date object that will hold parsed value
   * @param strict true to be strict when parsing, false to be lenient
   * 
   * @return 0 if parsing failed, otherwise the number of characters advanced
   */
  private int parse(String text, int start, Date date, boolean strict) {
    DateRecord cal = new DateRecord();
    int[] parsePos = {start};

    // For parsing abutting numeric fields. 'abutPat' is the
    // offset into 'pattern' of the first of 2 or more abutting
    // numeric fields. 'abutStart' is the offset into 'text'
    // where parsing the fields begins. 'abutPass' starts off as 0
    // and increments each time we try to parse the fields.
    int abutPat = -1; // If >=0, we are in a run of abutting numeric fields.
    int abutStart = 0;
    int abutPass = 0;

    for (int i = 0; i < patternParts.size(); ++i) {
      PatternPart part = patternParts.get(i);

      if (part.count > 0) {
        if (abutPat < 0 && part.abutStart) {
          abutPat = i;
          abutStart = start;
          abutPass = 0;
        }

        // Handle fields within a run of abutting numeric fields. Take
        // the pattern "HHmmss" as an example. We will try to parse
        // 2/2/2 characters of the input text, then if that fails,
        // 1/2/2. We only adjust the width of the leftmost field; the
        // others remain fixed. This allows "123456" => 12:34:56, but
        // "12345" => 1:23:45. Likewise, for the pattern "yyyyMMdd" we
        // try 4/2/2, 3/2/2, 2/2/2, and finally 1/2/2.
        if (abutPat >= 0) {
          // If we are at the start of a run of abutting fields, then
          // shorten this field in each pass. If we can't shorten
          // this field any more, then the parse of this set of
          // abutting numeric fields has failed.
          int count = part.count;
          if (i == abutPat) {
            count -= abutPass++;
            if (count == 0) {
              return 0;
            }
          }

          if (!subParse(text, parsePos, part, count, cal)) {
            // If the parse fails anywhere in the run, back up to the
            // start of the run and retry.
            i = abutPat - 1;
            parsePos[0] = abutStart;
            continue;
          }
        } else {
          // Handle non-numeric fields and non-abutting numeric fields.
          abutPat = -1;
          if (!subParse(text, parsePos, part, 0, cal)) {
            return 0;
          }
        }
      } else {
        // Handle literal pattern characters. These are any
        // quoted characters and non-alphabetic unquoted characters.
        abutPat = -1;
        // A run of white space in the pattern matches a run
        // of white space in the input text.
        if (part.text.charAt(0) == ' ') {
          // Advance over run in input text.
          int s = parsePos[0];
          skipSpace(text, parsePos);

          // Must see at least one white space char in input.
          if (parsePos[0] > s) {
            continue;
          }
        } else if (text.startsWith(part.text, parsePos[0])) {
          parsePos[0] += part.text.length();
          continue;
        }

        // We fall through to this point if the match fails.
        return 0;
      }
    }

    // Calculate the date from the parts
    if (!cal.calcDate(date, strict)) {
      return 0;
    }

    // Return progress.
    return parsePos[0] - start;
  }

  /**
   * Method parses a integer string and return integer value.
   * 
   * @param text string being parsed
   * @param pos parse position
   * 
   * @return integer value
   */
  private int parseInt(String text, int[] pos) {
    int ret = 0;
    int ind = pos[0];
    if (ind >= text.length()) {
      return -1;
    }
    char ch = text.charAt(ind);
    while (ch >= '0' && ch <= '9') {
      ret = ret * 10 + (ch - '0');
      ind++;
      if (ind >= text.length()) {
        break;
      }
      ch = text.charAt(ind);
    }
    if (ind > pos[0]) {
      pos[0] = ind;
    } else {
      ret = -1;
    }
    return ret;
  }

  /**
   * Method parses the input pattern string a generate a vector of pattern
   * parts.
   * 
   * @param pattern describe the format of date string that need to be parsed
   */
  private void parsePattern(String pattern) {
    StringBuffer buf = new StringBuffer(32);
    boolean inQuote = false;

    for (int i = 0; i < pattern.length(); i++) {
      char ch = pattern.charAt(i);

      // Handle space, add literal part (if exist), and add space part.
      if (ch == ' ') {
        addPart(buf, 0);
        buf.append(' ');
        addPart(buf, 0);
        while (i + 1 < pattern.length() && pattern.charAt(i + 1) == ' ') {
          i++;
        }
        continue;
      }

      // If inside quote, except two quote connected, just copy or exit.
      if (inQuote) {
        if (ch == '\'') {
          if (i + 1 < pattern.length() && pattern.charAt(i + 1) == '\'') {
            // Quote appeared twice continuously, interpret as one quote.
            buf.append(ch);
            ++i;
          } else {
            inQuote = false;
          }
        } else {
          // Literal.
          buf.append(ch);
        }
        continue;
      }

      // Outside quote now.
      if (PATTERN_CHARS.indexOf(ch) > 0) {
        addPart(buf, 0);
        buf.append(ch);
        int count = getNextCharCountInPattern(pattern, i);
        addPart(buf, count);
        i += count - 1;
        continue;
      }

      // Two consecutive quotes is a quote literal, inside or outside of quotes.
      if (ch == '\'') {
        if (i + 1 < pattern.length() && pattern.charAt(i + 1) == '\'') {
          buf.append('\'');
          i++;
        } else {
          inQuote = true;
        }
      } else {
        buf.append(ch);
      }
    }

    addPart(buf, 0);

    identifyAbutStart();
  }

  /**
   * Method parses time zone offset.
   * 
   * @param text the time text to be parsed
   * @param pos Parse position
   * @param cal DateRecord object that holds parsed value
   * 
   * @return <code>true</code> if parsing successful, otherwise
   *         <code>false</code>
   */
  private boolean parseTimeZoneOffset(String text, int[] pos, DateRecord cal) {
    if (pos[0] >= text.length()) {
      cal.setTzOffset(0);
      return true;
    }

    int sign;
    switch (text.charAt(pos[0])) {
      case '+':
        sign = 1;
        break;
      case '-':
        sign = -1;
        break;
      default:
        cal.setTzOffset(0);
        return true;
    }
    ++(pos[0]);

    // Look for hours:minutes or hhmm.
    int st = pos[0];
    int value = parseInt(text, pos);
    if (value == 0 && pos[0] == st) {
      return false;
    }

    int offset;
    if (pos[0] < text.length() && text.charAt(pos[0]) == ':') {
      // This is the hours:minutes case.
      offset = value * MINUTES_PER_HOUR;
      ++(pos[0]);
      st = pos[0];
      value = parseInt(text, pos);
      if (value == 0 && pos[0] == st) {
        return false;
      }
      offset += value;
    } else {
      // This is the hhmm case.
      offset = value;
      // Assume "-23".."+23" refers to hours.
      if (offset < 24 && (pos[0] - st) <= 2) {
        offset *= MINUTES_PER_HOUR;
      } else {
        offset = offset % 100 + offset / 100 * MINUTES_PER_HOUR;
      }
    }

    offset *= sign;
    cal.setTzOffset(-offset);
    return true;
  }

  /**
   * Method skips space in the string as pointed by pos.
   * 
   * @param text input string
   * @param pos where skip start, and return back where skip stop
   */
  private void skipSpace(String text, int[] pos) {
    while (pos[0] < text.length()
        && WHITE_SPACE.indexOf(text.charAt(pos[0])) >= 0) {
      ++(pos[0]);
    }
  }

  /**
   * Formats a single field according to pattern specified.
   * 
   * @param ch pattern character for this field
   * @param count number of time pattern char repeats; this controls how a field
   *          should be formatted
   * @param date the date object to be formatted
   * @param adjustedDate holds the time zone adjusted date fields
   * @param adjustedTime holds the time zone adjusted time fields
   * 
   * @return <code>true</code> if pattern valid, otherwise <code>false</code>
   * 
   */
  private boolean subFormat(StringBuffer buf, char ch, int count, Date date,
      Date adjustedDate, Date adjustedTime, TimeZone timezone) {
    switch (ch) {
      case 'G':
        formatEra(buf, count, adjustedDate);
        break;
      case 'y':
        formatYear(buf, count, adjustedDate);
        break;
      case 'M':
        formatMonth(buf, count, adjustedDate);
        break;
      case 'k':
        format24Hours(buf, count, adjustedTime);
        break;
      case 'S':
        formatFractionalSeconds(buf, count, adjustedTime);
        break;
      case 'E':
        formatDayOfWeek(buf, count, adjustedDate);
        break;
      case 'a':
        formatAmPm(buf, adjustedTime);
        break;
      case 'h':
        format1To12Hours(buf, count, adjustedTime);
        break;
      case 'K':
        format0To11Hours(buf, count, adjustedTime);
        break;
      case 'H':
        format0To23Hours(buf, count, adjustedTime);
        break;
      case 'c':
        formatStandaloneDay(buf, count, adjustedDate);
        break;
      case 'L':
        formatStandaloneMonth(buf, count, adjustedDate);
        break;
      case 'Q':
        formatQuarter(buf, count, adjustedDate);
        break;
      case 'd':
        formatDate(buf, count, adjustedDate);
        break;
      case 'm':
        formatMinutes(buf, count, adjustedTime);
        break;
      case 's':
        formatSeconds(buf, count, adjustedTime);
        break;
      case 'z':
        formatTimeZone(buf, count, date, timezone);
        break;
      case 'v':
        buf.append(timezone.getID());
        break;
      case 'Z':
        formatTimeZoneRFC(buf, count, date, timezone);
        break;
      default:
        return false;
    }
    return true;
  }

  /**
   * Converts one field of the input string into a numeric field value. Returns
   * <code>false</code> if failed.
   * 
   * @param text the time text to be parsed
   * @param pos Parse position
   * @param part the pattern part for this field
   * @param digitCount when greater than 0, numeric parsing must obey the count
   * @param cal DateRecord object that will hold parsed value
   * 
   * @return <code>true</code> if parsing successful
   */
  @SuppressWarnings("fallthrough")
  private boolean subParse(String text, int[] pos, PatternPart part,
      int digitCount, DateRecord cal) {

    skipSpace(text, pos);

    int start = pos[0];
    char ch = part.text.charAt(0);

    // Parse integer value if it is a numeric field.
    int value = -1; // initialize value to be -1,
    if (isNumeric(part)) {
      if (digitCount > 0) {
        if ((start + digitCount) > text.length()) {
          return false;
        }
        value = parseInt(text.substring(0, start + digitCount), pos);
      } else {
        value = parseInt(text, pos);
      }
    }

    switch (ch) {
      case 'G': // era
        value = matchString(text, start, dateTimeFormatInfo.erasFull(), pos);
        cal.setEra(value);
        return true;
      case 'M': // month
        return subParseMonth(text, pos, cal, value, start);
      case 'L': // standalone month
        return subParseStandaloneMonth(text, pos, cal, value, start);
      case 'E': // day of week
        return subParseDayOfWeek(text, pos, start, cal);
      case 'c': // standalone day of week
        return subParseStandaloneDay(text, pos, start, cal);
      case 'a': // AM/PM
        value = matchString(text, start, dateTimeFormatInfo.ampms(), pos);
        cal.setAmpm(value);
        return true;
      case 'y': // year
        return subParseYear(text, pos, start, value, part, cal);
      case 'd': // day of month
        if (value <= 0) {
          return false;
        }
        cal.setDayOfMonth(value);
        return true;
      case 'S': // fractional seconds
        if (value < 0) {
          return false;
        }
        return subParseFractionalSeconds(value, start, pos[0], cal);
      case 'h': // hour (1..12)
        if (value == 12) {
          value = 0;
        }
        // fall through
      case 'K': // hour (0..11)
      case 'H': // hour (0..23)
        if (value < 0) {
          return false;
        }
        cal.setHours(value);
        return true;
      case 'k': // hour (1..24)
        if (value < 0) {
          return false;
        }
        cal.setHours(value);
        return true;
      case 'm': // minute
        if (value < 0) {
          return false;
        }
        cal.setMinutes(value);
        return true;
      case 's': // second
        if (value < 0) {
          return false;
        }
        cal.setSeconds(value);
        return true;

      case 'z': // time zone offset
      case 'Z': // time zone RFC
      case 'v': // time zone generic
        return subParseTimeZoneInGMT(text, start, pos, cal);
      default:
        return false;
    }
  }

  /**
   * Method subParseDayOfWeek parses day of the week field.
   * 
   * @param text the time text to be parsed
   * @param pos Parse position
   * @param start from where parse start
   * @param cal DateRecord object that holds parsed value
   * 
   * @return <code>true</code> if parsing successful, otherwise
   *         <code>false</code>
   */
  private boolean subParseDayOfWeek(String text, int[] pos, int start,
      DateRecord cal) {
    int value;
    // 'E' - DAY_OF_WEEK
    // Want to be able to parse both short and long forms.
    // Try count == 4 (DDDD) first:
    value = matchString(text, start, dateTimeFormatInfo.weekdaysFull(), pos);
    if (value < 0) {
      value = matchString(text, start, dateTimeFormatInfo.weekdaysShort(), pos);
    }
    if (value < 0) {
      return false;
    }
    cal.setDayOfWeek(value);
    return true;
  }

  /**
   * Method subParseFractionalSeconds parses fractional seconds field.
   * 
   * @param value parsed numberic value
   * @param start
   * @param end parse position
   * @param cal DateRecord object that holds parsed value
   * @return <code>true</code> if parsing successful, otherwise
   *         <code>false</code>
   */
  private boolean subParseFractionalSeconds(int value, int start, int end,
      DateRecord cal) {
    // Fractional seconds left-justify.
    int i = end - start;
    if (i < 3) {
      while (i < 3) {
        value *= 10;
        i++;
      }
    } else {
      int a = 1;
      while (i > 3) {
        a *= 10;
        i--;
      }
      value = (value + (a >> 1)) / a;
    }
    cal.setMilliseconds(value);
    return true;
  }

  /**
   * Parses Month field.
   * 
   * @param text the time text to be parsed
   * @param pos Parse position
   * @param cal DateRecord object that will hold parsed value
   * @param value numeric value if this field is expressed using numberic
   *          pattern
   * @param start from where parse start
   * 
   * @return <code>true</code> if parsing successful
   */
  private boolean subParseMonth(String text, int[] pos, DateRecord cal,
      int value, int start) {
    // When month is symbols, i.e., MMM or MMMM, value will be -1.
    if (value < 0) {
      // Want to be able to parse both short and long forms.
      // Try count == 4 first:
      value = matchString(text, start, dateTimeFormatInfo.monthsFull(), pos);
      if (value < 0) { // count == 4 failed, now try count == 3.
        value = matchString(text, start, dateTimeFormatInfo.monthsShort(), pos);
      }
      if (value < 0) {
        return false;
      }
      cal.setMonth(value);
      return true;
    } else if (value > 0) {
      cal.setMonth(value - 1);
      return true;
    }
    return false;
  }

  /**
   * Parses standalone day of the week field.
   * 
   * @param text the time text to be parsed
   * @param pos Parse position
   * @param start from where parse start
   * @param cal DateRecord object that holds parsed value
   * 
   * @return <code>true</code> if parsing successful, otherwise
   *         <code>false</code>
   */
  private boolean subParseStandaloneDay(String text, int[] pos, int start,
      DateRecord cal) {
    int value;
    // 'c' - DAY_OF_WEEK
    // Want to be able to parse both short and long forms.
    // Try count == 4 (cccc) first:
    value = matchString(text, start, dateTimeFormatInfo.weekdaysFullStandalone(),
        pos);
    if (value < 0) {
      value = matchString(text, start,
          dateTimeFormatInfo.weekdaysShortStandalone(), pos);
    }
    if (value < 0) {
      return false;
    }
    cal.setDayOfWeek(value);
    return true;
  }

  /**
   * Parses a standalone month field.
   * 
   * @param text the time text to be parsed
   * @param pos Parse position
   * @param cal DateRecord object that will hold parsed value
   * @param value numeric value if this field is expressed using numberic
   *          pattern
   * @param start from where parse start
   * 
   * @return <code>true</code> if parsing successful
   */
  private boolean subParseStandaloneMonth(String text, int[] pos,
      DateRecord cal, int value, int start) {
    // When month is symbols, i.e., LLL or LLLL, value will be -1.
    if (value < 0) {
      // Want to be able to parse both short and long forms.
      // Try count == 4 first:
      value = matchString(text, start,
          dateTimeFormatInfo.monthsFullStandalone(), pos);
      if (value < 0) { // count == 4 failed, now try count == 3.
        value = matchString(text, start,
            dateTimeFormatInfo.monthsShortStandalone(), pos);
      }
      if (value < 0) {
        return false;
      }
      cal.setMonth(value);
      return true;
    } else if (value > 0) {
      cal.setMonth(value - 1);
      return true;
    }
    return false;
  }

  /**
   * Method parses GMT type timezone.
   * 
   * @param text the time text to be parsed
   * @param start from where parse start
   * @param pos Parse position
   * @param cal DateRecord object that holds parsed value
   * 
   * @return <code>true</code> if parsing successful, otherwise
   *         <code>false</code>
   */
  private boolean subParseTimeZoneInGMT(String text, int start, int[] pos,
      DateRecord cal) {
    // First try to parse generic forms such as GMT-07:00. Do this first
    // in case localized DateFormatZoneData contains the string "GMT"
    // for a zone; in that case, we don't want to match the first three
    // characters of GMT+/-HH:MM etc.

    // For time zones that have no known names, look for strings
    // of the form:
    // GMT[+-]hours:minutes or
    // GMT[+-]hhmm or
    // GMT.
    if (text.startsWith(GMT, start)) {
      pos[0] = start + GMT.length();
      return parseTimeZoneOffset(text, pos, cal);
    }
    // Likewise for UTC.
    if (text.startsWith(UTC, start)) {
      pos[0] = start + UTC.length();
      return parseTimeZoneOffset(text, pos, cal);
    }

    // At this point, check for named time zones by looking through
    // the locale data from the DateFormatZoneData strings.
    // Want to be able to parse both short and long forms.
    /*
     * i = subParseZoneString(text, start, cal); if (i != 0) return i;
     */

    // As a last resort, look for numeric timezones of the form
    // [+-]hhmm as specified by RFC 822. This code is actually
    // a little more permissive than RFC 822. It will try to do
    // its best with numbers that aren't strictly 4 digits long.
    return parseTimeZoneOffset(text, pos, cal);
  }

  /**
   * Method subParseYear parse year field. Year field is special because 1, two
   * digit year need to be resolved. 2, we allow year to take a sign. 3, year
   * field participate in abut processing. In my testing, negative year does not
   * seem working due to JDK (or GWT implementation) limitation. It is not a
   * big deal so we don't worry about it. But keep the logic here so that we
   * might want to replace DateRecord with our a calendar class.
   * 
   * @param text the time text to be parsed
   * @param pos parse position
   * @param start where this field starts
   * @param value integer value of year
   * @param part the pattern part for this field
   * @param cal DateRecord object that will hold parsed value
   * 
   * @return <code>true</code> if successful
   */
  private boolean subParseYear(String text, int[] pos, int start, int value,
      PatternPart part, DateRecord cal) {
    char ch = ' ';
    if (value < 0) {
      if (pos[0] >= text.length()) {
        return false;
      }
      ch = text.charAt(pos[0]);
      // Check if it is a sign.
      if (ch != '+' && ch != '-') {
        return false;
      }
      ++(pos[0]);
      value = parseInt(text, pos);
      if (value < 0) {
        return false;
      }
      if (ch == '-') {
        value = -value;
      }
    }

    // no sign, only 2 digit was actually parsed, pattern say it has 2 digit.
    if (ch == ' ' && (pos[0] - start) == 2 && part.count == 2) {
      // Assume for example that the defaultCenturyStart is 6/18/1903.
      // This means that two-digit years will be forced into the range
      // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02
      // correspond to 2000, 2001, and 2002. Years 04, 05, etc. correspond
      // to 1904, 1905, etc. If the year is 03, then it is 2003 if the
      // other fields specify a date before 6/18, or 1903 if they specify a
      // date afterwards. As a result, 03 is an ambiguous year. All other
      // two-digit years are unambiguous.
      Date date = new Date();
      int defaultCenturyStartYear = date.getYear() + 1900 - 80;
      int ambiguousTwoDigitYear = defaultCenturyStartYear % 100;
      cal.setAmbiguousYear(value == ambiguousTwoDigitYear);
      value += (defaultCenturyStartYear / 100) * 100
          + (value < ambiguousTwoDigitYear ? 100 : 0);
    }
    cal.setYear(value);
    return true;
  }

  /**
   * Formats a number with the specified minimum number of digits, using zero to
   * fill the gap.
   * 
   * @param buf where zero padded string will be written to
   * @param value the number value being formatted
   * @param minWidth minimum width of the formatted string; zero will be padded
   *          to reach this width
   */
  private void zeroPaddingNumber(StringBuffer buf, int value, int minWidth) {
    int b = NUMBER_BASE;
    for (int i = 0; i < minWidth - 1; i++) {
      if (value < b) {
        buf.append('0');
      }
      b *= NUMBER_BASE;
    }
    buf.append(value);
  }
}
