2 *******************************************************************************
\r
3 * Copyright (C) 1996-2008, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.text;
\r
10 import java.text.FieldPosition;
\r
11 import java.text.ParsePosition;
\r
12 import java.util.Date;
\r
13 import java.util.Locale;
\r
15 import com.ibm.icu.util.Calendar;
\r
16 import com.ibm.icu.util.ULocale;
\r
19 * <code>SimpleDateFormat</code> is a concrete class for formatting and
\r
20 * parsing dates in a locale-sensitive manner. It allows for formatting
\r
21 * (date -> text), parsing (text -> date), and normalization.
\r
24 * <code>SimpleDateFormat</code> allows you to start by choosing
\r
25 * any user-defined patterns for date-time formatting. However, you
\r
26 * are encouraged to create a date-time formatter with either
\r
27 * <code>getTimeInstance</code>, <code>getDateInstance</code>, or
\r
28 * <code>getDateTimeInstance</code> in <code>DateFormat</code>. Each
\r
29 * of these class methods can return a date/time formatter initialized
\r
30 * with a default format pattern. You may modify the format pattern
\r
31 * using the <code>applyPattern</code> methods as desired.
\r
32 * For more information on using these methods, see
\r
33 * {@link DateFormat}.
\r
36 * <strong>Time Format Syntax:</strong>
\r
38 * To specify the time format use a <em>time pattern</em> string.
\r
39 * In this pattern, all ASCII letters are reserved as pattern letters,
\r
40 * which are defined as the following:
\r
43 * Symbol Meaning Presentation Example
\r
44 * ------ ------- ------------ -------
\r
45 * G era designator (Text) AD
\r
46 * y† year (Number) 1996
\r
47 * Y* year (week of year) (Number) 1997
\r
48 * u* extended year (Number) 4601
\r
49 * M month in year (Text & Number) July & 07
\r
50 * d day in month (Number) 10
\r
51 * h hour in am/pm (1~12) (Number) 12
\r
52 * H hour in day (0~23) (Number) 0
\r
53 * m minute in hour (Number) 30
\r
54 * s second in minute (Number) 55
\r
55 * S fractional second (Number) 978
\r
56 * E day of week (Text) Tuesday
\r
57 * e* day of week (local 1~7) (Number) 2
\r
58 * D day in year (Number) 189
\r
59 * F day of week in month (Number) 2 (2nd Wed in July)
\r
60 * w week in year (Number) 27
\r
61 * W week in month (Number) 2
\r
62 * a am/pm marker (Text) PM
\r
63 * k hour in day (1~24) (Number) 24
\r
64 * K hour in am/pm (0~11) (Number) 0
\r
65 * z time zone (Text) Pacific Standard Time
\r
66 * Z time zone (RFC 822) (Number) -0800
\r
67 * v time zone (generic) (Text) Pacific Time
\r
68 * g* Julian day (Number) 2451334
\r
69 * A* milliseconds in day (Number) 69540000
\r
70 * ' escape for text (Delimiter) 'Date='
\r
71 * '' single quote (Literal) 'o''clock'
\r
74 * <tt><b>*</b></tt> These items are not supported by Java's SimpleDateFormat.<br>
\r
75 * <tt><b>†</b></tt> ICU interprets a single 'y' differently than Java.</p>
\r
77 * The count of pattern letters determine the format.
\r
79 * <strong>(Text)</strong>: 4 or more pattern letters--use full form,
\r
80 * < 4--use short or abbreviated form if one exists.
\r
82 * <strong>(Number)</strong>: the minimum number of digits. Shorter
\r
83 * numbers are zero-padded to this amount. Year is handled specially;
\r
84 * that is, if the count of 'y' is 2, the Year will be truncated to 2 digits.
\r
85 * (e.g., if "yyyy" produces "1997", "yy" produces "97".)
\r
86 * Unlike other fields, fractional seconds are padded on the right with zero.
\r
88 * <strong>(Text & Number)</strong>: 3 or over, use text, otherwise use number.
\r
90 * Any characters in the pattern that are not in the ranges of ['a'..'z']
\r
91 * and ['A'..'Z'] will be treated as quoted text. For instance, characters
\r
92 * like ':', '.', ' ', '#' and '@' will appear in the resulting time text
\r
93 * even they are not embraced within single quotes.
\r
95 * A pattern containing any invalid pattern letter will result in a thrown
\r
96 * exception during formatting or parsing.
\r
99 * <strong>Examples Using the US Locale:</strong>
\r
102 * Format Pattern Result
\r
103 * -------------- -------
\r
104 * "yyyy.MM.dd G 'at' HH:mm:ss vvvv" ->> 1996.07.10 AD at 15:08:56 Pacific Time
\r
105 * "EEE, MMM d, ''yy" ->> Wed, July 10, '96
\r
106 * "h:mm a" ->> 12:08 PM
\r
107 * "hh 'o''clock' a, zzzz" ->> 12 o'clock PM, Pacific Daylight Time
\r
108 * "K:mm a, vvv" ->> 0:00 PM, PT
\r
109 * "yyyyy.MMMMM.dd GGG hh:mm aaa" ->> 01996.July.10 AD 12:08 PM
\r
112 * <strong>Code Sample:</strong>
\r
115 * SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, "PST");
\r
116 * pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2*60*60*1000);
\r
117 * pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*60*60*1000);
\r
119 * // Format the current time.
\r
120 * SimpleDateFormat formatter
\r
121 * = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz");
\r
122 * Date currentTime_1 = new Date();
\r
123 * String dateString = formatter.format(currentTime_1);
\r
125 * // Parse the previous string back into a Date.
\r
126 * ParsePosition pos = new ParsePosition(0);
\r
127 * Date currentTime_2 = formatter.parse(dateString, pos);
\r
130 * In the example, the time value <code>currentTime_2</code> obtained from
\r
131 * parsing will be equal to <code>currentTime_1</code>. However, they may not be
\r
132 * equal if the am/pm marker 'a' is left out from the format pattern while
\r
133 * the "hour in am/pm" pattern symbol is used. This information loss can
\r
134 * happen when formatting the time in PM.
\r
137 * When parsing a date string using the abbreviated year pattern ("yy"),
\r
138 * SimpleDateFormat must interpret the abbreviated year
\r
139 * relative to some century. It does this by adjusting dates to be
\r
140 * within 80 years before and 20 years after the time the SimpleDateFormat
\r
141 * instance is created. For example, using a pattern of "MM/dd/yy" and a
\r
142 * SimpleDateFormat instance created on Jan 1, 1997, the string
\r
143 * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64"
\r
144 * would be interpreted as May 4, 1964.
\r
145 * During parsing, only strings consisting of exactly two digits, as defined by
\r
146 * {@link java.lang.Character#isDigit(char)}, will be parsed into the default
\r
148 * Any other numeric string, such as a one digit string, a three or more digit
\r
149 * string, or a two digit string that isn't all digits (for example, "-1"), is
\r
150 * interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the
\r
151 * same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC.
\r
154 * If the year pattern does not have exactly two 'y' characters, the year is
\r
155 * interpreted literally, regardless of the number of digits. So using the
\r
156 * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
\r
159 * When numeric fields abut one another directly, with no intervening delimiter
\r
160 * characters, they constitute a run of abutting numeric fields. Such runs are
\r
161 * parsed specially. For example, the format "HHmmss" parses the input text
\r
162 * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to
\r
163 * parse "1234". In other words, the leftmost field of the run is flexible,
\r
164 * while the others keep a fixed width. If the parse fails anywhere in the run,
\r
165 * then the leftmost field is shortened by one character, and the entire run is
\r
166 * parsed again. This is repeated until either the parse succeeds or the
\r
167 * leftmost field is one character in length. If the parse still fails at that
\r
168 * point, the parse of the run fails.
\r
171 * For time zones that have no names, use strings GMT+hours:minutes or
\r
172 * GMT-hours:minutes.
\r
175 * The calendar defines what is the first day of the week, the first week
\r
176 * of the year, whether hours are zero based or not (0 vs 12 or 24), and the
\r
177 * time zone. There is one common decimal format to handle all the numbers;
\r
178 * the digit count is handled programmatically according to the pattern.
\r
180 * <h4>Synchronization</h4>
\r
182 * Date formats are not synchronized. It is recommended to create separate
\r
183 * format instances for each thread. If multiple threads access a format
\r
184 * concurrently, it must be synchronized externally.
\r
186 * @see com.ibm.icu.util.Calendar
\r
187 * @see com.ibm.icu.util.GregorianCalendar
\r
188 * @see com.ibm.icu.util.TimeZone
\r
190 * @see DateFormatSymbols
\r
191 * @see DecimalFormat
\r
192 * @author Mark Davis, Chen-Lieh Huang, Alan Liu
\r
195 public class SimpleDateFormat extends DateFormat {
\r
196 private static final long serialVersionUID = 1;
\r
199 * Construct a SimpleDateFormat using the default pattern for the default
\r
200 * locale. <b>Note:</b> Not all locales support SimpleDateFormat; for full
\r
201 * generality, use the factory methods in the DateFormat class.
\r
206 public SimpleDateFormat() {
\r
207 super(new java.text.SimpleDateFormat());
\r
211 * Construct a SimpleDateFormat using the given pattern in the default
\r
212 * locale. <b>Note:</b> Not all locales support SimpleDateFormat; for full
\r
213 * generality, use the factory methods in the DateFormat class.
\r
214 * @param pattern the pattern to use
\r
217 public SimpleDateFormat(String pattern) {
\r
218 super(new java.text.SimpleDateFormat(pattern));
\r
222 * Construct a SimpleDateFormat using the given pattern and locale.
\r
223 * <b>Note:</b> Not all locales support SimpleDateFormat; for full
\r
224 * generality, use the factory methods in the DateFormat class.
\r
225 * @param pattern the pattern to use
\r
226 * @param loc the locale to use for localization
\r
229 public SimpleDateFormat(String pattern, Locale loc) {
\r
230 super(new java.text.SimpleDateFormat(pattern, loc));
\r
234 * Construct a SimpleDateFormat using the given pattern and locale.
\r
235 * <b>Note:</b> Not all locales support SimpleDateFormat; for full
\r
236 * generality, use the factory methods in the DateFormat class.
\r
237 * @param pattern the pattern to use
\r
238 * @param loc the ulocale to use for localization
\r
241 public SimpleDateFormat(String pattern, ULocale loc) {
\r
242 this(pattern, loc.toLocale());
\r
246 * Construct a SimpleDateFormat using the given pattern and
\r
247 * locale-specific symbol data.
\r
248 * Warning: uses default locale for digits!
\r
249 * @param pattern the pattern to use
\r
250 * @param formatData the symbols to use for localization
\r
253 public SimpleDateFormat(String pattern, DateFormatSymbols formatData) {
\r
254 super(new java.text.SimpleDateFormat(pattern, formatData.dfs));
\r
258 * Sets the 100-year period 2-digit years will be interpreted as being in
\r
259 * to begin on the date the user specifies.
\r
260 * @param startDate During parsing, two digit years will be placed in the range
\r
261 * <code>startDate</code> to <code>startDate + 100 years</code>.
\r
264 public void set2DigitYearStart(Date startDate) {
\r
265 ((java.text.SimpleDateFormat)dateFormat).set2DigitYearStart(startDate);
\r
269 * Returns the beginning date of the 100-year period 2-digit years are interpreted
\r
271 * @return the start of the 100-year period into which two digit years are
\r
275 public Date get2DigitYearStart() {
\r
276 return ((java.text.SimpleDateFormat)dateFormat).get2DigitYearStart();
\r
280 * Overrides DateFormat.
\r
281 * <p>Formats a date or time, which is the standard millis
\r
282 * since January 1, 1970, 00:00:00 GMT.
\r
283 * <p>Example: using the US locale:
\r
284 * "yyyy.MM.dd G 'at' HH:mm:ss zzz" ->> 1996.07.10 AD at 15:08:56 PDT
\r
285 * @param cal the calendar whose date-time value is to be formatted into a date-time string
\r
286 * @param toAppendTo where the new date-time text is to be appended
\r
287 * @param pos the formatting position. On input: an alignment field,
\r
288 * if desired. On output: the offsets of the alignment field.
\r
289 * @return the formatted date-time string.
\r
293 public StringBuffer format(Calendar cal, StringBuffer toAppendTo, FieldPosition pos) {
\r
294 StringBuffer result;
\r
295 synchronized(dateFormat) {
\r
296 java.util.Calendar oldCal = dateFormat.getCalendar();
\r
297 dateFormat.setCalendar(cal.calendar);
\r
298 result = dateFormat.format(cal.getTime(), toAppendTo, pos);
\r
299 dateFormat.setCalendar(oldCal);
\r
305 * Overrides DateFormat
\r
309 public void parse(String text, Calendar cal, ParsePosition parsePos) {
\r
310 // TODO: cannot set the parsed timezone, document?
\r
311 cal.setTime(dateFormat.parse(text, parsePos));
\r
315 * Return a pattern string describing this date format.
\r
318 public String toPattern() {
\r
319 return ((java.text.SimpleDateFormat)dateFormat).toPattern();
\r
323 * Return a localized pattern string describing this date format.
\r
326 public String toLocalizedPattern() {
\r
327 return ((java.text.SimpleDateFormat)dateFormat).toLocalizedPattern();
\r
331 * Apply the given unlocalized pattern string to this date format.
\r
334 public void applyPattern(String pattern) {
\r
335 ((java.text.SimpleDateFormat)dateFormat).applyPattern(pattern);
\r
339 * Apply the given localized pattern string to this date format.
\r
342 public void applyLocalizedPattern(String pattern) {
\r
343 ((java.text.SimpleDateFormat)dateFormat).applyLocalizedPattern(pattern);
\r
347 * Gets the date/time formatting data.
\r
348 * @return a copy of the date-time formatting data associated
\r
349 * with this date-time formatter.
\r
352 public DateFormatSymbols getDateFormatSymbols() {
\r
353 return new DateFormatSymbols(((java.text.SimpleDateFormat)dateFormat).getDateFormatSymbols());
\r
357 * Allows you to set the date/time formatting data.
\r
358 * @param newFormatSymbols the new symbols
\r
361 public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) {
\r
362 ((java.text.SimpleDateFormat)dateFormat).setDateFormatSymbols(newFormatSymbols.dfs);
\r
366 * Overrides Cloneable
\r
369 public Object clone() {
\r
370 return new SimpleDateFormat((java.text.SimpleDateFormat)dateFormat.clone());
\r
377 private SimpleDateFormat(java.text.SimpleDateFormat sdf) {
\r
381 // hashCode, equals, clone use DateFormat implementation.
\r