GNU Classpath (0.95) | |
Frames | No Frames |
1: /* DateFormat.java -- Class for formatting/parsing date/times 2: Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.text; 41: 42: import gnu.java.locale.LocaleHelper; 43: 44: import java.text.spi.DateFormatProvider; 45: 46: import java.io.InvalidObjectException; 47: import java.util.Calendar; 48: import java.util.Date; 49: import java.util.Locale; 50: import java.util.MissingResourceException; 51: import java.util.ResourceBundle; 52: import java.util.ServiceLoader; 53: import java.util.TimeZone; 54: 55: /** 56: * @author Per Bothner (bothner@cygnus.com) 57: * @date October 25, 1998. 58: */ 59: /* Written using "Java Class Libraries", 2nd edition, plus online 60: * API docs for JDK 1.2 beta from http://www.javasoft.com. 61: * Status: Mostly complete; search for FIXME to see omissions. 62: */ 63: 64: public abstract class DateFormat extends Format implements Cloneable 65: { 66: private static final long serialVersionUID = 7218322306649953788L; 67: 68: // Names fixed by serialization spec. 69: protected Calendar calendar; 70: protected NumberFormat numberFormat; 71: 72: // (Values determined using a test program.) 73: public static final int FULL = 0; 74: public static final int LONG = 1; 75: public static final int MEDIUM = 2; 76: public static final int SHORT = 3; 77: public static final int DEFAULT = MEDIUM; 78: 79: /* These constants need to have these exact values. They 80: * correspond to index positions within the localPatternChars 81: * string for a given locale. Each locale may specify its 82: * own character for a particular field, but the position 83: * of these characters must correspond to an appropriate field 84: * number (as listed below), in order for their meaning to 85: * be determined. For example, the US locale uses 86: * the string "GyMdkHmsSEDFwWahKzYeugAZ", where 'G' is the character 87: * for era, 'y' for year, and so on down to 'Z' for time zone. 88: */ 89: /** 90: * Represents the position of the era 91: * pattern character in the array of 92: * localized pattern characters. 93: * For example, 'AD' is an era used 94: * in the Gregorian calendar system. 95: * In the U.S. locale, this is 'G'. 96: */ 97: public static final int ERA_FIELD = 0; 98: /** 99: * Represents the position of the year 100: * pattern character in the array of 101: * localized pattern characters. 102: * In the U.S. locale, this is 'y'. 103: */ 104: public static final int YEAR_FIELD = 1; 105: /** 106: * Represents the position of the month 107: * pattern character in the array of 108: * localized pattern characters. 109: * In the U.S. locale, this is 'M'. 110: */ 111: public static final int MONTH_FIELD = 2; 112: /** 113: * Represents the position of the date 114: * or day of the month pattern character 115: * in the array of localized pattern 116: * characters. In the U.S. locale, 117: * this is 'd'. 118: */ 119: public static final int DATE_FIELD = 3; 120: /** 121: * Represents the position of the 24 122: * hour pattern character in the array of 123: * localized pattern characters. 124: * In the U.S. locale, this is 'k'. 125: * This field numbers hours from 1 to 24. 126: */ 127: public static final int HOUR_OF_DAY1_FIELD = 4; 128: /** 129: * Represents the position of the 24 130: * hour pattern character in the array of 131: * localized pattern characters. 132: * In the U.S. locale, this is 'H'. 133: * This field numbers hours from 0 to 23. 134: */ 135: public static final int HOUR_OF_DAY0_FIELD = 5; 136: /** 137: * Represents the position of the minute 138: * pattern character in the array of 139: * localized pattern characters. 140: * In the U.S. locale, this is 'm'. 141: */ 142: public static final int MINUTE_FIELD = 6; 143: /** 144: * Represents the position of the second 145: * pattern character in the array of 146: * localized pattern characters. 147: * In the U.S. locale, this is 's'. 148: */ 149: public static final int SECOND_FIELD = 7; 150: /** 151: * Represents the position of the millisecond 152: * pattern character in the array of 153: * localized pattern characters. 154: * In the U.S. locale, this is 'S'. 155: */ 156: public static final int MILLISECOND_FIELD = 8; 157: /** 158: * Represents the position of the day of the 159: * week pattern character in the array of 160: * localized pattern characters. 161: * In the U.S. locale, this is 'E'. 162: */ 163: public static final int DAY_OF_WEEK_FIELD = 9; 164: /** 165: * Represents the position of the day of the 166: * year pattern character in the array of 167: * localized pattern characters. 168: * In the U.S. locale, this is 'D'. 169: */ 170: public static final int DAY_OF_YEAR_FIELD = 10; 171: /** 172: * Represents the position of the day of the 173: * week in the month pattern character in the 174: * array of localized pattern characters. 175: * In the U.S. locale, this is 'F'. 176: */ 177: public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; 178: /** 179: * Represents the position of the week of the 180: * year pattern character in the array of 181: * localized pattern characters. 182: * In the U.S. locale, this is 'w'. 183: */ 184: public static final int WEEK_OF_YEAR_FIELD = 12; 185: /** 186: * Represents the position of the week of the 187: * month pattern character in the array of 188: * localized pattern characters. 189: * In the U.S. locale, this is 'W'. 190: */ 191: public static final int WEEK_OF_MONTH_FIELD = 13; 192: /** 193: * Represents the position of the am/pm 194: * pattern character in the array of 195: * localized pattern characters. 196: * In the U.S. locale, this is 'a'. 197: */ 198: public static final int AM_PM_FIELD = 14; 199: /** 200: * Represents the position of the 12 201: * hour pattern character in the array of 202: * localized pattern characters. 203: * In the U.S. locale, this is 'h'. 204: * This field numbers hours from 1 to 12. 205: */ 206: public static final int HOUR1_FIELD = 15; 207: /** 208: * Represents the position of the 12 209: * hour pattern character in the array of 210: * localized pattern characters. 211: * In the U.S. locale, this is 'K'. 212: * This field numbers hours from 0 to 11. 213: */ 214: public static final int HOUR0_FIELD = 16; 215: /** 216: * Represents the position of the generic 217: * timezone pattern character in the array of 218: * localized pattern characters. 219: * In the U.S. locale, this is 'z'. 220: */ 221: public static final int TIMEZONE_FIELD = 17; 222: /** 223: * Represents the position of the ISO year 224: * pattern character in the array of 225: * localized pattern characters. 226: * In the U.S. locale, this is 'Y'. 227: * This is a GNU extension in accordance with 228: * the CLDR data used. This value may 229: * differ from the normal year value. 230: */ 231: public static final int ISO_YEAR_FIELD = 18; 232: /** 233: * Represents the position of the localized 234: * day of the week pattern character in the 235: * array of localized pattern characters. 236: * In the U.S. locale, this is 'e'. 237: * This is a GNU extension in accordance with 238: * the CLDR data used. This value only 239: * differs from the day of the week with 240: * numeric formatting, in which case the 241: * locale's first day of the week is used. 242: */ 243: public static final int LOCALIZED_DAY_OF_WEEK_FIELD = 19; 244: /** 245: * Represents the position of the extended year 246: * pattern character in the array of 247: * localized pattern characters. 248: * In the U.S. locale, this is 'u'. 249: * This is a GNU extension in accordance with 250: * the CLDR data used. This value modifies 251: * the year value, so as to incorporate the era. 252: * For example, in the Gregorian calendar system, 253: * the extended year is negative instead of being 254: * marked as BC. 255: */ 256: public static final int EXTENDED_YEAR_FIELD = 20; 257: /** 258: * Represents the position of the modified Julian 259: * day pattern character in the array of 260: * localized pattern characters. 261: * In the U.S. locale, this is 'g'. 262: * This is a GNU extension in accordance with 263: * the CLDR data used. This value differs 264: * from the standard Julian day in that days 265: * are marked from midnight onwards rather than 266: * noon, and the local time zone affects the value. 267: * In simple terms, it can be thought of as all 268: * the date fields represented as a single number. 269: */ 270: public static final int MODIFIED_JULIAN_DAY_FIELD = 21; 271: /** 272: * Represents the position of the millisecond 273: * in the day pattern character in the array of 274: * localized pattern characters. 275: * In the U.S. locale, this is 'A'. 276: * This is a GNU extension in accordance with 277: * the CLDR data used. This value represents 278: * all the time fields (excluding the time zone) 279: * numerically, giving the number of milliseconds 280: * into the day (e.g. 10 in the morning would 281: * be 10 * 60 * 60 * 1000). Any daylight savings 282: * offset also affects this value. 283: */ 284: public static final int MILLISECOND_IN_DAY_FIELD = 22; 285: /** 286: * Represents the position of the RFC822 287: * timezone pattern character in the array of 288: * localized pattern characters. 289: * In the U.S. locale, this is 'Z'. 290: * This is a GNU extension in accordance with 291: * the CLDR data used. The value is the offset 292: * of the current time from GMT e.g. -0500 would 293: * be five hours prior to GMT. 294: */ 295: public static final int RFC822_TIMEZONE_FIELD = 23; 296: 297: public static class Field extends Format.Field 298: { 299: static final long serialVersionUID = 7441350119349544720L; 300: 301: private int calendarField; 302: 303: public static final DateFormat.Field ERA 304: = new Field("era", Calendar.ERA); 305: public static final DateFormat.Field YEAR 306: = new Field("year", Calendar.YEAR); 307: public static final DateFormat.Field MONTH 308: = new Field("month", Calendar.MONTH); 309: public static final DateFormat.Field DAY_OF_MONTH 310: = new Field("day of month", Calendar.DAY_OF_MONTH); 311: public static final DateFormat.Field HOUR_OF_DAY1 312: = new Field("hour of day 1", Calendar.HOUR_OF_DAY); 313: public static final DateFormat.Field HOUR_OF_DAY0 314: = new Field("hour of day 0", Calendar.HOUR_OF_DAY); 315: public static final DateFormat.Field MINUTE 316: = new Field("minute", Calendar.MINUTE); 317: public static final DateFormat.Field SECOND 318: = new Field("second", Calendar.SECOND); 319: public static final DateFormat.Field MILLISECOND 320: = new Field("millisecond", Calendar.MILLISECOND); 321: public static final DateFormat.Field DAY_OF_WEEK 322: = new Field("day of week", Calendar.DAY_OF_WEEK); 323: public static final DateFormat.Field DAY_OF_YEAR 324: = new Field("day of year", Calendar.DAY_OF_YEAR); 325: public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH 326: = new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH); 327: public static final DateFormat.Field WEEK_OF_YEAR 328: = new Field("week of year", Calendar.WEEK_OF_YEAR); 329: public static final DateFormat.Field WEEK_OF_MONTH 330: = new Field("week of month", Calendar.WEEK_OF_MONTH); 331: public static final DateFormat.Field AM_PM 332: = new Field("am/pm", Calendar.AM_PM); 333: public static final DateFormat.Field HOUR1 334: = new Field("hour1", Calendar.HOUR); 335: public static final DateFormat.Field HOUR0 336: = new Field("hour0", Calendar.HOUR); 337: public static final DateFormat.Field TIME_ZONE 338: = new Field("timezone", Calendar.ZONE_OFFSET); 339: public static final DateFormat.Field ISO_YEAR 340: = new Field("iso year", Calendar.YEAR); 341: public static final DateFormat.Field LOCALIZED_DAY_OF_WEEK 342: = new Field("localized day of week", Calendar.DAY_OF_WEEK); 343: public static final DateFormat.Field EXTENDED_YEAR 344: = new Field("extended year", Calendar.YEAR); 345: public static final DateFormat.Field MODIFIED_JULIAN_DAY 346: = new Field("julian day", -1); 347: public static final DateFormat.Field MILLISECOND_IN_DAY 348: = new Field("millisecond in day", -1); 349: public static final DateFormat.Field RFC822_TIME_ZONE 350: = new Field("rfc822 timezone", Calendar.ZONE_OFFSET); 351: 352: static final DateFormat.Field[] allFields = 353: { 354: ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1, 355: HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND, 356: DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH, 357: WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0, 358: TIME_ZONE, ISO_YEAR, LOCALIZED_DAY_OF_WEEK, 359: EXTENDED_YEAR, MODIFIED_JULIAN_DAY, MILLISECOND_IN_DAY, 360: RFC822_TIME_ZONE 361: }; 362: 363: // For deserialization 364: private Field() 365: { 366: super(""); 367: } 368: 369: protected Field(String name, int calendarField) 370: { 371: super(name); 372: this.calendarField = calendarField; 373: } 374: 375: public int getCalendarField() 376: { 377: return calendarField; 378: } 379: 380: public static Field ofCalendarField(int calendarField) 381: { 382: if (calendarField >= allFields.length || calendarField < 0) 383: throw new IllegalArgumentException("no such calendar field (" 384: + calendarField + ")"); 385: 386: return allFields[calendarField]; 387: } 388: 389: protected Object readResolve() throws InvalidObjectException 390: { 391: String s = getName(); 392: 393: for (int i=0;i<allFields.length;i++) 394: if (s.equals(allFields[i].getName())) 395: return allFields[i]; 396: 397: throw new InvalidObjectException("no such DateFormat field called " + s); 398: } 399: } 400: 401: /** 402: * This method initializes a new instance of <code>DateFormat</code>. 403: */ 404: protected DateFormat () 405: { 406: } 407: 408: /** 409: * This method tests this object for equality against the specified object. 410: * The two objects will be considered equal if an only if the specified 411: * object: 412: * <P> 413: * <ul> 414: * <li>Is not <code>null</code>.</li> 415: * <li>Is an instance of <code>DateFormat</code>.</li> 416: * <li>Has equal numberFormat field as this object.</li> 417: * <li>Has equal (Calendar) TimeZone rules as this object.</li> 418: * <li>Has equal (Calendar) isLenient results.</li> 419: * <li>Has equal Calendar first day of week and minimal days in week 420: * values.</li> 421: * </ul> 422: * Note that not all properties of the Calendar are relevant for a 423: * DateFormat. For formatting only the fact whether or not the 424: * TimeZone has the same rules and whether the calendar is lenient 425: * and has the same week rules is compared for this implementation 426: * of equals. Other properties of the Calendar (such as the time) 427: * are not taken into account. 428: * 429: * @param obj The object to test for equality against. 430: * 431: * @return <code>true</code> if the specified object is equal to this object, 432: * <code>false</code> otherwise. 433: */ 434: public boolean equals (Object obj) 435: { 436: if (!(obj instanceof DateFormat)) 437: return false; 438: 439: DateFormat d = (DateFormat) obj; 440: TimeZone tz = getTimeZone(); 441: TimeZone tzd = d.getTimeZone(); 442: if (tz.hasSameRules(tzd)) 443: if (isLenient() == d.isLenient()) 444: { 445: Calendar c = getCalendar(); 446: Calendar cd = d.getCalendar(); 447: if ((c == null && cd == null) 448: || 449: (c.getFirstDayOfWeek() == cd.getFirstDayOfWeek() 450: && 451: c.getMinimalDaysInFirstWeek() 452: == cd.getMinimalDaysInFirstWeek())) 453: return ((numberFormat == null && d.numberFormat == null) 454: || numberFormat.equals(d.numberFormat)); 455: } 456: 457: return false; 458: } 459: 460: /** 461: * This method returns a copy of this object. 462: * 463: * @return A copy of this object. 464: */ 465: public Object clone () 466: { 467: // We know the superclass just call's Object's generic cloner. 468: return super.clone (); 469: } 470: 471: /** 472: * This method formats the specified <code>Object</code> into a date string 473: * and appends it to the specified <code>StringBuffer</code>. 474: * The specified object must be an instance of <code>Number</code> or 475: * <code>Date</code> or an <code>IllegalArgumentException</code> will be 476: * thrown. 477: * 478: * @param obj The <code>Object</code> to format. 479: * @param buf The <code>StringBuffer</code> to append the resultant 480: * <code>String</code> to. 481: * @param pos Is updated to the start and end index of the 482: * specified field. 483: * 484: * @return The <code>StringBuffer</code> supplied on input, with the 485: * formatted date/time appended. 486: */ 487: public final StringBuffer format (Object obj, 488: StringBuffer buf, FieldPosition pos) 489: { 490: if (obj instanceof Number) 491: obj = new Date(((Number) obj).longValue()); 492: else if (! (obj instanceof Date)) 493: throw new IllegalArgumentException 494: ("Cannot format given Object as a Date"); 495: 496: return format ((Date) obj, buf, pos); 497: } 498: 499: /** 500: * Formats the date argument according to the pattern specified. 501: * 502: * @param date The formatted date. 503: */ 504: public final String format (Date date) 505: { 506: StringBuffer sb = new StringBuffer (); 507: format (date, sb, new FieldPosition (MONTH_FIELD)); 508: return sb.toString(); 509: } 510: 511: /** 512: * This method formats a <code>Date</code> into a string and appends it 513: * to the specified <code>StringBuffer</code>. 514: * 515: * @param date The <code>Date</code> value to format. 516: * @param buf The <code>StringBuffer</code> to append the resultant 517: * <code>String</code> to. 518: * @param pos Is updated to the start and end index of the 519: * specified field. 520: * 521: * @return The <code>StringBuffer</code> supplied on input, with the 522: * formatted date/time appended. 523: */ 524: public abstract StringBuffer format (Date date, 525: StringBuffer buf, FieldPosition pos); 526: 527: /** 528: * This method returns a list of available locales supported by this 529: * class. 530: */ 531: public static Locale[] getAvailableLocales() 532: { 533: return Locale.getAvailableLocales(); 534: } 535: 536: /** 537: * This method returns the <code>Calendar</code> object being used by 538: * this object to parse/format datetimes. 539: * 540: * @return The <code>Calendar</code> being used by this object. 541: * 542: * @see java.util.Calendar 543: */ 544: public Calendar getCalendar () 545: { 546: return calendar; 547: } 548: 549: private static DateFormat computeInstance (int style, Locale loc, 550: boolean use_date, boolean use_time) 551: { 552: return computeInstance (style, style, loc, use_date, use_time); 553: } 554: 555: private static DateFormat computeInstance (int dateStyle, int timeStyle, 556: Locale loc, boolean use_date, 557: boolean use_time) 558: throws MissingResourceException 559: { 560: if (loc.equals(Locale.ROOT)) 561: return computeDefault(dateStyle,timeStyle,use_date,use_time); 562: 563: ResourceBundle res = 564: ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", 565: loc, ClassLoader.getSystemClassLoader()); 566: 567: String pattern = null; 568: if (use_date) 569: { 570: String name, def; 571: switch (dateStyle) 572: { 573: case FULL: 574: name = "fullDateFormat"; 575: def = "EEEE MMMM d, yyyy G"; 576: break; 577: case LONG: 578: name = "longDateFormat"; 579: def = "MMMM d, yyyy"; 580: break; 581: case MEDIUM: 582: name = "mediumDateFormat"; 583: def = "d-MMM-yy"; 584: break; 585: case SHORT: 586: name = "shortDateFormat"; 587: def = "M/d/yy"; 588: break; 589: default: 590: throw new IllegalArgumentException (); 591: } 592: try 593: { 594: pattern = res == null ? def : res.getString(name); 595: } 596: catch (MissingResourceException x) 597: { 598: pattern = def; 599: } 600: } 601: 602: if (use_time) 603: { 604: if (pattern == null) 605: pattern = ""; 606: else 607: pattern += " "; 608: 609: String name, def; 610: switch (timeStyle) 611: { 612: case FULL: 613: name = "fullTimeFormat"; 614: def = "h:mm:ss;S 'o''clock' a z"; 615: break; 616: case LONG: 617: name = "longTimeFormat"; 618: def = "h:mm:ss a z"; 619: break; 620: case MEDIUM: 621: name = "mediumTimeFormat"; 622: def = "h:mm:ss a"; 623: break; 624: case SHORT: 625: name = "shortTimeFormat"; 626: def = "h:mm a"; 627: break; 628: default: 629: throw new IllegalArgumentException (); 630: } 631: 632: String s; 633: try 634: { 635: s = res == null ? def : res.getString(name); 636: } 637: catch (MissingResourceException x) 638: { 639: s = def; 640: } 641: pattern += s; 642: } 643: 644: return new SimpleDateFormat (pattern, loc); 645: } 646: 647: private static DateFormat computeDefault (int dateStyle, int timeStyle, 648: boolean use_date, boolean use_time) 649: { 650: String pattern = null; 651: if (use_date) 652: { 653: switch (dateStyle) 654: { 655: case FULL: 656: pattern = "EEEE MMMM d, yyyy G"; 657: break; 658: case LONG: 659: pattern = "MMMM d, yyyy"; 660: break; 661: case MEDIUM: 662: pattern = "d-MMM-yy"; 663: break; 664: case SHORT: 665: pattern = "M/d/yy"; 666: default: 667: throw new IllegalArgumentException (); 668: } 669: } 670: 671: if (use_time) 672: { 673: if (pattern == null) 674: pattern = ""; 675: else 676: pattern += " "; 677: 678: switch (timeStyle) 679: { 680: case FULL: 681: pattern += "h:mm:ss;S 'o''clock' a z"; 682: break; 683: case LONG: 684: pattern += "h:mm:ss a z"; 685: break; 686: case MEDIUM: 687: pattern += "h:mm:ss a"; 688: break; 689: case SHORT: 690: pattern += "h:mm a"; 691: break; 692: default: 693: throw new IllegalArgumentException (); 694: } 695: } 696: 697: return new SimpleDateFormat (pattern, Locale.ROOT); 698: } 699: 700: /** 701: * This method returns an instance of <code>DateFormat</code> that will 702: * format using the default formatting style for dates. 703: * 704: * @return A new <code>DateFormat</code> instance. 705: */ 706: public static final DateFormat getDateInstance () 707: { 708: return getDateInstance (DEFAULT, Locale.getDefault()); 709: } 710: 711: /** 712: * This method returns an instance of <code>DateFormat</code> that will 713: * format using the specified formatting style for dates. 714: * 715: * @param style The type of formatting to perform. 716: * 717: * @return A new <code>DateFormat</code> instance. 718: */ 719: public static final DateFormat getDateInstance (int style) 720: { 721: return getDateInstance (style, Locale.getDefault()); 722: } 723: 724: /** 725: * This method returns an instance of <code>DateFormat</code> that will 726: * format using the specified formatting style for dates. The specified 727: * localed will be used in place of the default. 728: * 729: * @param style The type of formatting to perform. 730: * @param loc The desired locale. 731: * 732: * @return A new <code>DateFormat</code> instance. 733: */ 734: public static final DateFormat getDateInstance (int style, Locale loc) 735: { 736: try 737: { 738: return computeInstance (style, loc, true, false); 739: } 740: catch (MissingResourceException e) 741: { 742: for (DateFormatProvider p : 743: ServiceLoader.load(DateFormatProvider.class)) 744: { 745: for (Locale l : p.getAvailableLocales()) 746: { 747: if (l.equals(loc)) 748: { 749: DateFormat df = p.getDateInstance(style, loc); 750: if (df != null) 751: return df; 752: break; 753: } 754: } 755: } 756: return getDateInstance(style, 757: LocaleHelper.getFallbackLocale(loc)); 758: } 759: } 760: 761: /** 762: * This method returns a new instance of <code>DateFormat</code> that 763: * formats both dates and times using the <code>SHORT</code> style. 764: * 765: * @return A new <code>DateFormat</code>instance. 766: */ 767: public static final DateFormat getDateTimeInstance () 768: { 769: return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault()); 770: } 771: 772: /** 773: * This method returns a new instance of <code>DateFormat</code> that 774: * formats both dates and times using the <code>DEFAULT</code> style. 775: * 776: * @return A new <code>DateFormat</code>instance. 777: */ 778: public static final DateFormat getDateTimeInstance (int dateStyle, 779: int timeStyle) 780: { 781: return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault()); 782: } 783: 784: /** 785: * This method returns a new instance of <code>DateFormat</code> that 786: * formats both dates and times using the specified styles. 787: * 788: * @param dateStyle The desired style for date formatting. 789: * @param timeStyle The desired style for time formatting 790: * 791: * @return A new <code>DateFormat</code>instance. 792: */ 793: public static final DateFormat getDateTimeInstance (int dateStyle, 794: int timeStyle, 795: Locale loc) 796: { 797: try 798: { 799: return computeInstance (dateStyle, timeStyle, loc, true, true); 800: } 801: catch (MissingResourceException e) 802: { 803: for (DateFormatProvider p : 804: ServiceLoader.load(DateFormatProvider.class)) 805: { 806: for (Locale l : p.getAvailableLocales()) 807: { 808: if (l.equals(loc)) 809: { 810: DateFormat df = p.getDateTimeInstance(dateStyle, 811: timeStyle, loc); 812: if (df != null) 813: return df; 814: break; 815: } 816: } 817: } 818: return getDateTimeInstance(dateStyle, timeStyle, 819: LocaleHelper.getFallbackLocale(loc)); 820: } 821: } 822: 823: /** 824: * This method returns a new instance of <code>DateFormat</code> that 825: * formats both dates and times using the <code>SHORT</code> style. 826: * 827: * @return A new <code>DateFormat</code>instance. 828: */ 829: public static final DateFormat getInstance () 830: { 831: // JCL book says SHORT. 832: return getDateTimeInstance (SHORT, SHORT, Locale.getDefault()); 833: } 834: 835: /** 836: * This method returns the <code>NumberFormat</code> object being used 837: * by this object to parse/format time values. 838: * 839: * @return The <code>NumberFormat</code> in use by this object. 840: */ 841: public NumberFormat getNumberFormat () 842: { 843: return numberFormat; 844: } 845: 846: /** 847: * This method returns an instance of <code>DateFormat</code> that will 848: * format using the default formatting style for times. 849: * 850: * @return A new <code>DateFormat</code> instance. 851: */ 852: public static final DateFormat getTimeInstance () 853: { 854: return getTimeInstance (DEFAULT, Locale.getDefault()); 855: } 856: 857: /** 858: * This method returns an instance of <code>DateFormat</code> that will 859: * format using the specified formatting style for times. 860: * 861: * @param style The type of formatting to perform. 862: * 863: * @return A new <code>DateFormat</code> instance. 864: */ 865: public static final DateFormat getTimeInstance (int style) 866: { 867: return getTimeInstance (style, Locale.getDefault()); 868: } 869: 870: /** 871: * This method returns an instance of <code>DateFormat</code> that will 872: * format using the specified formatting style for times. The specified 873: * localed will be used in place of the default. 874: * 875: * @param style The type of formatting to perform. 876: * @param loc The desired locale. 877: * 878: * @return A new <code>DateFormat</code> instance. 879: */ 880: public static final DateFormat getTimeInstance (int style, Locale loc) 881: { 882: try 883: { 884: return computeInstance (style, loc, false, true); 885: } 886: catch (MissingResourceException e) 887: { 888: for (DateFormatProvider p : 889: ServiceLoader.load(DateFormatProvider.class)) 890: { 891: for (Locale l : p.getAvailableLocales()) 892: { 893: if (l.equals(loc)) 894: { 895: DateFormat df = p.getTimeInstance(style, loc); 896: if (df != null) 897: return df; 898: break; 899: } 900: } 901: } 902: return getTimeInstance(style, 903: LocaleHelper.getFallbackLocale(loc)); 904: } 905: } 906: 907: /** 908: * This method returns the <code>TimeZone</code> object being used by 909: * this instance. 910: * 911: * @return The time zone in use. 912: */ 913: public TimeZone getTimeZone () 914: { 915: return calendar.getTimeZone(); 916: } 917: 918: /** 919: * This method returns a hash value for this object. 920: * 921: * @return A hash value for this object. 922: */ 923: public int hashCode () 924: { 925: if (numberFormat != null) 926: return numberFormat.hashCode(); 927: else 928: return 0; 929: } 930: 931: /** 932: * This method indicates whether or not the parsing of date and time 933: * values should be done in a lenient value. 934: * 935: * @return <code>true</code> if date/time parsing is lenient, 936: * <code>false</code> otherwise. 937: */ 938: public boolean isLenient () 939: { 940: return calendar.isLenient(); 941: } 942: 943: /** 944: * This method parses the specified date/time string. 945: * 946: * @param source The string to parse. 947: * @return The resultant date. 948: * 949: * @exception ParseException If the specified string cannot be parsed. 950: */ 951: public Date parse (String source) throws ParseException 952: { 953: ParsePosition pos = new ParsePosition(0); 954: Date result = parse (source, pos); 955: if (result == null) 956: { 957: int index = pos.getErrorIndex(); 958: if (index < 0) 959: index = pos.getIndex(); 960: throw new ParseException("invalid Date syntax in \"" 961: + source + '\"', index); 962: } 963: return result; 964: } 965: 966: /** 967: * This method parses the specified <code>String</code> into a 968: * <code>Date</code>. The <code>pos</code> argument contains the 969: * starting parse position on method entry and the ending parse 970: * position on method exit. 971: * 972: * @param source The string to parse. 973: * @param pos The starting parse position in entry, the ending parse 974: * position on exit. 975: * 976: * @return The parsed date, or <code>null</code> if the string cannot 977: * be parsed. 978: */ 979: public abstract Date parse (String source, ParsePosition pos); 980: 981: /** 982: * This method is identical to <code>parse(String, ParsePosition)</code>, 983: * but returns its result as an <code>Object</code> instead of a 984: * <code>Date</code>. 985: * 986: * @param source The string to parse. 987: * @param pos The starting parse position in entry, the ending parse 988: * position on exit. 989: * 990: * @return The parsed date, or <code>null</code> if the string cannot 991: * be parsed. 992: */ 993: public Object parseObject (String source, ParsePosition pos) 994: { 995: return parse(source, pos); 996: } 997: 998: /** 999: * This method specified the <code>Calendar</code> that should be used 1000: * by this object to parse/format datetimes. 1001: * 1002: * @param calendar The new <code>Calendar</code> for this object. 1003: * 1004: * @see java.util.Calendar 1005: */ 1006: public void setCalendar (Calendar calendar) 1007: { 1008: this.calendar = calendar; 1009: } 1010: 1011: /** 1012: * This method specifies whether or not this object should be lenient in 1013: * the syntax it accepts while parsing date/time values. 1014: * 1015: * @param lenient <code>true</code> if parsing should be lenient, 1016: * <code>false</code> otherwise. 1017: */ 1018: public void setLenient (boolean lenient) 1019: { 1020: calendar.setLenient(lenient); 1021: } 1022: 1023: /** 1024: * This method specifies the <code>NumberFormat</code> object that should 1025: * be used by this object to parse/format times. 1026: * 1027: * @param numberFormat The <code>NumberFormat</code> in use by this object. 1028: */ 1029: public void setNumberFormat (NumberFormat numberFormat) 1030: { 1031: this.numberFormat = numberFormat; 1032: } 1033: 1034: /** 1035: * This method sets the time zone that should be used by this object. 1036: * 1037: * @param timeZone The new time zone. 1038: */ 1039: public void setTimeZone (TimeZone timeZone) 1040: { 1041: calendar.setTimeZone(timeZone); 1042: } 1043: }
GNU Classpath (0.95) |