151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The original version of this source code and documentation is copyrighted 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * materials are provided under terms of a License Agreement between Taligent 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and Sun. This technology is protected by multiple US and International 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * patents. This notice and attribution to Taligent may not be removed. 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Taligent is a registered trademark of Taligent, Inc. 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.text; 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.InvalidObjectException; 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.ObjectInputStream; 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Calendar; 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Date; 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.GregorianCalendar; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Locale; 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Map; 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.SimpleTimeZone; 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.TimeZone; 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.ConcurrentHashMap; 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.ConcurrentMap; 549c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebskiimport libcore.icu.LocaleData; 55cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauerimport libcore.icu.TimeZoneNames; 56cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.util.calendar.CalendarUtils; 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport static java.text.DateFormatSymbols.*; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> is a concrete class for formatting and 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parsing dates in a locale-sensitive manner. It allows for formatting 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (date -> text), parsing (text -> date), and normalization. 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> allows you to start by choosing 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * any user-defined patterns for date-time formatting. However, you 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are encouraged to create a date-time formatter with either 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>getTimeInstance</code>, <code>getDateInstance</code>, or 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>getDateTimeInstance</code> in <code>DateFormat</code>. Each 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of these class methods can return a date/time formatter initialized 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with a default format pattern. You may modify the format pattern 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * using the <code>applyPattern</code> methods as desired. 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For more information on using these methods, see 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link DateFormat}. 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <h4>Date and Time Patterns</h4> 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Date and time formats are specified by <em>date and time pattern</em> 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * strings. 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Within date and time pattern strings, unquoted letters from 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>'A'</code> to <code>'Z'</code> and from <code>'a'</code> to 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>'z'</code> are interpreted as pattern letters representing the 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * components of a date or time string. 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Text can be quoted using single quotes (<code>'</code>) to avoid 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interpretation. 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>"''"</code> represents a single quote. 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All other characters are not interpreted; they're simply copied into the 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * output string during formatting or matched against the input string 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * during parsing. 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following pattern letters are defined (all other characters from 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>'A'</code> to <code>'Z'</code> and from <code>'a'</code> to 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>'z'</code> are reserved): 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote> 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <table border=0 cellspacing=3 cellpadding=0 summary="Chart shows pattern letters, date/time component, presentation, and examples."> 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#ccccff"> 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <th align=left>Letter 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <th align=left>Date or Time Component 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <th align=left>Presentation 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <th align=left>Examples 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>G</code> 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Era designator 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#text">Text</a> 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>AD</code> 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>y</code> 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Year 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#year">Year</a> 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>1996</code>; <code>96</code> 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>Y</code> 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Week year 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#year">Year</a> 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2009</code>; <code>09</code> 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>M</code> 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Month in year 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#month">Month</a> 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>July</code>; <code>Jul</code>; <code>07</code> 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>w</code> 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Week in year 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>27</code> 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>W</code> 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Week in month 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2</code> 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>D</code> 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Day in year 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>189</code> 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>d</code> 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Day in month 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>10</code> 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>F</code> 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Day of week in month 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2</code> 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>E</code> 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Day name in week 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#text">Text</a> 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>Tuesday</code>; <code>Tue</code> 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>u</code> 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Day number of week (1 = Monday, ..., 7 = Sunday) 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>1</code> 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>a</code> 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Am/pm marker 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#text">Text</a> 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>PM</code> 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>H</code> 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Hour in day (0-23) 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>0</code> 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>k</code> 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Hour in day (1-24) 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>24</code> 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>K</code> 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Hour in am/pm (0-11) 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>0</code> 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>h</code> 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Hour in am/pm (1-12) 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>12</code> 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>m</code> 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Minute in hour 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>30</code> 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>s</code> 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Second in minute 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>55</code> 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>S</code> 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Millisecond 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#number">Number</a> 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>978</code> 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>z</code> 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Time zone 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#timezone">General time zone</a> 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>Pacific Standard Time</code>; <code>PST</code>; <code>GMT-08:00</code> 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>Z</code> 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Time zone 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#rfc822timezone">RFC 822 time zone</a> 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>-0800</code> 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>X</code> 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td>Time zone 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><a href="#iso8601timezone">ISO 8601 time zone</a> 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>-08</code>; <code>-0800</code>; <code>-08:00</code> 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </table> 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </blockquote> 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Pattern letters are usually repeated, as their number determines the 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exact presentation: 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul> 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="text">Text:</a></strong> 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For formatting, if the number of pattern letters is 4 or more, 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the full form is used; otherwise a short or abbreviated form 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is used if available. 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For parsing, both forms are accepted, independent of the number 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of pattern letters.<br><br></li> 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="number">Number:</a></strong> 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For formatting, the number of pattern letters is the minimum 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * number of digits, and shorter numbers are zero-padded to this amount. 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For parsing, the number of pattern letters is ignored unless 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it's needed to separate two adjacent fields.<br><br></li> 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="year">Year:</a></strong> 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the formatter's {@link #getCalendar() Calendar} is the Gregorian 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calendar, the following rules are applied.<br> 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul> 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>For formatting, if the number of pattern letters is 2, the year 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is truncated to 2 digits; otherwise it is interpreted as a 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="#number">number</a>. 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>For parsing, if the number of pattern letters is more than 2, 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the year is interpreted literally, regardless of the number of 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Jan 11, 12 A.D. 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li>For parsing with the abbreviated year pattern ("y" or "yy"), 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> must interpret the abbreviated year 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * relative to some century. It does this by adjusting dates to be 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * within 80 years before and 20 years after the time the <code>SimpleDateFormat</code> 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * instance is created. For example, using a pattern of "MM/dd/yy" and a 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> instance created on Jan 1, 1997, the string 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * would be interpreted as May 4, 1964. 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * During parsing, only strings consisting of exactly two digits, as defined by 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link Character#isDigit(char)}, will be parsed into the default century. 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Any other numeric string, such as a one digit string, a three or more digit 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * string, or a two digit string that isn't all digits (for example, "-1"), is 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC. 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul> 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise, calendar system specific forms are applied. 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For both formatting and parsing, if the number of pattern 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * letters is 4 or more, a calendar specific {@linkplain 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Calendar#LONG long form} is used. Otherwise, a calendar 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specific {@linkplain Calendar#SHORT short or abbreviated form} 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is used.<br> 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <br> 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If week year {@code 'Y'} is specified and the {@linkplain 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * #getCalendar() calendar} doesn't support any <a 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * href="../util/GregorianCalendar.html#week_year"> week 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * years</a>, the calendar year ({@code 'y'}) is used instead. The 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * support of week years can be tested with a call to {@link 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DateFormat#getCalendar() getCalendar()}.{@link 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.util.Calendar#isWeekDateSupported() 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * isWeekDateSupported()}.<br><br></li> 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="month">Month:</a></strong> 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the number of pattern letters is 3 or more, the month is 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interpreted as <a href="#text">text</a>; otherwise, 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is interpreted as a <a href="#number">number</a>.<br><br></li> 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="timezone">General time zone:</a></strong> 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Time zones are interpreted as <a href="#text">text</a> if they have 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * names. For time zones representing a GMT offset value, the 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * following syntax is used: 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a name="GMTOffsetTimeZone"><i>GMTOffsetTimeZone:</i></a> 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>GMT</code> <i>Sign</i> <i>Hours</i> <code>:</code> <i>Minutes</i> 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Sign:</i> one of 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>+ -</code> 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Hours:</i> 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Digit</i> 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Digit</i> <i>Digit</i> 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Minutes:</i> 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Digit</i> <i>Digit</i> 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Digit:</i> one of 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>0 1 2 3 4 5 6 7 8 9</code></pre> 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Hours</i> must be between 0 and 23, and <i>Minutes</i> must be between 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 00 and 59. The format is locale independent and digits must be taken 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * from the Basic Latin block of the Unicode standard. 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>For parsing, <a href="#rfc822timezone">RFC 822 time zones</a> are also 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accepted.<br><br></li> 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="rfc822timezone">RFC 822 time zone:</a></strong> 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For formatting, the RFC 822 4-digit time zone format is used: 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>RFC822TimeZone:</i> 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Sign</i> <i>TwoDigitHours</i> <i>Minutes</i> 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>TwoDigitHours:</i> 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Digit Digit</i></pre> 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>TwoDigitHours</i> must be between 00 and 23. Other definitions 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are as for <a href="#timezone">general time zones</a>. 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>For parsing, <a href="#timezone">general time zones</a> are also 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accepted. 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><strong><a name="iso8601timezone">ISO 8601 Time zone:</a></strong> 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The number of pattern letters designates the format for both formatting 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and parsing as follows: 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>ISO8601TimeZone:</i> 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>OneLetterISO8601TimeZone</i> 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>TwoLetterISO8601TimeZone</i> 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>ThreeLetterISO8601TimeZone</i> 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>OneLetterISO8601TimeZone:</i> 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Sign</i> <i>TwoDigitHours</i> 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code Z} 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>TwoLetterISO8601TimeZone:</i> 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Sign</i> <i>TwoDigitHours</i> <i>Minutes</i> 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code Z} 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>ThreeLetterISO8601TimeZone:</i> 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <i>Sign</i> <i>TwoDigitHours</i> {@code :} <i>Minutes</i> 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code Z}</pre> 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Other definitions are as for <a href="#timezone">general time zones</a> or 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="#rfc822timezone">RFC 822 time zones</a>. 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>For formatting, if the offset value from GMT is 0, {@code "Z"} is 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * produced. If the number of pattern letters is 1, any fraction of an hour 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is ignored. For example, if the pattern is {@code "X"} and the time zone is 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@code "GMT+05:30"}, {@code "+05"} is produced. 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>For parsing, {@code "Z"} is parsed as the UTC time zone designator. 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="#timezone">General time zones</a> are <em>not</em> accepted. 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If the number of pattern letters is 4 or more, {@link 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IllegalArgumentException} is thrown when constructing a {@code 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SimpleDateFormat} or {@linkplain #applyPattern(String) applying a 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern}. 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul> 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> also supports <em>localized date and time 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern</em> strings. In these strings, the pattern letters described above 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be replaced with other, locale dependent, pattern letters. 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> does not deal with the localization of text 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * other than the pattern letters; that's up to the client of the class. 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <h4>Examples</h4> 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following examples show how date and time patterns are interpreted in 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the U.S. locale. The given date and time are 2001-07-04 12:08:56 local time 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the U.S. Pacific Time time zone. 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote> 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <table border=0 cellspacing=3 cellpadding=0 summary="Examples of date and time patterns interpreted in the U.S. locale"> 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#ccccff"> 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <th align=left>Date and Time Pattern 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <th align=left>Result 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"yyyy.MM.dd G 'at' HH:mm:ss z"</code> 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2001.07.04 AD at 12:08:56 PDT</code> 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"EEE, MMM d, ''yy"</code> 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>Wed, Jul 4, '01</code> 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"h:mm a"</code> 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>12:08 PM</code> 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"hh 'o''clock' a, zzzz"</code> 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>12 o'clock PM, Pacific Daylight Time</code> 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"K:mm a, z"</code> 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>0:08 PM, PDT</code> 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"yyyyy.MMMMM.dd GGG hh:mm aaa"</code> 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>02001.July.04 AD 12:08 PM</code> 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"EEE, d MMM yyyy HH:mm:ss Z"</code> 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>Wed, 4 Jul 2001 12:08:56 -0700</code> 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"yyMMddHHmmssZ"</code> 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>010704120856-0700</code> 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"yyyy-MM-dd'T'HH:mm:ss.SSSZ"</code> 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2001-07-04T12:08:56.235-0700</code> 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr bgcolor="#eeeeff"> 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"</code> 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2001-07-04T12:08:56.235-07:00</code> 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <tr> 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>"YYYY-'W'ww-u"</code> 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <td><code>2001-W27-3</code> 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </table> 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </blockquote> 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <h4><a name="synchronization">Synchronization</a></h4> 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Date formats are not synchronized. 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It is recommended to create separate format instances for each thread. 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If multiple threads access a format concurrently, it must be synchronized 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * externally. 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/simpleDateFormat.html">Java Tutorial</a> 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.Calendar 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.TimeZone 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see DateFormat 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see DateFormatSymbols 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Mark Davis, Chen-Lieh Huang, Alan Liu 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class SimpleDateFormat extends DateFormat { 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the official serial version ID which says cryptically 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // which version we're compatible with 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final long serialVersionUID = 4774881970558875024L; 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the internal serial version which says which version was written 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // - 0 (default) for version up to JDK 1.1.3 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // - 1 for version from JDK 1.1.4, which includes a new field 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int currentSerialVersion = 1; 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The version of the serialized data on the stream. Possible values: 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul> 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><b>0</b> or not present on stream: JDK 1.1.3. This version 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * has no <code>defaultCenturyStart</code> on stream. 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><b>1</b> JDK 1.1.4 or later. This version adds 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>defaultCenturyStart</code>. 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </ul> 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When streaming out this class, the most recent format 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the highest allowable <code>serialVersionOnStream</code> 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is written. 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1.4 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int serialVersionOnStream = currentSerialVersion; 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The pattern string of this formatter. This is always a non-localized 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern. May not be null. See class documentation for details. 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String pattern; 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Saved numberFormat and pattern. 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SimpleDateFormat#checkNegativeNumberExpression 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private NumberFormat originalNumberFormat; 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private String originalNumberPattern; 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The minus sign to be used with format and parse. 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private char minusSign = '-'; 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * True when a negative sign follows a number. 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (True as default in Arabic.) 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private boolean hasFollowingMinusSign = false; 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The compiled pattern. 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private char[] compiledPattern; 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tags for the compiled pattern. 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final static int TAG_QUOTE_ASCII_CHAR = 100; 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final static int TAG_QUOTE_CHARS = 101; 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Locale dependent digit zero. 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #zeroPaddingNumber 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.text.DecimalFormatSymbols#getZeroDigit 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private char zeroDigit; 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The symbols used by this formatter for week names, month names, 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * etc. May not be null. 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.text.DateFormatSymbols 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private DateFormatSymbols formatData; 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * We map dates with two-digit years into the century starting at 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>defaultCenturyStart</code>, which may be any date. May 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not be null. 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1.4 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Date defaultCenturyStart; 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient private int defaultCenturyStartYear; 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int MILLIS_PER_MINUTE = 60 * 1000; 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // For time zones that have no names, use strings GMT+minutes and 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // GMT-minutes. For instance, in France the time zone is GMT+60. 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final String GMT = "GMT"; 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Cache NumberFormat instances with Locale key. 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final ConcurrentMap<Locale, NumberFormat> cachedNumberFormatData 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski = new ConcurrentHashMap<Locale, NumberFormat>(3); 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The Locale used to instantiate this 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code>. The value may be null if this object 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * has been created by an older <code>SimpleDateFormat</code> and 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * deserialized. 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @serial 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.6 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Locale locale; 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Indicates whether this <code>SimpleDateFormat</code> should use 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the DateFormatSymbols. If true, the format and parse methods 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * use the DateFormatSymbols values. If false, the format and 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parse methods call Calendar.getDisplayName or 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Calendar.getDisplayNames. 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transient boolean useDateFormatSymbols; 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a <code>SimpleDateFormat</code> using the default pattern and 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * date format symbols for the default locale. 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <b>Note:</b> This constructor may not support all locales. 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For full coverage, use the factory methods in the {@link DateFormat} 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class. 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SimpleDateFormat() { 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(SHORT, SHORT, Locale.getDefault(Locale.Category.FORMAT)); 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a <code>SimpleDateFormat</code> using the given pattern and 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the default date format symbols for the default locale. 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <b>Note:</b> This constructor may not support all locales. 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For full coverage, use the factory methods in the {@link DateFormat} 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class. 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pattern the pattern describing the date and time format 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given pattern is null 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SimpleDateFormat(String pattern) 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(pattern, Locale.getDefault(Locale.Category.FORMAT)); 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a <code>SimpleDateFormat</code> using the given pattern and 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the default date format symbols for the given locale. 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <b>Note:</b> This constructor may not support all locales. 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For full coverage, use the factory methods in the {@link DateFormat} 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class. 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pattern the pattern describing the date and time format 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param locale the locale whose date format symbols should be used 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given pattern or locale is null 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SimpleDateFormat(String pattern, Locale locale) 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pattern == null || locale == null) { 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeCalendar(locale); 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.pattern = pattern; 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.formatData = DateFormatSymbols.getInstanceRef(locale); 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.locale = locale; 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initialize(locale); 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a <code>SimpleDateFormat</code> using the given pattern and 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * date format symbols. 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pattern the pattern describing the date and time format 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param formatSymbols the date format symbols to be used for formatting 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given pattern or formatSymbols is null 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols) 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pattern == null || formatSymbols == null) { 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.pattern = pattern; 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.formatData = (DateFormatSymbols) formatSymbols.clone(); 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.locale = Locale.getDefault(Locale.Category.FORMAT); 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeCalendar(this.locale); 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initialize(this.locale); 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useDateFormatSymbols = true; 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Package-private, called by DateFormat factory methods */ 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SimpleDateFormat(int timeStyle, int dateStyle, Locale loc) { 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (loc == null) { 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.locale = loc; 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // initialize calendar and related fields 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeCalendar(loc); 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski formatData = DateFormatSymbols.getInstanceRef(loc); 6166fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller LocaleData localeData = LocaleData.get(loc); 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((timeStyle >= 0) && (dateStyle >= 0)) { 6186fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller Object[] dateTimeArgs = { 6196fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller localeData.getDateFormat(dateStyle), 6206fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller localeData.getTimeFormat(timeStyle), 6216fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller }; 6226fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller pattern = MessageFormat.format("{0} {1}", dateTimeArgs); 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (timeStyle >= 0) { 6256fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller pattern = localeData.getTimeFormat(timeStyle); 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (dateStyle >= 0) { 6286fdc0bf198c455cbe73ecf825bd0f8f985481066Neil Fuller pattern = localeData.getDateFormat(dateStyle); 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("No date or time style specified"); 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initialize(loc); 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Initialize compiledPattern and numberFormat fields */ 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void initialize(Locale loc) { 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Verify and compile the given pattern. 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern = compile(pattern); 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* try the cache first */ 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat = cachedNumberFormatData.get(loc); 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (numberFormat == null) { /* cache miss */ 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat = NumberFormat.getIntegerInstance(loc); 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat.setGroupingUsed(false); 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* update cache */ 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cachedNumberFormatData.putIfAbsent(loc, numberFormat); 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat = (NumberFormat) numberFormat.clone(); 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeDefaultCentury(); 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void initializeCalendar(Locale loc) { 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (calendar == null) { 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert loc != null; 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The format object must be constructed using the symbols for this zone. 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // However, the calendar should use the current default TimeZone. 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If this is not contained in the locale zone strings, then the zone 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // will be formatted using generic GMT+/-H:MM nomenclature. 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calendar = Calendar.getInstance(TimeZone.getDefault(), loc); 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the compiled form of the given pattern. The syntax of 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the compiled pattern is: 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote> 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CompiledPattern: 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * EntryList 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * EntryList: 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Entry 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * EntryList Entry 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Entry: 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TagField 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TagField data 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TagField: 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tag Length 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TaggedData 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tag: 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern_char_index 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TAG_QUOTE_CHARS 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Length: 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * short_length 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * long_length 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TaggedData: 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TAG_QUOTE_ASCII_CHAR ascii_char 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </blockquote> 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * where `short_length' is an 8-bit unsigned integer between 0 and 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 254. `long_length' is a sequence of an 8-bit integer 255 and a 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32-bit signed integer value which is split into upper and lower 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16-bit fields in two char's. `pattern_char_index' is an 8-bit 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * integer between 0 and 18. `ascii_char' is an 7-bit ASCII 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * character value. `data' depends on its Tag value. 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If Length is short_length, Tag and short_length are packed in a 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * single char, as illustrated below. 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote> 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * char[0] = (Tag << 8) | short_length; 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </blockquote> 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If Length is long_length, Tag and 255 are packed in the first 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * char and a 32-bit integer, as illustrated below. 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <blockquote> 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * char[0] = (Tag << 8) | 255; 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * char[1] = (char) (long_length >>> 16); 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * char[2] = (char) (long_length & 0xffff); 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </blockquote> 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If Tag is a pattern_char_index, its Length is the number of 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern characters. For example, if the given pattern is 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "yyyy", Tag is 1 and Length is 4, followed by no data. 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If Tag is TAG_QUOTE_CHARS, its Length is the number of char's 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * following the TagField. For example, if the given pattern is 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "'o''clock'", Length is 7 followed by a char sequence of 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>o&nbs;'&nbs;c&nbs;l&nbs;o&nbs;c&nbs;k</code>. 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TAG_QUOTE_ASCII_CHAR is a special tag and has an ASCII 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * character in place of Length. For example, if the given pattern 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is "'o'", the TaggedData entry is 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>((TAG_QUOTE_ASCII_CHAR&nbs;<<&nbs;8)&nbs;|&nbs;'o')</code>. 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given pattern is null 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private char[] compile(String pattern) { 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int length = pattern.length(); 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean inQuote = false; 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuilder compiledPattern = new StringBuilder(length * 2); 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuilder tmpBuffer = null; 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int count = 0; 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lastTag = -1; 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < length; i++) { 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = pattern.charAt(i); 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '\'') { 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // '' is treated as a single quote regardless of being 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // in a quoted section. 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((i + 1) < length) { 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = pattern.charAt(i + 1); 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '\'') { 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i++; 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count != 0) { 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(lastTag, count, compiledPattern); 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastTag = -1; 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count = 0; 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inQuote) { 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmpBuffer.append(c); 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append((char)(TAG_QUOTE_ASCII_CHAR << 8 | c)); 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!inQuote) { 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count != 0) { 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(lastTag, count, compiledPattern); 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastTag = -1; 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count = 0; 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tmpBuffer == null) { 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmpBuffer = new StringBuilder(length); 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmpBuffer.setLength(0); 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inQuote = true; 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = tmpBuffer.length(); 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len == 1) { 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char ch = tmpBuffer.charAt(0); 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ch < 128) { 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append((char)(TAG_QUOTE_ASCII_CHAR << 8 | ch)); 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append((char)(TAG_QUOTE_CHARS << 8 | 1)); 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append(ch); 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(TAG_QUOTE_CHARS, len, compiledPattern); 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append(tmpBuffer); 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inQuote = false; 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inQuote) { 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tmpBuffer.append(c); 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) { 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count != 0) { 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(lastTag, count, compiledPattern); 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastTag = -1; 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count = 0; 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c < 128) { 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // In most cases, c would be a delimiter, such as ':'. 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append((char)(TAG_QUOTE_ASCII_CHAR << 8 | c)); 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Take any contiguous non-ASCII alphabet characters and 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // put them in a single TAG_QUOTE_CHARS. 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int j; 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (j = i + 1; j < length; j++) { 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char d = pattern.charAt(j); 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (d == '\'' || (d >= 'a' && d <= 'z' || d >= 'A' && d <= 'Z')) { 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append((char)(TAG_QUOTE_CHARS << 8 | (j - i))); 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (; i < j; i++) { 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.append(pattern.charAt(i)); 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i--; 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int tag; 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((tag = DateFormatSymbols.patternChars.indexOf(c)) == -1) { 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Illegal pattern character " + 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "'" + c + "'"); 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lastTag == -1 || lastTag == tag) { 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastTag = tag; 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count++; 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(lastTag, count, compiledPattern); 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastTag = tag; 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count = 1; 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inQuote) { 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Unterminated quote"); 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count != 0) { 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encode(lastTag, count, compiledPattern); 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Copy the compiled pattern to a char array 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = compiledPattern.length(); 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char[] r = new char[len]; 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern.getChars(0, len, r, 0); 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return r; 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Encodes the given tag and length and puts encoded char(s) into buffer. 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final void encode(int tag, int length, StringBuilder buffer) { 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tag == PATTERN_ISO_ZONE && length >= 4) { 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("invalid ISO 8601 format: length=" + length); 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length < 255) { 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(tag << 8 | length)); 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)((tag << 8) | 0xff)); 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(length >>> 16)); 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(length & 0xffff)); 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Initialize the fields we use to disambiguate ambiguous years. Separate 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * so we can call it from readObject(). 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void initializeDefaultCentury() { 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calendar.setTimeInMillis(System.currentTimeMillis()); 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calendar.add( Calendar.YEAR, -80 ); 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parseAmbiguousDatesAsAfter(calendar.getTime()); 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Define one-century window into which to disambiguate dates using 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * two-digit years. 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void parseAmbiguousDatesAsAfter(Date startDate) { 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultCenturyStart = startDate; 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calendar.setTime(startDate); 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultCenturyStartYear = calendar.get(Calendar.YEAR); 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the 100-year period 2-digit years will be interpreted as being in 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to begin on the date the user specifies. 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param startDate During parsing, two digit years will be placed in the range 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>startDate</code> to <code>startDate + 100 years</code>. 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #get2DigitYearStart 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.2 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void set2DigitYearStart(Date startDate) { 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parseAmbiguousDatesAsAfter(new Date(startDate.getTime())); 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the beginning date of the 100-year period 2-digit years are interpreted 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as being within. 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the start of the 100-year period into which two digit years are 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parsed 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #set2DigitYearStart 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.2 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Date get2DigitYearStart() { 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (Date) defaultCenturyStart.clone(); 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Formats the given <code>Date</code> into a date/time string and appends 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the result to the given <code>StringBuffer</code>. 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param date the date-time value to be formatted into a date-time string. 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param toAppendTo where the new date-time text is to be appended. 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pos the formatting position. On input: an alignment field, 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if desired. On output: the offsets of the alignment field. 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the formatted date-time string. 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given {@code date} is {@code null}. 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public StringBuffer format(Date date, StringBuffer toAppendTo, 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FieldPosition pos) 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.beginIndex = pos.endIndex = 0; 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return format(date, toAppendTo, pos.getFieldDelegate()); 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Called from Format after creating a FieldDelegate 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private StringBuffer format(Date date, StringBuffer toAppendTo, 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FieldDelegate delegate) { 93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Convert input date to time field list 93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calendar.setTime(date); 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean useDateFormatSymbols = useDateFormatSymbols(); 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < compiledPattern.length; ) { 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int tag = compiledPattern[i] >>> 8; 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int count = compiledPattern[i++] & 0xff; 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count == 255) { 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count = compiledPattern[i++] << 16; 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count |= compiledPattern[i++]; 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tag) { 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TAG_QUOTE_ASCII_CHAR: 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toAppendTo.append((char)count); 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TAG_QUOTE_CHARS: 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toAppendTo.append(compiledPattern, i, count); 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i += count; 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols); 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return toAppendTo; 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Formats an Object producing an <code>AttributedCharacterIterator</code>. 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You can use the returned <code>AttributedCharacterIterator</code> 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to build the resulting String, as well as to determine information 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * about the resulting String. 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Each attribute key of the AttributedCharacterIterator will be of type 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>DateFormat.Field</code>, with the corresponding attribute value 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * being the same as the attribute key. 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if obj is null. 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the Format cannot format the 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * given object, or if the Format's pattern string is invalid. 97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param obj The object to format 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return AttributedCharacterIterator describing the formatted value. 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public AttributedCharacterIterator formatToCharacterIterator(Object obj) { 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuffer sb = new StringBuffer(); 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CharacterIteratorFieldDelegate delegate = new 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CharacterIteratorFieldDelegate(); 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj instanceof Date) { 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski format((Date)obj, sb, delegate); 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (obj instanceof Number) { 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski format(new Date(((Number)obj).longValue()), sb, delegate); 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (obj == null) { 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException( 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "formatToCharacterIterator must be passed non-null object"); 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException( 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "Cannot format given Object as a Date"); 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return delegate.getIterator(sb.toString()); 100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Map index into pattern character string to Calendar field number 100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int[] PATTERN_INDEX_TO_CALENDAR_FIELD = 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.ERA, Calendar.YEAR, Calendar.MONTH, Calendar.DATE, 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.HOUR_OF_DAY, Calendar.HOUR_OF_DAY, Calendar.MINUTE, 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.SECOND, Calendar.MILLISECOND, Calendar.DAY_OF_WEEK, 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK_IN_MONTH, 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.WEEK_OF_YEAR, Calendar.WEEK_OF_MONTH, 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.AM_PM, Calendar.HOUR, Calendar.HOUR, Calendar.ZONE_OFFSET, 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.ZONE_OFFSET, 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Pseudo Calendar fields 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CalendarBuilder.WEEK_YEAR, 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CalendarBuilder.ISO_DAY_OF_WEEK, 1018b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath Calendar.ZONE_OFFSET, 1019b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath // 'L' and 'c', 1020b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath Calendar.MONTH, 1021b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath Calendar.DAY_OF_WEEK 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Map index into pattern character string to DateFormat field number 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int[] PATTERN_INDEX_TO_DATE_FORMAT_FIELD = { 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.ERA_FIELD, DateFormat.YEAR_FIELD, DateFormat.MONTH_FIELD, 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.DATE_FIELD, DateFormat.HOUR_OF_DAY1_FIELD, 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.HOUR_OF_DAY0_FIELD, DateFormat.MINUTE_FIELD, 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.SECOND_FIELD, DateFormat.MILLISECOND_FIELD, 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.DAY_OF_WEEK_FIELD, DateFormat.DAY_OF_YEAR_FIELD, 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD, DateFormat.WEEK_OF_YEAR_FIELD, 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.WEEK_OF_MONTH_FIELD, DateFormat.AM_PM_FIELD, 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.HOUR1_FIELD, DateFormat.HOUR0_FIELD, 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.TIMEZONE_FIELD, DateFormat.TIMEZONE_FIELD, 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormat.YEAR_FIELD, DateFormat.DAY_OF_WEEK_FIELD, 1036b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath DateFormat.TIMEZONE_FIELD, 1037b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath // 'L' and 'c' 1038b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath DateFormat.MONTH_FIELD, 1039b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath DateFormat.DAY_OF_WEEK_FIELD 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Maps from DecimalFormatSymbols index to Field constant 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final Field[] PATTERN_INDEX_TO_DATE_FORMAT_FIELD_ID = { 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.ERA, Field.YEAR, Field.MONTH, Field.DAY_OF_MONTH, 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.HOUR_OF_DAY1, Field.HOUR_OF_DAY0, Field.MINUTE, 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.SECOND, Field.MILLISECOND, Field.DAY_OF_WEEK, 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.DAY_OF_YEAR, Field.DAY_OF_WEEK_IN_MONTH, 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.WEEK_OF_YEAR, Field.WEEK_OF_MONTH, 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.AM_PM, Field.HOUR1, Field.HOUR0, Field.TIME_ZONE, 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.TIME_ZONE, 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field.YEAR, Field.DAY_OF_WEEK, 1052b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath Field.TIME_ZONE, 1053b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath // 'L' and 'c' 1054b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath Field.MONTH, 1055b7554f779d330037a5cf591fcc8be73db73a0384Narayan Kamath Field.DAY_OF_WEEK 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Private member function that does the real date/time formatting. 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void subFormat(int patternCharIndex, int count, 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FieldDelegate delegate, StringBuffer buffer, 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean useDateFormatSymbols) 106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int maxIntCount = Integer.MAX_VALUE; 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String current = null; 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int beginOffset = buffer.length(); 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex]; 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int value; 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (field == CalendarBuilder.WEEK_YEAR) { 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (calendar.isWeekDateSupported()) { 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = calendar.getWeekYear(); 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // use calendar year 'y' instead 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski patternCharIndex = PATTERN_YEAR; 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex]; 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = calendar.get(field); 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (field == CalendarBuilder.ISO_DAY_OF_WEEK) { 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = CalendarBuilder.toISODayOfWeek(calendar.get(Calendar.DAY_OF_WEEK)); 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = calendar.get(field); 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int style = (count >= 4) ? Calendar.LONG : Calendar.SHORT; 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!useDateFormatSymbols && field != CalendarBuilder.ISO_DAY_OF_WEEK) { 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski current = calendar.getDisplayName(field, style, locale); 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Note: zeroPaddingNumber() assumes that maxDigits is either 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 2 or maxIntCount. If we make any changes to this, 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // zeroPaddingNumber() must be fixed. 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (patternCharIndex) { 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ERA: // 'G' 109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useDateFormatSymbols) { 109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] eras = formatData.getEras(); 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value < eras.length) 110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski current = eras[value]; 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current == null) 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski current = ""; 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_WEEK_YEAR: // 'Y' 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_YEAR: // 'y' 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (calendar instanceof GregorianCalendar) { 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count != 2) 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value, count, maxIntCount, buffer); 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else // count == 2 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value, 2, 2, buffer); // clip 1996 to 96 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current == null) { 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value, style == Calendar.LONG ? 1 : count, 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maxIntCount, buffer); 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1121d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath case PATTERN_STANDALONE_MONTH: // 'L' 1122d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1123d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath current = formatMonth(count, value, maxIntCount, buffer, useDateFormatSymbols, 1124d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath true /* standalone */); 1125d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath break; 1126d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1127d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_MONTH: // 'M' 1129d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1130d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath current = formatMonth(count, value, maxIntCount, buffer, useDateFormatSymbols, 1131d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath false /* standalone */); 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 1133d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_HOUR_OF_DAY1: // 'k' 1-based. eg, 23:59 + 1 hour =>> 24:59 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current == null) { 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == 0) 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(calendar.getMaximum(Calendar.HOUR_OF_DAY)+1, 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count, maxIntCount, buffer); 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value, count, maxIntCount, buffer); 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1145d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath case PATTERN_STANDALONE_DAY_OF_WEEK: // 'c' 1146d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1147d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath current = formatWeekday(count, value, useDateFormatSymbols, true /* standalone */); 1148d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath break; 1149d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1150d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_DAY_OF_WEEK: // 'E' 1152d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1153d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath current = formatWeekday(count, value, useDateFormatSymbols, false /* standalone */); 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 1155d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_AM_PM: // 'a' 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useDateFormatSymbols) { 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] ampm = formatData.getAmPmStrings(); 116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski current = ampm[value]; 116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_HOUR1: // 'h' 1-based. eg, 11PM + 1 hour =>> 12 AM 116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current == null) { 116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == 0) 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(calendar.getLeastMaximum(Calendar.HOUR)+1, 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count, maxIntCount, buffer); 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value, count, maxIntCount, buffer); 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ZONE_NAME: // 'z' 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current == null) { 11769c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski TimeZone tz = calendar.getTimeZone(); 11779c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski boolean daylight = (calendar.get(Calendar.DST_OFFSET) != 0); 11789c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski int tzstyle = count < 4 ? TimeZone.SHORT : TimeZone.LONG; 1179cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer String zoneString; 1180cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer if (formatData.isZoneStringsSet) { 1181cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer zoneString = TimeZoneNames.getDisplayName( 1182cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer formatData.getZoneStringsWrapper(), tz.getID(), daylight, tzstyle); 1183cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer } else { 1184cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer zoneString = tz.getDisplayName(daylight, tzstyle, formatData.locale); 1185cdde6627c3b5fe67e086043cb789e88110a38028Joachim Sauer } 11869c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski if (zoneString != null) { 11879c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski buffer.append(zoneString); 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 11899c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski int offsetMillis = calendar.get(Calendar.ZONE_OFFSET) + 11909c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski calendar.get(Calendar.DST_OFFSET); 11919c853c5b9ebbb0ef60a013ae10ee411d70dfa832Piotr Jastrzebski buffer.append(TimeZone.createGmtOffsetString(true, true, offsetMillis)); 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ZONE_VALUE: // 'Z' ("-/+hhmm" form) 1197d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1198d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath value = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); 1199d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final boolean includeSeparator = (count >= 4); 1200d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final boolean includeGmt = (count == 4); 1201d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath buffer.append(TimeZone.createGmtOffsetString(includeGmt, includeSeparator, value)); 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 1204d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ISO_ZONE: // 'X' 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = calendar.get(Calendar.ZONE_OFFSET) 120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + calendar.get(Calendar.DST_OFFSET); 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == 0) { 121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append('Z'); 121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value /= 60000; 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value >= 0) { 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append('+'); 121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append('-'); 122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = -value; 122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CalendarUtils.sprintf0d(buffer, value / 60, 2); 122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count == 1) { 122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count == 3) { 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append(':'); 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CalendarUtils.sprintf0d(buffer, value % 60, 2); 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 1233afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath case PATTERN_MILLISECOND: // 'S' 1234afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // Fractional seconds must be treated specially. We must always convert the parsed 1235afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // value into a fractional second [0, 1) and then widen it out to the appropriate 1236afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // formatted size. For example, an initial value of 789 will be converted 1237afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // 0.789 and then become ".7" (S) or ".78" (SS) or "0.789" (SSS) or "0.7890" (SSSS) 1238afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // in the resulting formatted output. 1239afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath if (current == null) { 1240afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath value = (int) (((double) value / 1000) * Math.pow(10, count)); 1241afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath zeroPaddingNumber(value, count, count, buffer); 1242afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath } 1243afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath break; 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_DAY_OF_MONTH: // 'd' 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_HOUR_OF_DAY0: // 'H' 0-based. eg, 23:59 + 1 hour =>> 00:59 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_MINUTE: // 'm' 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_SECOND: // 's' 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_DAY_OF_YEAR: // 'D' 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_DAY_OF_WEEK_IN_MONTH: // 'F' 125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_WEEK_OF_YEAR: // 'w' 125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_WEEK_OF_MONTH: // 'W' 125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_HOUR0: // 'K' eg, 11PM + 1 hour =>> 0 AM 125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_ISO_DAY_OF_WEEK: // 'u' pseudo field, Monday = 1, ..., Sunday = 7 125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current == null) { 125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value, count, maxIntCount, buffer); 125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // switch (patternCharIndex) 126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (current != null) { 126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append(current); 126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int fieldID = PATTERN_INDEX_TO_DATE_FORMAT_FIELD[patternCharIndex]; 126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Field f = PATTERN_INDEX_TO_DATE_FORMAT_FIELD_ID[patternCharIndex]; 126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski delegate.formatted(fieldID, f, f, beginOffset, buffer.length(), buffer); 127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1272d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath private String formatWeekday(int count, int value, boolean useDateFormatSymbols, 1273d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath boolean standalone) { 1274d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (useDateFormatSymbols) { 1275d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final String[] weekdays; 1276d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (count == 4) { 1277d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath weekdays = standalone ? formatData.getStandAloneWeekdays() : formatData.getWeekdays(); 1278d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else if (count == 5) { 1279d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath weekdays = 1280d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath standalone ? formatData.getTinyStandAloneWeekdays() : formatData.getTinyWeekdays(); 1281d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1282d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else { // count < 4, use abbreviated form if exists 1283d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath weekdays = standalone ? formatData.getShortStandAloneWeekdays() : formatData.getShortWeekdays(); 1284d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1285d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1286d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return weekdays[value]; 1287d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1288d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1289d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return null; 1290d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1291d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1292d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath private String formatMonth(int count, int value, int maxIntCount, StringBuffer buffer, 1293d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath boolean useDateFormatSymbols, boolean standalone) { 1294d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath String current = null; 1295d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (useDateFormatSymbols) { 1296d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final String[] months; 1297d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (count == 4) { 1298d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath months = standalone ? formatData.getStandAloneMonths() : formatData.getMonths(); 1299d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else if (count == 5) { 1300d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath months = standalone ? formatData.getTinyStandAloneMonths() : formatData.getTinyMonths(); 1301d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else if (count == 3) { 1302d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath months = standalone ? formatData.getShortStandAloneMonths() : formatData.getShortMonths(); 1303d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else { 1304d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath months = null; 1305d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1306d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1307d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (months != null) { 1308d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath current = months[value]; 1309d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1310d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else { 1311d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (count < 3) { 1312d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath current = null; 1313d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1314d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1315d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1316d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (current == null) { 1317d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath zeroPaddingNumber(value+1, count, maxIntCount, buffer); 1318d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1319d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1320d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return current; 1321d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1322d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Formats a number with the specified minimum and maximum number of digits. 132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final void zeroPaddingNumber(int value, int minDigits, int maxDigits, StringBuffer buffer) 132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Optimization for 1, 2 and 4 digit numbers. This should 132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // cover most cases of formatting date/time related items. 133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Note: This optimization code assumes that maxDigits is 133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // either 2 or Integer.MAX_VALUE (maxIntCount in format()). 133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (zeroDigit == 0) { 133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroDigit = ((DecimalFormat)numberFormat).getDecimalFormatSymbols().getZeroDigit(); 133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value >= 0) { 133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value < 100 && minDigits >= 1 && minDigits <= 2) { 133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value < 10) { 133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (minDigits == 2) { 134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append(zeroDigit); 134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value)); 134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value / 10)); 134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value % 10)); 134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (value >= 1000 && value < 10000) { 134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (minDigits == 4) { 135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value / 1000)); 135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value %= 1000; 135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value / 100)); 135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value %= 100; 135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value / 10)); 135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buffer.append((char)(zeroDigit + value % 10)); 135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (minDigits == 2 && maxDigits == 2) { 135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zeroPaddingNumber(value % 100, 2, 2, buffer); 136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat.setMinimumIntegerDigits(minDigits); 136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat.setMaximumIntegerDigits(maxDigits); 136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numberFormat.format((long)value, buffer, DontCareFieldPosition.INSTANCE); 137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Parses text from a string to produce a <code>Date</code>. 137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The method attempts to parse text starting at the index given by 137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>pos</code>. 137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If parsing succeeds, then the index of <code>pos</code> is updated 137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the index after the last character used (parsing does not necessarily 138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * use all characters up to the end of the string), and the parsed 138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * date is returned. The updated <code>pos</code> can be used to 138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * indicate the starting point for the next call to this method. 138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If an error occurs, then the index of <code>pos</code> is not 138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * changed, the error index of <code>pos</code> is set to the index of 138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the character where the error occurred, and null is returned. 138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>This parsing operation uses the {@link DateFormat#calendar 138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calendar} to produce a {@code Date}. All of the {@code 138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calendar}'s date-time fields are {@linkplain Calendar#clear() 139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cleared} before parsing, and the {@code calendar}'s default 139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * values of the date-time fields are used for any missing 139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * date-time information. For example, the year value of the 139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parsed {@code Date} is 1970 with {@link GregorianCalendar} if 139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * no year value is given from the parsing operation. The {@code 139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TimeZone} value may be overwritten, depending on the given 139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern and the time zone value in {@code text}. Any {@code 139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TimeZone} value that has previously been set by a call to 139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #setTimeZone(java.util.TimeZone) setTimeZone} may need 139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to be restored for further operations. 140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param text A <code>String</code>, part of which should be parsed. 140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pos A <code>ParsePosition</code> object with index and error 140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * index information as described above. 140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return A <code>Date</code> parsed from the string. In case of 140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * error, returns null. 140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if <code>text</code> or <code>pos</code> is null. 140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 140808db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath public Date parse(String text, ParsePosition pos) { 140908db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath // Make sure the timezone associated with this dateformat instance (set via 141008db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath // {@code setTimeZone} isn't change as a side-effect of parsing a date. 141108db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath final TimeZone tz = getTimeZone(); 141208db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath try { 141308db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath return parseInternal(text, pos); 141408db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath } finally { 141508db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath setTimeZone(tz); 141608db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath } 141708db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath } 141808db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath 141908db36e9a34896135e8b0883f65bde5b86ee90e6Narayan Kamath private Date parseInternal(String text, ParsePosition pos) 142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkNegativeNumberExpression(); 142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int start = pos.index; 142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldStart = start; 142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int textLength = text.length(); 142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean[] ambiguousYear = {false}; 142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CalendarBuilder calb = new CalendarBuilder(); 143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < compiledPattern.length; ) { 143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int tag = compiledPattern[i] >>> 8; 143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int count = compiledPattern[i++] & 0xff; 143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count == 255) { 143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count = compiledPattern[i++] << 16; 143651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count |= compiledPattern[i++]; 143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (tag) { 144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TAG_QUOTE_ASCII_CHAR: 144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (start >= textLength || text.charAt(start) != (char)count) { 144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = oldStart; 144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.errorIndex = start; 144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 144551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start++; 144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case TAG_QUOTE_CHARS: 145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (count-- > 0) { 145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (start >= textLength || text.charAt(start) != compiledPattern[i++]) { 145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = oldStart; 145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.errorIndex = start; 145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start++; 145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Peek the next pattern to determine if we need to 146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // obey the number of pattern letters for 146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // parsing. It's required when parsing contiguous 146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // digit text (e.g., "20010704") with a pattern which 146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // has no delimiters between fields, like "yyyyMMdd". 146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean obeyCount = false; 146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 146851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // In Arabic, a minus sign for a negative number is put after 146951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the number. Even in another locale, a minus sign can be 147051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // put after a number using DateFormat.setNumberFormat(). 147151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If both the minus sign and the field-delimiter are '-', 147251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // subParse() needs to determine whether a '-' after a number 147351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // in the given text is a delimiter or is a minus sign for the 147451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // preceding number. We give subParse() a clue based on the 147551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // information in compiledPattern. 147651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean useFollowingMinusSignAsDelimiter = false; 147751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 147851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i < compiledPattern.length) { 147951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nextTag = compiledPattern[i] >>> 8; 148051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(nextTag == TAG_QUOTE_ASCII_CHAR || 148151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nextTag == TAG_QUOTE_CHARS)) { 148251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski obeyCount = true; 148351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 148451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 148551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasFollowingMinusSign && 148651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (nextTag == TAG_QUOTE_ASCII_CHAR || 148751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nextTag == TAG_QUOTE_CHARS)) { 148851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c; 148951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nextTag == TAG_QUOTE_ASCII_CHAR) { 149051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = compiledPattern[i] & 0xff; 149151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 149251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = compiledPattern[i+1]; 149351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 149551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == minusSign) { 149651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useFollowingMinusSignAsDelimiter = true; 149751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 149951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 150051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start = subParse(text, start, tag, count, obeyCount, 150151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ambiguousYear, pos, 150251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useFollowingMinusSignAsDelimiter, calb); 150351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (start < 0) { 150451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = oldStart; 150551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 150651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 150751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 150851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 150951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // At this point the fields of Calendar have been set. Calendar 151151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // will fill in default values for missing fields when the time 151251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // is computed. 151351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = start; 151551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 151651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date parsedDate; 151751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 151851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parsedDate = calb.establish(calendar).getTime(); 151951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the year value is ambiguous, 152051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // then the two-digit year == the default start year 152151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ambiguousYear[0]) { 152251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parsedDate.before(defaultCenturyStart)) { 152351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parsedDate = calb.addYear(100).establish(calendar).getTime(); 152451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 152751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // An IllegalArgumentException will be thrown by Calendar.getTime() 152851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if any fields are out of range, e.g., MONTH == 17. 152951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski catch (IllegalArgumentException e) { 153051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.errorIndex = start; 153151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = oldStart; 153251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 153351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 153451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 153551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return parsedDate; 153651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 153751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 153851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 153951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Private code-size reduction function used by subParse. 154051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param text the time text being parsed. 154151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param start where to start parsing. 154251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param field the date field being parsed. 154351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param data the string array to parsed. 154451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the new start position if matching succeeded; a negative number 154551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * indicating matching failure, otherwise. 154651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 154751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int matchString(String text, int start, int field, String[] data, CalendarBuilder calb) 154851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 154951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = 0; 155051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int count = data.length; 155151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 155251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (field == Calendar.DAY_OF_WEEK) i = 1; 155351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 155451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // There may be multiple strings in the data[] array which begin with 155551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech). 155651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // We keep track of the longest match, and return that. Note that this 155751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // unfortunately requires us to test all array elements. 155851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int bestMatchLength = 0, bestMatch = -1; 155951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (; i<count; ++i) 156051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 156151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int length = data[i].length(); 156251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Always compare if we have no match yet; otherwise only compare 156351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // against potentially better matches (longer strings). 156451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (length > bestMatchLength && 156551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski text.regionMatches(true, start, data[i], 0, length)) 156651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 156751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bestMatch = i; 156851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bestMatchLength = length; 156951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 157000617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath 157100617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath // When the input option ends with a period (usually an abbreviated form), attempt 157200617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath // to match all chars up to that period. 157300617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath if ((data[i].charAt(length - 1) == '.') && 157400617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath ((length - 1) > bestMatchLength) && 157500617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath text.regionMatches(true, start, data[i], 0, length - 1)) { 157600617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath bestMatch = i; 157700617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath bestMatchLength = (length - 1); 157800617c74e1f95fbe088f078341d607132575b0d6Narayan Kamath } 157951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 158051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bestMatch >= 0) 158151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 158251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(field, bestMatch); 158351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return start + bestMatchLength; 158451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 158551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -start; 158651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 158751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 158851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 158951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Performs the same thing as matchString(String, int, int, 159051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * String[]). This method takes a Map<String, Integer> instead of 159151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * String[]. 159251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 159351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int matchString(String text, int start, int field, 159451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<String,Integer> data, CalendarBuilder calb) { 159551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (data != null) { 159651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String bestMatch = null; 159751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 159851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (String name : data.keySet()) { 159951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int length = name.length(); 160051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bestMatch == null || length > bestMatch.length()) { 160151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (text.regionMatches(true, start, name, 0, length)) { 160251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bestMatch = name; 160351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 160651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 160751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bestMatch != null) { 160851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(field, data.get(bestMatch)); 160951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return start + bestMatch.length(); 161051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 161151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 161251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -start; 161351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 161451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 161551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int matchZoneString(String text, int start, String[] zoneNames) { 161651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 1; i <= 4; ++i) { 161751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Checking long and short zones [1 & 2], 161851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // and long and short daylight [3 & 4]. 161951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String zoneName = zoneNames[i]; 162051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (text.regionMatches(true, start, 162151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zoneName, 0, zoneName.length())) { 162251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return i; 162351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 162651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 162751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 162851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean matchDSTString(String text, int start, int zoneIndex, int standardIndex, 162951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[][] zoneStrings) { 163051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = standardIndex + 2; 163151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String zoneName = zoneStrings[zoneIndex][index]; 163251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (text.regionMatches(true, start, 163351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zoneName, 0, zoneName.length())) { 163451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 163551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 163651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 163751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 163851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 163951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 164051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * find time zone 'text' matched zoneStrings and set to internal 164151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calendar. 164251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 164351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int subParseZoneString(String text, int start, CalendarBuilder calb) { 164451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean useSameName = false; // true if standard and daylight time use the same abbreviation. 164551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski TimeZone currentTimeZone = getTimeZone(); 164651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 164751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // At this point, check for named time zones by looking through 164851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the locale data from the TimeZoneNames strings. 164951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Want to be able to parse both short and long forms. 165051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int zoneIndex = formatData.getZoneIndex(currentTimeZone.getID()); 165151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski TimeZone tz = null; 165251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[][] zoneStrings = formatData.getZoneStringsWrapper(); 165351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] zoneNames = null; 165451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nameIndex = 0; 165551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (zoneIndex != -1) { 165651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zoneNames = zoneStrings[zoneIndex]; 165751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((nameIndex = matchZoneString(text, start, zoneNames)) > 0) { 165851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nameIndex <= 2) { 165951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Check if the standard name (abbr) and the daylight name are the same. 166051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useSameName = zoneNames[nameIndex].equalsIgnoreCase(zoneNames[nameIndex + 2]); 166151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 166251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tz = TimeZone.getTimeZone(zoneNames[0]); 166351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 166451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 166551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tz == null) { 166651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zoneIndex = formatData.getZoneIndex(TimeZone.getDefault().getID()); 166751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (zoneIndex != -1) { 166851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zoneNames = zoneStrings[zoneIndex]; 166951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((nameIndex = matchZoneString(text, start, zoneNames)) > 0) { 167051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nameIndex <= 2) { 167151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useSameName = zoneNames[nameIndex].equalsIgnoreCase(zoneNames[nameIndex + 2]); 167251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tz = TimeZone.getTimeZone(zoneNames[0]); 167451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 167751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 167851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tz == null) { 167951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = zoneStrings.length; 168051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < len; i++) { 168151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski zoneNames = zoneStrings[i]; 168251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((nameIndex = matchZoneString(text, start, zoneNames)) > 0) { 168351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nameIndex <= 2) { 168451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useSameName = zoneNames[nameIndex].equalsIgnoreCase(zoneNames[nameIndex + 2]); 168551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 168651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tz = TimeZone.getTimeZone(zoneNames[0]); 168751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 168851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 168951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 169051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 169151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tz != null) { // Matched any ? 169251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!tz.equals(currentTimeZone)) { 169351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setTimeZone(tz); 169451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 169551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the time zone matched uses the same name 169651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // (abbreviation) for both standard and daylight time, 169751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // let the time zone in the Calendar decide which one. 169851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 169951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Also if tz.getDSTSaving() returns 0 for DST, use tz to 170051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // determine the local time. (6645292) 170151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dstAmount = (nameIndex >= 3) ? tz.getDSTSavings() : 0; 170251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(useSameName || (nameIndex >= 3 && dstAmount == 0))) { 170351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.clear(Calendar.ZONE_OFFSET).set(Calendar.DST_OFFSET, dstAmount); 170451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 170551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (start + zoneNames[nameIndex].length()); 170651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 170751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 170851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 170951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 171051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 171151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Parses numeric forms of time zone offset, such as "hh:mm", and 171251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sets calb to the parsed value. 171351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 171451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param text the text to be parsed 171551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param start the character position to start parsing 171651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param sign 1: positive; -1: negative 171751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's 1718d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath * @param colonRequired true - colon required between hh and mm; false - no colon required 171951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param calb a CalendarBuilder in which the parsed value is stored 172051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return updated parsed position, or its negative value to indicate a parsing error 172151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 172251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int subParseNumericZone(String text, int start, int sign, int count, 1723d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath boolean colonRequired, CalendarBuilder calb) { 172451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = start; 172551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 172651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parse: 172751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 172851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = text.charAt(index++); 172951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Parse hh 173051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int hours; 173151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isDigit(c)) { 173251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parse; 173351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 173451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hours = c - '0'; 173551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = text.charAt(index++); 173651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isDigit(c)) { 173751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hours = hours * 10 + (c - '0'); 173851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 173951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski --index; 174051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 174151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hours > 23) { 174251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parse; 174351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 174451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int minutes = 0; 174551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count != 1) { 174651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Proceed with parsing mm 174751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = text.charAt(index++); 1748d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath if (c == ':') { 174951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = text.charAt(index++); 1750d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath } else if (colonRequired) { 1751d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath break parse; 175251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 175351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isDigit(c)) { 175451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parse; 175551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 175651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski minutes = c - '0'; 175751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = text.charAt(index++); 175851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isDigit(c)) { 175951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parse; 176051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 176151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski minutes = minutes * 10 + (c - '0'); 176251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (minutes > 59) { 176351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parse; 176451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 176551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 176651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski minutes += hours * 60; 176751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(Calendar.ZONE_OFFSET, minutes * MILLIS_PER_MINUTE * sign) 176851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .set(Calendar.DST_OFFSET, 0); 176951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 177051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IndexOutOfBoundsException e) { 177151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 177251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 1 - index; // -(index - 1) 177351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 177451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isDigit(char c) { 177651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return c >= '0' && c <= '9'; 177751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 177851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 178051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Private member function that converts the parsed date strings into 178151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * timeFields. Returns -start (for ParsePosition) if failed. 178251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param text the time text to be parsed. 178351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param start where to start parsing. 178451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ch the pattern character for the date field text to be parsed. 178551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param count the count of a pattern character. 178651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param obeyCount if true, then the next field directly abuts this one, 178751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and we should use the count to know when to stop parsing. 178851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ambiguousYear return parameter; upon return, if ambiguousYear[0] 178951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is true, then a two-digit year was parsed and may need to be readjusted. 179051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param origPos origPos.errorIndex is used to return an error index 179151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * at which a parse error occurred, if matching failure occurs. 179251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the new start position if matching succeeded; -1 indicating 179351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * matching failure, otherwise. In case matching failure occurred, 179451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an error index is set to origPos.errorIndex. 179551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 179651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int subParse(String text, int start, int patternCharIndex, int count, 179751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean obeyCount, boolean[] ambiguousYear, 179851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ParsePosition origPos, 179951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean useFollowingMinusSignAsDelimiter, CalendarBuilder calb) { 180051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Number number = null; 180151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int value = 0; 180251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ParsePosition pos = new ParsePosition(0); 180351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = start; 180451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (patternCharIndex == PATTERN_WEEK_YEAR && !calendar.isWeekDateSupported()) { 180551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // use calendar year 'y' instead 180651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski patternCharIndex = PATTERN_YEAR; 180751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 180851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex]; 180951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 181051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If there are any spaces here, skip over them. If we hit the end 181151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // of the string, then fail. 181251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 181351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos.index >= text.length()) { 181451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski origPos.errorIndex = start; 181551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 181651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 181751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = text.charAt(pos.index); 181851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c != ' ' && c != '\t') break; 181951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ++pos.index; 182051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 182151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 182251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parsing: 182351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 182451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // We handle a few special cases here where we need to parse 182551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // a number value. We handle further, more generic cases below. We need 182651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to handle some of them here because some fields require extra processing on 182751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the parsed value. 182851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (patternCharIndex == PATTERN_HOUR_OF_DAY1 || 182951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski patternCharIndex == PATTERN_HOUR1 || 183051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (patternCharIndex == PATTERN_MONTH && count <= 2) || 183151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski patternCharIndex == PATTERN_YEAR || 183251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski patternCharIndex == PATTERN_WEEK_YEAR) { 183351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // It would be good to unify this with the obeyCount logic below, 183451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // but that's going to be difficult. 183551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obeyCount) { 183651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((start+count) > text.length()) { 183751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 183851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 183951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski number = numberFormat.parse(text.substring(0, start+count), pos); 184051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 184151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski number = numberFormat.parse(text, pos); 184251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 184351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (number == null) { 184451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (patternCharIndex != PATTERN_YEAR || calendar instanceof GregorianCalendar) { 184551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 184651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 184751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 184851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = number.intValue(); 184951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 185051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useFollowingMinusSignAsDelimiter && (value < 0) && 185151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (((pos.index < text.length()) && 185251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (text.charAt(pos.index) != minusSign)) || 185351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((pos.index == text.length()) && 185451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (text.charAt(pos.index-1) == minusSign)))) { 185551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = -value; 185651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index--; 185751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 185851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 185951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 186051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 186151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean useDateFormatSymbols = useDateFormatSymbols(); 186251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 186351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index; 186451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (patternCharIndex) { 186551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ERA: // 'G' 186651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useDateFormatSymbols) { 186751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((index = matchString(text, start, Calendar.ERA, formatData.getEras(), calb)) > 0) { 186851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 186951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 187051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 187151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<String, Integer> map = calendar.getDisplayNames(field, 187251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Calendar.ALL_STYLES, 187351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski locale); 187451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((index = matchString(text, start, field, map, calb)) > 0) { 187551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 187651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 187751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 187851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 187951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 188051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_WEEK_YEAR: // 'Y' 188151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_YEAR: // 'y' 188251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(calendar instanceof GregorianCalendar)) { 188351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // calendar might have text representations for year values, 188451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // such as "\u5143" in JapaneseImperialCalendar. 188551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int style = (count >= 4) ? Calendar.LONG : Calendar.SHORT; 188651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<String, Integer> map = calendar.getDisplayNames(field, style, locale); 188751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (map != null) { 188851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((index = matchString(text, start, field, map, calb)) > 0) { 188951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 189051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 189151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 189251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(field, value); 189351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos.index; 189451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 189551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 189651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If there are 3 or more YEAR pattern characters, this indicates 189751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that the year value is to be treated literally, without any 189851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // two-digit year adjustments (e.g., from "01" to 2001). Otherwise 189951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // we made adjustments to place the 2-digit year in the proper 190051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // century, for parsed strings from "00" to "99". Any other string 190151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // is treated literally: "2250", "-1", "1", "002". 190251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (count <= 2 && (pos.index - start) == 2 190351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && Character.isDigit(text.charAt(start)) 190451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && Character.isDigit(text.charAt(start+1))) { 190551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Assume for example that the defaultCenturyStart is 6/18/1903. 190651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This means that two-digit years will be forced into the range 190751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02 190851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // correspond to 2000, 2001, and 2002. Years 04, 05, etc. correspond 190951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to 1904, 1905, etc. If the year is 03, then it is 2003 if the 191051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // other fields specify a date before 6/18, or 1903 if they specify a 191151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // date afterwards. As a result, 03 is an ambiguous year. All other 191251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // two-digit years are unambiguous. 191351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ambiguousTwoDigitYear = defaultCenturyStartYear % 100; 191451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ambiguousYear[0] = value == ambiguousTwoDigitYear; 191551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value += (defaultCenturyStartYear/100)*100 + 191651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (value < ambiguousTwoDigitYear ? 100 : 0); 191751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 191851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(field, value); 191951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos.index; 192051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1921d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath case PATTERN_STANDALONE_MONTH: // 'L'. 1922d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1923d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final int idx = parseMonth(text, count, value, start, field, pos, 1924d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath useDateFormatSymbols, true /* isStandalone */, calb); 1925d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (idx > 0) { 1926d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return idx; 192751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1928d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath break parsing; 1929d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 193051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1931d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath case PATTERN_MONTH: // 'M' 1932d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1933d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final int idx = parseMonth(text, count, value, start, field, pos, 1934d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath useDateFormatSymbols, false /* isStandalone */, calb); 1935d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (idx > 0) { 1936d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return idx; 193751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1938d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 193951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 1940d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 194151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 194251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_HOUR_OF_DAY1: // 'k' 1-based. eg, 23:59 + 1 hour =>> 24:59 194351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isLenient()) { 194451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Validate the hour value in non-lenient 194551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value < 1 || value > 24) { 194651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 194751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 194851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 194951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // [We computed 'value' above.] 195051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == calendar.getMaximum(Calendar.HOUR_OF_DAY)+1) 195151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = 0; 195251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(Calendar.HOUR_OF_DAY, value); 195351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos.index; 195451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1955d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath case PATTERN_STANDALONE_DAY_OF_WEEK: // 'c' 1956d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1957d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final int idx = parseWeekday(text, start, field, useDateFormatSymbols, 195882c413526cc241290cc69170f28cac5213cf74edJoachim Sauer true /* standalone */, calb); 1959d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (idx > 0) { 1960d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return idx; 1961d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1962d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 1963d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath break parsing; 1964d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1965d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 196651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_DAY_OF_WEEK: // 'E' 1967d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 1968d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath final int idx = parseWeekday(text, start, field, useDateFormatSymbols, 1969d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath false /* standalone */, calb); 1970d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (idx > 0) { 1971d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return idx; 197251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1973d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 197451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 1975d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 1976d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 197751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 197851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_AM_PM: // 'a' 197951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useDateFormatSymbols) { 198051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((index = matchString(text, start, Calendar.AM_PM, 198151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski formatData.getAmPmStrings(), calb)) > 0) { 198251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 198351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 198451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 198551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<String,Integer> map = calendar.getDisplayNames(field, Calendar.ALL_STYLES, locale); 198651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((index = matchString(text, start, field, map, calb)) > 0) { 198751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return index; 198851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 198951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 199051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 199151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 199251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_HOUR1: // 'h' 1-based. eg, 11PM + 1 hour =>> 12 AM 199351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isLenient()) { 199451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Validate the hour value in non-lenient 199551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value < 1 || value > 12) { 199651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 199751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 199851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 199951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // [We computed 'value' above.] 200051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == calendar.getLeastMaximum(Calendar.HOUR)+1) 200151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = 0; 200251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(Calendar.HOUR, value); 200351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos.index; 200451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 200551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ZONE_NAME: // 'z' 200651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ZONE_VALUE: // 'Z' 200751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 200851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sign = 0; 200951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 201051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = text.charAt(pos.index); 201151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '+') { 201251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign = 1; 201351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (c == '-') { 201451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign = -1; 201551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 201651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sign == 0) { 201751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Try parsing a custom time zone "GMT+hh:mm" or "GMT". 201851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((c == 'G' || c == 'g') 201951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && (text.length() - start) >= GMT.length() 202051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && text.regionMatches(true, start, GMT, 0, GMT.length())) { 202151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = start + GMT.length(); 202251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 202351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((text.length() - pos.index) > 0) { 202451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = text.charAt(pos.index); 202551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '+') { 202651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign = 1; 202751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (c == '-') { 202851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign = -1; 202951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 203051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 203151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 203251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sign == 0) { /* "GMT" without offset */ 203351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(Calendar.ZONE_OFFSET, 0) 203451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .set(Calendar.DST_OFFSET, 0); 203551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos.index; 203651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 203751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2038d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath // Parse the rest as "hh[:]?mm" 2039d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath int i = subParseNumericZone(text, ++pos.index, sign, 0, 2040d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath false, calb); 204151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i > 0) { 204251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return i; 204351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 204451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = -i; 204551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 204651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Try parsing the text as a time zone 204751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // name or abbreviation. 204851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = subParseZoneString(text, pos.index, calb); 204951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i > 0) { 205051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return i; 205151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 205251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = -i; 205351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 205451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 2055d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath // Parse the rest as "hh[:]?mm" (RFC 822) 2056d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath int i = subParseNumericZone(text, ++pos.index, sign, 0, 2057d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath false, calb); 205851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i > 0) { 205951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return i; 206051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 206151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = -i; 206251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 206351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IndexOutOfBoundsException e) { 206451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 206551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 206651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 206751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 206851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case PATTERN_ISO_ZONE: // 'X' 206951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 207051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((text.length() - pos.index) <= 0) { 207151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 207251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 207351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 207451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sign = 0; 207551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = text.charAt(pos.index); 207651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == 'Z') { 207751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0); 207851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ++pos.index; 207951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 208051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 208151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // parse text as "+/-hh[[:]mm]" based on count 208251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '+') { 208351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign = 1; 208451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (c == '-') { 208551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sign = -1; 208651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 208751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ++pos.index; 208851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 208951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 2090d06c9ff1e64308978a6db2135d744613e396b65eNarayan Kamath int i = subParseNumericZone(text, ++pos.index, sign, count, (count == 3), calb); 209151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i > 0) { 209251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return i; 209351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 209451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index = -i; 209551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 209651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 209751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 209851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 209951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_DAY_OF_MONTH: // 'd' 210051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_HOUR_OF_DAY0: // 'H' 0-based. eg, 23:59 + 1 hour =>> 00:59 210151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_MINUTE: // 'm' 210251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_SECOND: // 's' 210351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_MILLISECOND: // 'S' 210451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_DAY_OF_YEAR: // 'D' 210551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_DAY_OF_WEEK_IN_MONTH: // 'F' 210651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_WEEK_OF_YEAR: // 'w' 210751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_WEEK_OF_MONTH: // 'W' 210851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_HOUR0: // 'K' 0-based. eg, 11PM + 1 hour =>> 0 AM 210951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // case PATTERN_ISO_DAY_OF_WEEK: // 'u' (pseudo field); 211051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 211151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Handle "generic" fields 2112afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath int parseStart = pos.getIndex(); 211351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obeyCount) { 211451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((start+count) > text.length()) { 211551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 211651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 211751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski number = numberFormat.parse(text.substring(0, start+count), pos); 211851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 211951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski number = numberFormat.parse(text, pos); 212051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 212151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (number != null) { 2122afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath if (patternCharIndex == PATTERN_MILLISECOND) { 2123afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // Fractional seconds must be treated specially. We must always 2124afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // normalize them to their fractional second value [0, 1) before we attempt 2125afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // to parse them. 2126afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // 2127afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // Case 1: 11.78 seconds is 11 seconds and 780 (not 78) milliseconds. 2128afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath // Case 2: 11.7890567 seconds is 11 seconds and 789 (not 7890567) milliseconds. 2129afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath double doubleValue = number.doubleValue(); 2130afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath int width = pos.getIndex() - parseStart; 2131afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath final double divisor = Math.pow(10, width); 2132afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath value = (int) ((doubleValue / divisor) * 1000); 2133afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath } else { 2134afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath value = number.intValue(); 2135afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath } 213651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 213751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useFollowingMinusSignAsDelimiter && (value < 0) && 2138afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath (((pos.index < text.length()) && 2139afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath (text.charAt(pos.index) != minusSign)) || 2140afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath ((pos.index == text.length()) && 2141afe86efb5d4b237c50df82b7dcb581d4d75b1132Narayan Kamath (text.charAt(pos.index - 1) == minusSign)))) { 214251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = -value; 214351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.index--; 214451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 214551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 214651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski calb.set(field, value); 214751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pos.index; 214851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 214951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break parsing; 215051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 215151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 215251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 215351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Parsing failed. 215451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski origPos.errorIndex = pos.index; 215551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 215651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 215751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2158d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath private int parseMonth(String text, int count, int value, int start, 2159d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath int field, ParsePosition pos, boolean useDateFormatSymbols, 2160d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath boolean standalone, 2161d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath CalendarBuilder out) { 2162d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (count <= 2) // i.e., M or MM. 2163d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath { 2164d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // Don't want to parse the month if it is a string 2165d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // while pattern uses numeric style: M or MM. 2166d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // [We computed 'value' above.] 2167d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath out.set(Calendar.MONTH, value - 1); 2168d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return pos.index; 2169d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2170d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 2171d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath int index = -1; 2172d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (useDateFormatSymbols) { 2173d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // count >= 3 // i.e., MMM or MMMM 2174d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // Want to be able to parse both short and long forms. 2175d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // Try count == 4 first: 2176d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if ((index = matchString( 2177d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath text, start, Calendar.MONTH, 2178d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath standalone ? formatData.getStandAloneMonths() : formatData.getMonths(), 2179d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath out)) > 0) { 2180d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2181d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2182d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // count == 4 failed, now try count == 3 2183d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if ((index = matchString( 2184d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath text, start, Calendar.MONTH, 2185d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath standalone ? formatData.getShortStandAloneMonths() : formatData.getShortMonths(), 2186d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath out)) > 0) { 2187d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2188d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2189d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else { 2190d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath Map<String, Integer> map = calendar.getDisplayNames(field, 2191d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath Calendar.ALL_STYLES, 2192d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath locale); 2193d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if ((index = matchString(text, start, field, map, out)) > 0) { 2194d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2195d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2196d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2197d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 2198d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2199d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2200d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 2201d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath private int parseWeekday(String text, int start, int field, boolean useDateFormatSymbols, 2202d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath boolean standalone, CalendarBuilder out) { 2203d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath int index = -1; 2204d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if (useDateFormatSymbols) { 2205d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // Want to be able to parse both short and long forms. 2206d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // Try count == 4 (DDDD) first: 2207d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if ((index=matchString( 2208d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath text, start, Calendar.DAY_OF_WEEK, 2209d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath standalone ? formatData.getStandAloneWeekdays() : formatData.getWeekdays(), 2210d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath out)) > 0) { 2211d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2212d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2213d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 2214d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath // DDDD failed, now try DDD 2215d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if ((index = matchString( 2216d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath text, start, Calendar.DAY_OF_WEEK, 2217d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath standalone ? formatData.getShortStandAloneWeekdays() : formatData.getShortWeekdays(), 2218d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath out)) > 0) { 2219d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2220d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2221d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } else { 2222d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath int[] styles = { Calendar.LONG, Calendar.SHORT }; 2223d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath for (int style : styles) { 2224d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath Map<String,Integer> map = calendar.getDisplayNames(field, style, locale); 2225d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath if ((index = matchString(text, start, field, map, out)) > 0) { 2226d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2227d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2228d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2229d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2230d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 2231d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath return index; 2232d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath } 2233d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 2234d6c54ba7af74286d2e310703a4aa2c924ec85c99Narayan Kamath 223551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final String getCalendarName() { 223651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return calendar.getClass().getName(); 223751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 223851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 223951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean useDateFormatSymbols() { 224051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useDateFormatSymbols) { 224151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 224251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 224351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isGregorianCalendar() || locale == null; 224451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 224551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 224651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isGregorianCalendar() { 224751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "java.util.GregorianCalendar".equals(getCalendarName()); 224851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 224951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 225051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 225151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates a pattern, mapping each character in the from string to the 225251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * corresponding character in the to string. 225351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 225451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 225551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 225651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String translatePattern(String pattern, String from, String to) { 225751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuilder result = new StringBuilder(); 225851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean inQuote = false; 225951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < pattern.length(); ++i) { 226051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = pattern.charAt(i); 226151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inQuote) { 226251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '\'') 226351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inQuote = false; 226451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 226551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 226651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c == '\'') 226751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski inQuote = true; 226851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { 226951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ci = from.indexOf(c); 227051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ci >= 0) { 227151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // patternChars is longer than localPatternChars due 227251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to serialization compatibility. The pattern letters 227351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // unsupported by localPatternChars pass through. 227451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ci < to.length()) { 227551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = to.charAt(ci); 227651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 227751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 227851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Illegal pattern " + 227951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski " character '" + 228051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c + "'"); 228151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 228251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 228351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 228451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result.append(c); 228551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 228651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inQuote) 228751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Unfinished quote in pattern"); 228851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result.toString(); 228951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 229051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 229151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 229251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a pattern string describing this date format. 229351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 229451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a pattern string describing this date format. 229551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 229651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toPattern() { 229751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pattern; 229851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 229951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 230051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 230151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns a localized pattern string describing this date format. 230251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 230351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a localized pattern string describing this date format. 230451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 230551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String toLocalizedPattern() { 230651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translatePattern(pattern, 230751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormatSymbols.patternChars, 230851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski formatData.getLocalPatternChars()); 230951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 231051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 231151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 231251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Applies the given pattern string to this date format. 231351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 231451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pattern the new date and time pattern for this date format 231551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given pattern is null 231651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 231751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 231851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void applyPattern(String pattern) 231951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 232051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern = compile(pattern); 232151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.pattern = pattern; 232251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 232351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 232451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 232551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Applies the given localized pattern string to this date format. 232651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 232751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param pattern a String to be mapped to the new date and time format 232851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern for this format 232951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given pattern is null 233051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the given pattern is invalid 233151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 233251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void applyLocalizedPattern(String pattern) { 233351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String p = translatePattern(pattern, 233451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski formatData.getLocalPatternChars(), 233551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DateFormatSymbols.patternChars); 233651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern = compile(p); 233751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.pattern = p; 233851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 233951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 234051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 234151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets a copy of the date and time format symbols of this date format. 234251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 234351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the date and time format symbols of this date format 234451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setDateFormatSymbols 234551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 234651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DateFormatSymbols getDateFormatSymbols() 234751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 234851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (DateFormatSymbols)formatData.clone(); 234951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 235051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 235151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 235251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the date and time format symbols of this date format. 235351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 235451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param newFormatSymbols the new date and time format symbols 235551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception NullPointerException if the given newFormatSymbols is null 235651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getDateFormatSymbols 235751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 235851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) 235951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 236051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.formatData = (DateFormatSymbols)newFormatSymbols.clone(); 236151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useDateFormatSymbols = true; 236251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 236351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 236451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 236551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a copy of this <code>SimpleDateFormat</code>. This also 236651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * clones the format's date format symbols. 236751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 236851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a clone of this <code>SimpleDateFormat</code> 236951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 237051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object clone() { 237151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SimpleDateFormat other = (SimpleDateFormat) super.clone(); 237251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski other.formatData = (DateFormatSymbols) formatData.clone(); 237351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return other; 237451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 237551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 237651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 237751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the hash code value for this <code>SimpleDateFormat</code> object. 237851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 237951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the hash code value for this <code>SimpleDateFormat</code> object. 238051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 238151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int hashCode() 238251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 238351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return pattern.hashCode(); 238451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // just enough fields for a reasonable distribution 238551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 238651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 238751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 238851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Compares the given object with this <code>SimpleDateFormat</code> for 238951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * equality. 239051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 239151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if the given object is equal to this 239251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>SimpleDateFormat</code> 239351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 239451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object obj) 239551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 239651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!super.equals(obj)) return false; // super does class check 239751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SimpleDateFormat that = (SimpleDateFormat) obj; 239851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (pattern.equals(that.pattern) 239951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && formatData.equals(that.formatData)); 240051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 240151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 240251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 240351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * After reading an object from the input stream, the format 240451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * pattern in the object is verified. 240551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 240651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception InvalidObjectException if the pattern is invalid 240751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 240851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void readObject(ObjectInputStream stream) 240951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException, ClassNotFoundException { 241051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stream.defaultReadObject(); 241151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 241251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 241351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski compiledPattern = compile(pattern); 241451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 241551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InvalidObjectException("invalid pattern"); 241651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 241751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 241851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (serialVersionOnStream < 1) { 241951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // didn't have defaultCenturyStart field 242051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeDefaultCentury(); 242151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 242251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 242351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fill in dependent transient field 242451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parseAmbiguousDatesAsAfter(defaultCenturyStart); 242551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 242651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski serialVersionOnStream = currentSerialVersion; 242751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 242851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the deserialized object has a SimpleTimeZone, try 242951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to replace it with a ZoneInfo equivalent in order to 243051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // be compatible with the SimpleTimeZone-based 243151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // implementation as much as possible. 243251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski TimeZone tz = getTimeZone(); 243351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tz instanceof SimpleTimeZone) { 243451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String id = tz.getID(); 243551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski TimeZone zi = TimeZone.getTimeZone(id); 243651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (zi != null && zi.hasSameRules(tz) && zi.getID().equals(id)) { 243751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setTimeZone(zi); 243851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 243951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 244051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 244151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 244251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 244351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Analyze the negative subpattern of DecimalFormat and set/update values 244451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as necessary. 244551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 244651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkNegativeNumberExpression() { 244751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((numberFormat instanceof DecimalFormat) && 244851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski !numberFormat.equals(originalNumberFormat)) { 244951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String numberPattern = ((DecimalFormat)numberFormat).toPattern(); 245051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!numberPattern.equals(originalNumberPattern)) { 245151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasFollowingMinusSign = false; 245251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 245351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int separatorIndex = numberPattern.indexOf(';'); 245451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the negative subpattern is not absent, we have to analayze 245551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // it in order to check if it has a following minus sign. 245651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (separatorIndex > -1) { 245751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int minusIndex = numberPattern.indexOf('-', separatorIndex); 245851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((minusIndex > numberPattern.lastIndexOf('0')) && 245951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (minusIndex > numberPattern.lastIndexOf('#'))) { 246051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasFollowingMinusSign = true; 246151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski minusSign = ((DecimalFormat)numberFormat).getDecimalFormatSymbols().getMinusSign(); 246251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 246351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 246451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski originalNumberPattern = numberPattern; 246551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 246651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski originalNumberFormat = numberFormat; 246751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 246851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 246951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 247051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 2471