/*
 * 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 java.util.ArrayList;
import java.util.Date;

/**
 * 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, ZZZ</td>
 * <td>-0700</td>
 * <td>-0700</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 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 {
  /**
   * 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 FULL_DATE_FORMAT = 0;
  private static final int LONG_DATE_FORMAT = 1;
  private static final int MEDIUM_DATE_FORMAT = 2;
  private static final int SHORT_DATE_FORMAT = 3;
  private static final int FULL_TIME_FORMAT = 0;
  private static final int LONG_TIME_FORMAT = 1;
  private static final int MEDIUM_TIME_FORMAT = 2;

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

  private static DateTimeFormat cachedFullDateFormat;
  private static DateTimeFormat cachedLongDateFormat;
  private static DateTimeFormat cachedMediumDateFormat;

  private static DateTimeFormat cachedShortDateFormat;
  private static DateTimeFormat cachedFullTimeFormat;
  private static DateTimeFormat cachedLongTimeFormat;
  private static DateTimeFormat cachedMediumTimeFormat;

  private static DateTimeFormat cachedShortTimeFormat;
  private static DateTimeFormat cachedFullDateTimeFormat;
  private static DateTimeFormat cachedLongDateTimeFormat;
  private static DateTimeFormat cachedMediumDateTimeFormat;
  private static DateTimeFormat cachedShortDateTimeFormat;

  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 int MINUTES_PER_HOUR = 60;

  /**
   * 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.
   * 
   * @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 new DateTimeFormat(pattern, getDefaultDateTimeConstants());
  }

  /**
   * Retrieve the DateTimeFormat object for full date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getFullDateFormat() {
    if (cachedFullDateFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[FULL_DATE_FORMAT];
      cachedFullDateFormat = new DateTimeFormat(pattern);
    }
    return cachedFullDateFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for full date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getFullDateTimeFormat() {
    if (cachedFullDateTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[FULL_DATE_FORMAT]
          + " " + getDefaultDateTimeConstants().timeFormats()[FULL_TIME_FORMAT];
      cachedFullDateTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedFullDateTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for full time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getFullTimeFormat() {
    if (cachedFullTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().timeFormats()[FULL_TIME_FORMAT];
      cachedFullTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedFullTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for long date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getLongDateFormat() {
    if (cachedLongDateFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[LONG_DATE_FORMAT];
      cachedLongDateFormat = new DateTimeFormat(pattern);
    }
    return cachedLongDateFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for long date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getLongDateTimeFormat() {
    if (cachedLongDateTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[LONG_DATE_FORMAT]
          + " " + getDefaultDateTimeConstants().timeFormats()[LONG_TIME_FORMAT];
      cachedLongDateTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedLongDateTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for long time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getLongTimeFormat() {
    if (cachedLongTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().timeFormats()[LONG_TIME_FORMAT];
      cachedLongTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedLongTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for medium date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getMediumDateFormat() {
    if (cachedMediumDateFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[MEDIUM_DATE_FORMAT];
      cachedMediumDateFormat = new DateTimeFormat(pattern);
    }
    return cachedMediumDateFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for medium date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getMediumDateTimeFormat() {
    if (cachedMediumDateTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[MEDIUM_DATE_FORMAT]
          + " " + getDefaultDateTimeConstants().timeFormats()[MEDIUM_TIME_FORMAT];
      cachedMediumDateTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedMediumDateTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for medium time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getMediumTimeFormat() {
    if (cachedMediumTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().timeFormats()[MEDIUM_TIME_FORMAT];
      cachedMediumTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedMediumTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for short date format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getShortDateFormat() {
    if (cachedShortDateFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[SHORT_DATE_FORMAT];
      cachedShortDateFormat = new DateTimeFormat(pattern);
    }
    return cachedShortDateFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for short date and time format. The
   * pattern for this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getShortDateTimeFormat() {
    if (cachedShortDateTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().dateFormats()[SHORT_DATE_FORMAT]
          + " " + getDefaultDateTimeConstants().timeFormats()[SHORT_TIME_FORMAT];
      cachedShortDateTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedShortDateTimeFormat;
  }

  /**
   * Retrieve the DateTimeFormat object for short time format. The pattern for
   * this format is predefined for each locale.
   * 
   * @return A DateTimeFormat object.
   */
  public static DateTimeFormat getShortTimeFormat() {
    if (cachedShortTimeFormat == null) {
      String pattern = getDefaultDateTimeConstants().timeFormats()[SHORT_TIME_FORMAT];
      cachedShortTimeFormat = new DateTimeFormat(pattern);
    }
    return cachedShortTimeFormat;
  }

  private static DateTimeConstants getDefaultDateTimeConstants() {
    return LocaleInfo.getCurrentLocale().getDateTimeConstants();
  }

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

  private final DateTimeConstants dateTimeConstants;

  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, getDefaultDateTimeConstants());
  }

  /**
   * 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
   */
  protected DateTimeFormat(String pattern, DateTimeConstants dateTimeConstants) {
    this.pattern = pattern;
    this.dateTimeConstants = dateTimeConstants;

    /*
     * 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(dateTimeConstants.ampms()[1]);
    } else {
      buf.append(dateTimeConstants.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(dateTimeConstants.narrowWeekdays()[value]);
    } else if (count == 4) {
      buf.append(dateTimeConstants.weekdays()[value]);
    } else {
      buf.append(dateTimeConstants.shortWeekdays()[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(dateTimeConstants.eraNames()[value]);
    } else {
      buf.append(dateTimeConstants.eras()[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);
    } 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(dateTimeConstants.narrowMonths()[value]);
        break;
      case 4:
        buf.append(dateTimeConstants.months()[value]);
        break;
      case 3:
        buf.append(dateTimeConstants.shortMonths()[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(dateTimeConstants.shortQuarters()[value]);
    } else {
      buf.append(dateTimeConstants.quarters()[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(dateTimeConstants.standaloneNarrowWeekdays()[value]);
    } else if (count == 4) {
      buf.append(dateTimeConstants.standaloneWeekdays()[value]);
    } else if (count == 3) {
      buf.append(dateTimeConstants.standaloneShortWeekdays()[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(dateTimeConstants.standaloneNarrowMonths()[value]);
    } else if (count == 4) {
      buf.append(dateTimeConstants.standaloneMonths()[value]);
    } else if (count == 3) {
      buf.append(dateTimeConstants.standaloneShortMonths()[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 < 4) {
      buf.append(timeZone.getRFCTimeZoneString(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
   * @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;
    }
    if (count == 2) {
      zeroPaddingNumber(buf, value % 100, 2);
    } else {
      // count != 2
      buf.append(value);
    }
  }

  /**
   * 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 parsingm 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];
    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, dateTimeConstants.eras(), 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, dateTimeConstants.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
        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)
        cal.setHours(value);
        return true;
      case 'k': // hour (1..24)
        cal.setHours(value);
        return true;
      case 'm': // minute
        cal.setMinutes(value);
        return true;
      case 's': // second
        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, dateTimeConstants.weekdays(), pos);
    if (value < 0) {
      value = matchString(text, start, dateTimeConstants.shortWeekdays(), 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, dateTimeConstants.months(), pos);
      if (value < 0) { // count == 4 failed, now try count == 3.
        value = matchString(text, start, dateTimeConstants.shortMonths(), 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, dateTimeConstants.standaloneWeekdays(),
        pos);
    if (value < 0) {
      value = matchString(text, start,
          dateTimeConstants.standaloneShortWeekdays(), 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,
          dateTimeConstants.standaloneMonths(), pos);
      if (value < 0) { // count == 4 failed, now try count == 3.
        value = matchString(text, start,
            dateTimeConstants.standaloneShortMonths(), 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);
    }

    // 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 redpill 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 star
   * @param value integer value of yea
   * @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) {
      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);
  }
}
