Source Code Cross Referenced for FastDateFormat.java in  » Net » openfire » org » jivesoftware » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » openfire » org.jivesoftware.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         * Trove - Copyright (c) 1997-2001 Walt Disney Internet Group
0003:         * ====================================================================
0004:         * The Tea Software License, Version 1.1
0005:         *
0006:         * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
0007:         *
0008:         * Redistribution and use in source and binary forms, with or without
0009:         * modification, are permitted provided that the following conditions
0010:         * are met:
0011:         *
0012:         * 1. Redistributions of source code must retain the above copyright
0013:         *    notice, this list of conditions and the following disclaimer.
0014:         *
0015:         * 2. Redistributions in binary form must reproduce the above copyright
0016:         *    notice, this list of conditions and the following disclaimer in
0017:         *    the documentation and/or other materials provided with the
0018:         *    distribution.
0019:         *
0020:         * 3. The end-user documentation included with the redistribution,
0021:         *    if any, must include the following acknowledgment:
0022:         *       "This product includes software developed by the
0023:         *        Walt Disney Internet Group (http://opensource.go.com/)."
0024:         *    Alternately, this acknowledgment may appear in the software itself,
0025:         *    if and wherever such third-party acknowledgments normally appear.
0026:         *
0027:         * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
0028:         *    not be used to endorse or promote products derived from this
0029:         *    software without prior written permission. For written
0030:         *    permission, please contact opensource@dig.com.
0031:         *
0032:         * 5. Products derived from this software may not be called "Tea",
0033:         *    "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
0034:         *    "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
0035:         *    written permission of the Walt Disney Internet Group.
0036:         *
0037:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0038:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0039:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0040:         * DISCLAIMED.  IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
0041:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0042:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0043:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0044:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0045:         * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0046:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0047:         * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0048:         * ====================================================================
0049:         *
0050:         * For more information about Tea, please see http://opensource.go.com/.
0051:         */
0052:
0053:        package org.jivesoftware.util;
0054:
0055:        import java.util.Date;
0056:        import java.util.Calendar;
0057:        import java.util.GregorianCalendar;
0058:        import java.util.Locale;
0059:        import java.util.TimeZone;
0060:        import java.util.List;
0061:        import java.util.ArrayList;
0062:        import java.util.Map;
0063:        import java.util.HashMap;
0064:        import java.text.DateFormatSymbols;
0065:        import java.text.DateFormat;
0066:        import java.text.SimpleDateFormat;
0067:
0068:        /**
0069:         * <p>Similar to {@link java.text.SimpleDateFormat}, but faster and thread-safe.
0070:         * Only formatting is supported, but all patterns are compatible with
0071:         * SimpleDateFormat.</p>
0072:         *
0073:         * <p>Note, this class is from the open source Tea project (http://sourceforge.net/projects/teatrove/).</p>
0074:         *
0075:         * @author Brian S O'Neill
0076:         */
0077:        public class FastDateFormat {
0078:            /** Style pattern */
0079:            public static final Object FULL = new Integer(SimpleDateFormat.FULL),
0080:                    LONG = new Integer(SimpleDateFormat.LONG),
0081:                    MEDIUM = new Integer(SimpleDateFormat.MEDIUM),
0082:                    SHORT = new Integer(SimpleDateFormat.SHORT);
0083:
0084:            private static final double LOG_10 = Math.log(10);
0085:
0086:            private static String cDefaultPattern;
0087:            private static TimeZone cDefaultTimeZone = TimeZone.getDefault();
0088:
0089:            private static Map cTimeZoneDisplayCache = new HashMap();
0090:
0091:            private static Map cInstanceCache = new HashMap(7);
0092:            private static Map cDateInstanceCache = new HashMap(7);
0093:            private static Map cTimeInstanceCache = new HashMap(7);
0094:            private static Map cDateTimeInstanceCache = new HashMap(7);
0095:
0096:            public static FastDateFormat getInstance() {
0097:                return getInstance(getDefaultPattern(), null, null, null);
0098:            }
0099:
0100:            /**
0101:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0102:             */
0103:            public static FastDateFormat getInstance(String pattern)
0104:                    throws IllegalArgumentException {
0105:                return getInstance(pattern, null, null, null);
0106:            }
0107:
0108:            /**
0109:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0110:             * @param timeZone optional time zone, overrides time zone of formatted
0111:             * date
0112:             */
0113:            public static FastDateFormat getInstance(String pattern,
0114:                    TimeZone timeZone) throws IllegalArgumentException {
0115:                return getInstance(pattern, timeZone, null, null);
0116:            }
0117:
0118:            /**
0119:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0120:             * @param locale optional locale, overrides system locale
0121:             */
0122:            public static FastDateFormat getInstance(String pattern,
0123:                    Locale locale) throws IllegalArgumentException {
0124:                return getInstance(pattern, null, locale, null);
0125:            }
0126:
0127:            /**
0128:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0129:             * @param symbols optional date format symbols, overrides symbols for
0130:             * system locale
0131:             */
0132:            public static FastDateFormat getInstance(String pattern,
0133:                    DateFormatSymbols symbols) throws IllegalArgumentException {
0134:                return getInstance(pattern, null, null, symbols);
0135:            }
0136:
0137:            /**
0138:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0139:             * @param timeZone optional time zone, overrides time zone of formatted
0140:             * date
0141:             * @param locale optional locale, overrides system locale
0142:             */
0143:            public static FastDateFormat getInstance(String pattern,
0144:                    TimeZone timeZone, Locale locale)
0145:                    throws IllegalArgumentException {
0146:                return getInstance(pattern, timeZone, locale, null);
0147:            }
0148:
0149:            /**
0150:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0151:             * @param timeZone optional time zone, overrides time zone of formatted
0152:             * date
0153:             * @param locale optional locale, overrides system locale
0154:             * @param symbols optional date format symbols, overrides symbols for
0155:             * provided locale
0156:             */
0157:            public static synchronized FastDateFormat getInstance(
0158:                    String pattern, TimeZone timeZone, Locale locale,
0159:                    DateFormatSymbols symbols) throws IllegalArgumentException {
0160:                Object key = pattern;
0161:
0162:                if (timeZone != null) {
0163:                    key = new Pair(key, timeZone);
0164:                }
0165:                if (locale != null) {
0166:                    key = new Pair(key, locale);
0167:                }
0168:                if (symbols != null) {
0169:                    key = new Pair(key, symbols);
0170:                }
0171:
0172:                FastDateFormat format = (FastDateFormat) cInstanceCache
0173:                        .get(key);
0174:                if (format == null) {
0175:                    if (locale == null) {
0176:                        locale = Locale.getDefault();
0177:                    }
0178:                    if (symbols == null) {
0179:                        symbols = new DateFormatSymbols(locale);
0180:                    }
0181:                    format = new FastDateFormat(pattern, timeZone, locale,
0182:                            symbols);
0183:                    cInstanceCache.put(key, format);
0184:                }
0185:                return format;
0186:            }
0187:
0188:            /**
0189:             * @param style date style: FULL, LONG, MEDIUM, or SHORT
0190:             * @param timeZone optional time zone, overrides time zone of formatted
0191:             * date
0192:             * @param locale optional locale, overrides system locale
0193:             */
0194:            public static synchronized FastDateFormat getDateInstance(
0195:                    Object style, TimeZone timeZone, Locale locale)
0196:                    throws IllegalArgumentException {
0197:                Object key = style;
0198:
0199:                if (timeZone != null) {
0200:                    key = new Pair(key, timeZone);
0201:                }
0202:                if (locale == null) {
0203:                    key = new Pair(key, locale);
0204:                }
0205:
0206:                FastDateFormat format = (FastDateFormat) cDateInstanceCache
0207:                        .get(key);
0208:
0209:                if (format == null) {
0210:                    int ds;
0211:                    try {
0212:                        ds = ((Integer) style).intValue();
0213:                    } catch (ClassCastException e) {
0214:                        throw new IllegalArgumentException(
0215:                                "Illegal date style: " + style);
0216:                    }
0217:
0218:                    if (locale == null) {
0219:                        locale = Locale.getDefault();
0220:                    }
0221:
0222:                    try {
0223:                        String pattern = ((SimpleDateFormat) DateFormat
0224:                                .getDateInstance(ds, locale)).toPattern();
0225:                        format = getInstance(pattern, timeZone, locale);
0226:                        cDateInstanceCache.put(key, format);
0227:                    } catch (ClassCastException e) {
0228:                        throw new IllegalArgumentException(
0229:                                "No date pattern for locale: " + locale);
0230:                    }
0231:                }
0232:
0233:                return format;
0234:            }
0235:
0236:            /**
0237:             * @param style time style: FULL, LONG, MEDIUM, or SHORT
0238:             * @param timeZone optional time zone, overrides time zone of formatted
0239:             * date
0240:             * @param locale optional locale, overrides system locale
0241:             */
0242:            public static synchronized FastDateFormat getTimeInstance(
0243:                    Object style, TimeZone timeZone, Locale locale)
0244:                    throws IllegalArgumentException {
0245:                Object key = style;
0246:
0247:                if (timeZone != null) {
0248:                    key = new Pair(key, timeZone);
0249:                }
0250:                if (locale != null) {
0251:                    key = new Pair(key, locale);
0252:                }
0253:
0254:                FastDateFormat format = (FastDateFormat) cTimeInstanceCache
0255:                        .get(key);
0256:
0257:                if (format == null) {
0258:                    int ts;
0259:                    try {
0260:                        ts = ((Integer) style).intValue();
0261:                    } catch (ClassCastException e) {
0262:                        throw new IllegalArgumentException(
0263:                                "Illegal time style: " + style);
0264:                    }
0265:
0266:                    if (locale == null) {
0267:                        locale = Locale.getDefault();
0268:                    }
0269:
0270:                    try {
0271:                        String pattern = ((SimpleDateFormat) DateFormat
0272:                                .getTimeInstance(ts, locale)).toPattern();
0273:                        format = getInstance(pattern, timeZone, locale);
0274:                        cTimeInstanceCache.put(key, format);
0275:                    } catch (ClassCastException e) {
0276:                        throw new IllegalArgumentException(
0277:                                "No date pattern for locale: " + locale);
0278:                    }
0279:                }
0280:
0281:                return format;
0282:            }
0283:
0284:            /**
0285:             * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
0286:             * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
0287:             * @param timeZone optional time zone, overrides time zone of formatted
0288:             * date
0289:             * @param locale optional locale, overrides system locale
0290:             */
0291:            public static synchronized FastDateFormat getDateTimeInstance(
0292:                    Object dateStyle, Object timeStyle, TimeZone timeZone,
0293:                    Locale locale) throws IllegalArgumentException {
0294:                Object key = new Pair(dateStyle, timeStyle);
0295:
0296:                if (timeZone != null) {
0297:                    key = new Pair(key, timeZone);
0298:                }
0299:                if (locale != null) {
0300:                    key = new Pair(key, locale);
0301:                }
0302:
0303:                FastDateFormat format = (FastDateFormat) cDateTimeInstanceCache
0304:                        .get(key);
0305:
0306:                if (format == null) {
0307:                    int ds;
0308:                    try {
0309:                        ds = ((Integer) dateStyle).intValue();
0310:                    } catch (ClassCastException e) {
0311:                        throw new IllegalArgumentException(
0312:                                "Illegal date style: " + dateStyle);
0313:                    }
0314:
0315:                    int ts;
0316:                    try {
0317:                        ts = ((Integer) timeStyle).intValue();
0318:                    } catch (ClassCastException e) {
0319:                        throw new IllegalArgumentException(
0320:                                "Illegal time style: " + timeStyle);
0321:                    }
0322:
0323:                    if (locale == null) {
0324:                        locale = Locale.getDefault();
0325:                    }
0326:
0327:                    try {
0328:                        String pattern = ((SimpleDateFormat) DateFormat
0329:                                .getDateTimeInstance(ds, ts, locale))
0330:                                .toPattern();
0331:                        format = getInstance(pattern, timeZone, locale);
0332:                        cDateTimeInstanceCache.put(key, format);
0333:                    } catch (ClassCastException e) {
0334:                        throw new IllegalArgumentException(
0335:                                "No date time pattern for locale: " + locale);
0336:                    }
0337:                }
0338:
0339:                return format;
0340:            }
0341:
0342:            static synchronized String getTimeZoneDisplay(TimeZone tz,
0343:                    boolean daylight, int style, Locale locale) {
0344:                Object key = new TimeZoneDisplayKey(tz, daylight, style, locale);
0345:                String value = (String) cTimeZoneDisplayCache.get(key);
0346:                if (value == null) {
0347:                    // This is a very slow call, so cache the results.
0348:                    value = tz.getDisplayName(daylight, style, locale);
0349:                    cTimeZoneDisplayCache.put(key, value);
0350:                }
0351:                return value;
0352:            }
0353:
0354:            private static synchronized String getDefaultPattern() {
0355:                if (cDefaultPattern == null) {
0356:                    cDefaultPattern = new SimpleDateFormat().toPattern();
0357:                }
0358:                return cDefaultPattern;
0359:            }
0360:
0361:            /**
0362:             * Returns a list of Rules.
0363:             */
0364:            private static List parse(String pattern, TimeZone timeZone,
0365:                    Locale locale, DateFormatSymbols symbols) {
0366:                List rules = new ArrayList();
0367:
0368:                String[] ERAs = symbols.getEras();
0369:                String[] months = symbols.getMonths();
0370:                String[] shortMonths = symbols.getShortMonths();
0371:                String[] weekdays = symbols.getWeekdays();
0372:                String[] shortWeekdays = symbols.getShortWeekdays();
0373:                String[] AmPmStrings = symbols.getAmPmStrings();
0374:
0375:                int length = pattern.length();
0376:                int[] indexRef = new int[1];
0377:
0378:                for (int i = 0; i < length; i++) {
0379:                    indexRef[0] = i;
0380:                    String token = parseToken(pattern, indexRef);
0381:                    i = indexRef[0];
0382:
0383:                    int tokenLen = token.length();
0384:                    if (tokenLen == 0) {
0385:                        break;
0386:                    }
0387:
0388:                    Rule rule;
0389:                    char c = token.charAt(0);
0390:
0391:                    switch (c) {
0392:                    case 'G': // era designator (text)
0393:                        rule = new TextField(Calendar.ERA, ERAs);
0394:                        break;
0395:                    case 'y': // year (number)
0396:                        if (tokenLen >= 4) {
0397:                            rule = new UnpaddedNumberField(Calendar.YEAR);
0398:                        } else {
0399:                            rule = new TwoDigitYearField();
0400:                        }
0401:                        break;
0402:                    case 'M': // month in year (text and number)
0403:                        if (tokenLen >= 4) {
0404:                            rule = new TextField(Calendar.MONTH, months);
0405:                        } else if (tokenLen == 3) {
0406:                            rule = new TextField(Calendar.MONTH, shortMonths);
0407:                        } else if (tokenLen == 2) {
0408:                            rule = new TwoDigitMonthField();
0409:                        } else {
0410:                            rule = new UnpaddedMonthField();
0411:                        }
0412:                        break;
0413:                    case 'd': // day in month (number)
0414:                        rule = selectNumberRule(Calendar.DAY_OF_MONTH, tokenLen);
0415:                        break;
0416:                    case 'h': // hour in am/pm (number, 1..12)
0417:                        rule = new TwelveHourField(selectNumberRule(
0418:                                Calendar.HOUR, tokenLen));
0419:                        break;
0420:                    case 'H': // hour in day (number, 0..23)
0421:                        rule = selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen);
0422:                        break;
0423:                    case 'm': // minute in hour (number)
0424:                        rule = selectNumberRule(Calendar.MINUTE, tokenLen);
0425:                        break;
0426:                    case 's': // second in minute (number)
0427:                        rule = selectNumberRule(Calendar.SECOND, tokenLen);
0428:                        break;
0429:                    case 'S': // millisecond (number)
0430:                        rule = selectNumberRule(Calendar.MILLISECOND, tokenLen);
0431:                        break;
0432:                    case 'E': // day in week (text)
0433:                        rule = new TextField(Calendar.DAY_OF_WEEK,
0434:                                tokenLen < 4 ? shortWeekdays : weekdays);
0435:                        break;
0436:                    case 'D': // day in year (number)
0437:                        rule = selectNumberRule(Calendar.DAY_OF_YEAR, tokenLen);
0438:                        break;
0439:                    case 'F': // day of week in month (number)
0440:                        rule = selectNumberRule(Calendar.DAY_OF_WEEK_IN_MONTH,
0441:                                tokenLen);
0442:                        break;
0443:                    case 'w': // week in year (number)
0444:                        rule = selectNumberRule(Calendar.WEEK_OF_YEAR, tokenLen);
0445:                        break;
0446:                    case 'W': // week in month (number)
0447:                        rule = selectNumberRule(Calendar.WEEK_OF_MONTH,
0448:                                tokenLen);
0449:                        break;
0450:                    case 'a': // am/pm marker (text)
0451:                        rule = new TextField(Calendar.AM_PM, AmPmStrings);
0452:                        break;
0453:                    case 'k': // hour in day (1..24)
0454:                        rule = new TwentyFourHourField(selectNumberRule(
0455:                                Calendar.HOUR_OF_DAY, tokenLen));
0456:                        break;
0457:                    case 'K': // hour in am/pm (0..11)
0458:                        rule = selectNumberRule(Calendar.HOUR, tokenLen);
0459:                        break;
0460:                    case 'z': // time zone (text)
0461:                        if (tokenLen >= 4) {
0462:                            rule = new TimeZoneRule(timeZone, locale,
0463:                                    TimeZone.LONG);
0464:                        } else {
0465:                            rule = new TimeZoneRule(timeZone, locale,
0466:                                    TimeZone.SHORT);
0467:                        }
0468:                        break;
0469:                    case '\'': // literal text
0470:                        String sub = token.substring(1);
0471:                        if (sub.length() == 1) {
0472:                            rule = new CharacterLiteral(sub.charAt(0));
0473:                        } else {
0474:                            rule = new StringLiteral(new String(sub));
0475:                        }
0476:                        break;
0477:                    default:
0478:                        throw new IllegalArgumentException(
0479:                                "Illegal pattern component: " + token);
0480:                    }
0481:
0482:                    rules.add(rule);
0483:                }
0484:
0485:                return rules;
0486:            }
0487:
0488:            private static String parseToken(String pattern, int[] indexRef) {
0489:                StringBuffer buf = new StringBuffer();
0490:
0491:                int i = indexRef[0];
0492:                int length = pattern.length();
0493:
0494:                char c = pattern.charAt(i);
0495:                if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
0496:                    // Scan a run of the same character, which indicates a time
0497:                    // pattern.
0498:                    buf.append(c);
0499:
0500:                    while (i + 1 < length) {
0501:                        char peek = pattern.charAt(i + 1);
0502:                        if (peek == c) {
0503:                            buf.append(c);
0504:                            i++;
0505:                        } else {
0506:                            break;
0507:                        }
0508:                    }
0509:                } else {
0510:                    // This will identify token as text.
0511:                    buf.append('\'');
0512:
0513:                    boolean inLiteral = false;
0514:
0515:                    for (; i < length; i++) {
0516:                        c = pattern.charAt(i);
0517:
0518:                        if (c == '\'') {
0519:                            if (i + 1 < length && pattern.charAt(i + 1) == '\'') {
0520:                                // '' is treated as escaped '
0521:                                i++;
0522:                                buf.append(c);
0523:                            } else {
0524:                                inLiteral = !inLiteral;
0525:                            }
0526:                        } else if (!inLiteral
0527:                                && (c >= 'A' && c <= 'Z' || c >= 'a'
0528:                                        && c <= 'z')) {
0529:                            i--;
0530:                            break;
0531:                        } else {
0532:                            buf.append(c);
0533:                        }
0534:                    }
0535:                }
0536:
0537:                indexRef[0] = i;
0538:                return buf.toString();
0539:            }
0540:
0541:            private static NumberRule selectNumberRule(int field, int padding) {
0542:                switch (padding) {
0543:                case 1:
0544:                    return new UnpaddedNumberField(field);
0545:                case 2:
0546:                    return new TwoDigitNumberField(field);
0547:                default:
0548:                    return new PaddedNumberField(field, padding);
0549:                }
0550:            }
0551:
0552:            private final String mPattern;
0553:            private final TimeZone mTimeZone;
0554:            private final Locale mLocale;
0555:            private final Rule[] mRules;
0556:            private final int mMaxLengthEstimate;
0557:
0558:            private FastDateFormat() {
0559:                this (getDefaultPattern(), null, null, null);
0560:            }
0561:
0562:            /**
0563:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0564:             */
0565:            private FastDateFormat(String pattern)
0566:                    throws IllegalArgumentException {
0567:                this (pattern, null, null, null);
0568:            }
0569:
0570:            /**
0571:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0572:             * @param timeZone optional time zone, overrides time zone of formatted
0573:             * date
0574:             */
0575:            private FastDateFormat(String pattern, TimeZone timeZone)
0576:                    throws IllegalArgumentException {
0577:                this (pattern, timeZone, null, null);
0578:            }
0579:
0580:            /**
0581:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0582:             * @param locale optional locale, overrides system locale
0583:             */
0584:            private FastDateFormat(String pattern, Locale locale)
0585:                    throws IllegalArgumentException {
0586:                this (pattern, null, locale, null);
0587:            }
0588:
0589:            /**
0590:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0591:             * @param symbols optional date format symbols, overrides symbols for
0592:             * system locale
0593:             */
0594:            private FastDateFormat(String pattern, DateFormatSymbols symbols)
0595:                    throws IllegalArgumentException {
0596:                this (pattern, null, null, symbols);
0597:            }
0598:
0599:            /**
0600:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0601:             * @param timeZone optional time zone, overrides time zone of formatted
0602:             * date
0603:             * @param locale optional locale, overrides system locale
0604:             */
0605:            private FastDateFormat(String pattern, TimeZone timeZone,
0606:                    Locale locale) throws IllegalArgumentException {
0607:                this (pattern, timeZone, locale, null);
0608:            }
0609:
0610:            /**
0611:             * @param pattern {@link java.text.SimpleDateFormat} compatible pattern
0612:             * @param timeZone optional time zone, overrides time zone of formatted
0613:             * date
0614:             * @param locale optional locale, overrides system locale
0615:             * @param symbols optional date format symbols, overrides symbols for
0616:             * provided locale
0617:             */
0618:            private FastDateFormat(String pattern, TimeZone timeZone,
0619:                    Locale locale, DateFormatSymbols symbols)
0620:                    throws IllegalArgumentException {
0621:                if (locale == null) {
0622:                    locale = Locale.getDefault();
0623:                }
0624:
0625:                mPattern = pattern;
0626:                mTimeZone = timeZone;
0627:                mLocale = locale;
0628:
0629:                if (symbols == null) {
0630:                    symbols = new DateFormatSymbols(locale);
0631:                }
0632:
0633:                List rulesList = parse(pattern, timeZone, locale, symbols);
0634:                mRules = (Rule[]) rulesList.toArray(new Rule[rulesList.size()]);
0635:
0636:                int len = 0;
0637:                for (int i = mRules.length; --i >= 0;) {
0638:                    len += mRules[i].estimateLength();
0639:                }
0640:
0641:                mMaxLengthEstimate = len;
0642:            }
0643:
0644:            public String format(Date date) {
0645:                Calendar c = new GregorianCalendar(cDefaultTimeZone);
0646:                c.setTime(date);
0647:                if (mTimeZone != null) {
0648:                    c.setTimeZone(mTimeZone);
0649:                }
0650:                return applyRules(c, new StringBuffer(mMaxLengthEstimate))
0651:                        .toString();
0652:            }
0653:
0654:            public String format(Calendar calendar) {
0655:                return format(calendar, new StringBuffer(mMaxLengthEstimate))
0656:                        .toString();
0657:            }
0658:
0659:            public StringBuffer format(Date date, StringBuffer buf) {
0660:                Calendar c = new GregorianCalendar(cDefaultTimeZone);
0661:                c.setTime(date);
0662:                if (mTimeZone != null) {
0663:                    c.setTimeZone(mTimeZone);
0664:                }
0665:                return applyRules(c, buf);
0666:            }
0667:
0668:            public StringBuffer format(Calendar calendar, StringBuffer buf) {
0669:                if (mTimeZone != null) {
0670:                    calendar = (Calendar) calendar.clone();
0671:                    calendar.setTimeZone(mTimeZone);
0672:                }
0673:                return applyRules(calendar, buf);
0674:            }
0675:
0676:            private StringBuffer applyRules(Calendar calendar, StringBuffer buf) {
0677:                Rule[] rules = mRules;
0678:                int len = mRules.length;
0679:                for (int i = 0; i < len; i++) {
0680:                    rules[i].appendTo(buf, calendar);
0681:                }
0682:                return buf;
0683:            }
0684:
0685:            public String getPattern() {
0686:                return mPattern;
0687:            }
0688:
0689:            /**
0690:             * Returns the time zone used by this formatter, or null if time zone of
0691:             * formatted dates is used instead.
0692:             */
0693:            public TimeZone getTimeZone() {
0694:                return mTimeZone;
0695:            }
0696:
0697:            public Locale getLocale() {
0698:                return mLocale;
0699:            }
0700:
0701:            /**
0702:             * Returns an estimate for the maximum length date that this date
0703:             * formatter will produce. The actual formatted length will almost always
0704:             * be less than or equal to this amount.
0705:             */
0706:            public int getMaxLengthEstimate() {
0707:                return mMaxLengthEstimate;
0708:            }
0709:
0710:            private interface Rule {
0711:                int estimateLength();
0712:
0713:                void appendTo(StringBuffer buffer, Calendar calendar);
0714:            }
0715:
0716:            private interface NumberRule extends Rule {
0717:                void appendTo(StringBuffer buffer, int value);
0718:            }
0719:
0720:            private static class CharacterLiteral implements  Rule {
0721:                private final char mValue;
0722:
0723:                CharacterLiteral(char value) {
0724:                    mValue = value;
0725:                }
0726:
0727:                public int estimateLength() {
0728:                    return 1;
0729:                }
0730:
0731:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0732:                    buffer.append(mValue);
0733:                }
0734:            }
0735:
0736:            private static class StringLiteral implements  Rule {
0737:                private final String mValue;
0738:
0739:                StringLiteral(String value) {
0740:                    mValue = value;
0741:                }
0742:
0743:                public int estimateLength() {
0744:                    return mValue.length();
0745:                }
0746:
0747:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0748:                    buffer.append(mValue);
0749:                }
0750:            }
0751:
0752:            private static class TextField implements  Rule {
0753:                private final int mField;
0754:                private final String[] mValues;
0755:
0756:                TextField(int field, String[] values) {
0757:                    mField = field;
0758:                    mValues = values;
0759:                }
0760:
0761:                public int estimateLength() {
0762:                    int max = 0;
0763:                    for (int i = mValues.length; --i >= 0;) {
0764:                        int len = mValues[i].length();
0765:                        if (len > max) {
0766:                            max = len;
0767:                        }
0768:                    }
0769:                    return max;
0770:                }
0771:
0772:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0773:                    buffer.append(mValues[calendar.get(mField)]);
0774:                }
0775:            }
0776:
0777:            private static class UnpaddedNumberField implements  NumberRule {
0778:                private final int mField;
0779:
0780:                UnpaddedNumberField(int field) {
0781:                    mField = field;
0782:                }
0783:
0784:                public int estimateLength() {
0785:                    return 4;
0786:                }
0787:
0788:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0789:                    appendTo(buffer, calendar.get(mField));
0790:                }
0791:
0792:                public final void appendTo(StringBuffer buffer, int value) {
0793:                    if (value < 10) {
0794:                        buffer.append((char) (value + '0'));
0795:                    } else if (value < 100) {
0796:                        buffer.append((char) (value / 10 + '0'));
0797:                        buffer.append((char) (value % 10 + '0'));
0798:                    } else {
0799:                        buffer.append(Integer.toString(value));
0800:                    }
0801:                }
0802:            }
0803:
0804:            private static class UnpaddedMonthField implements  NumberRule {
0805:                UnpaddedMonthField() {
0806:                }
0807:
0808:                public int estimateLength() {
0809:                    return 2;
0810:                }
0811:
0812:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0813:                    appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
0814:                }
0815:
0816:                public final void appendTo(StringBuffer buffer, int value) {
0817:                    if (value < 10) {
0818:                        buffer.append((char) (value + '0'));
0819:                    } else {
0820:                        buffer.append((char) (value / 10 + '0'));
0821:                        buffer.append((char) (value % 10 + '0'));
0822:                    }
0823:                }
0824:            }
0825:
0826:            private static class PaddedNumberField implements  NumberRule {
0827:                private final int mField;
0828:                private final int mSize;
0829:
0830:                PaddedNumberField(int field, int size) {
0831:                    if (size < 3) {
0832:                        // Should use UnpaddedNumberField or TwoDigitNumberField.
0833:                        throw new IllegalArgumentException();
0834:                    }
0835:                    mField = field;
0836:                    mSize = size;
0837:                }
0838:
0839:                public int estimateLength() {
0840:                    return 4;
0841:                }
0842:
0843:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0844:                    appendTo(buffer, calendar.get(mField));
0845:                }
0846:
0847:                public final void appendTo(StringBuffer buffer, int value) {
0848:                    if (value < 100) {
0849:                        for (int i = mSize; --i >= 2;) {
0850:                            buffer.append('0');
0851:                        }
0852:                        buffer.append((char) (value / 10 + '0'));
0853:                        buffer.append((char) (value % 10 + '0'));
0854:                    } else {
0855:                        int digits;
0856:                        if (value < 1000) {
0857:                            digits = 3;
0858:                        } else {
0859:                            digits = (int) (Math.log(value) / LOG_10) + 1;
0860:                        }
0861:                        for (int i = mSize; --i >= digits;) {
0862:                            buffer.append('0');
0863:                        }
0864:                        buffer.append(Integer.toString(value));
0865:                    }
0866:                }
0867:            }
0868:
0869:            private static class TwoDigitNumberField implements  NumberRule {
0870:                private final int mField;
0871:
0872:                TwoDigitNumberField(int field) {
0873:                    mField = field;
0874:                }
0875:
0876:                public int estimateLength() {
0877:                    return 2;
0878:                }
0879:
0880:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0881:                    appendTo(buffer, calendar.get(mField));
0882:                }
0883:
0884:                public final void appendTo(StringBuffer buffer, int value) {
0885:                    if (value < 100) {
0886:                        buffer.append((char) (value / 10 + '0'));
0887:                        buffer.append((char) (value % 10 + '0'));
0888:                    } else {
0889:                        buffer.append(Integer.toString(value));
0890:                    }
0891:                }
0892:            }
0893:
0894:            private static class TwoDigitYearField implements  NumberRule {
0895:                TwoDigitYearField() {
0896:                }
0897:
0898:                public int estimateLength() {
0899:                    return 2;
0900:                }
0901:
0902:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0903:                    appendTo(buffer, calendar.get(Calendar.YEAR) % 100);
0904:                }
0905:
0906:                public final void appendTo(StringBuffer buffer, int value) {
0907:                    buffer.append((char) (value / 10 + '0'));
0908:                    buffer.append((char) (value % 10 + '0'));
0909:                }
0910:            }
0911:
0912:            private static class TwoDigitMonthField implements  NumberRule {
0913:                TwoDigitMonthField() {
0914:                }
0915:
0916:                public int estimateLength() {
0917:                    return 2;
0918:                }
0919:
0920:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0921:                    appendTo(buffer, calendar.get(Calendar.MONTH) + 1);
0922:                }
0923:
0924:                public final void appendTo(StringBuffer buffer, int value) {
0925:                    buffer.append((char) (value / 10 + '0'));
0926:                    buffer.append((char) (value % 10 + '0'));
0927:                }
0928:            }
0929:
0930:            private static class TwelveHourField implements  NumberRule {
0931:                private final NumberRule mRule;
0932:
0933:                TwelveHourField(NumberRule rule) {
0934:                    mRule = rule;
0935:                }
0936:
0937:                public int estimateLength() {
0938:                    return mRule.estimateLength();
0939:                }
0940:
0941:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0942:                    int value = calendar.get(Calendar.HOUR);
0943:                    if (value == 0) {
0944:                        value = calendar.getLeastMaximum(Calendar.HOUR) + 1;
0945:                    }
0946:                    mRule.appendTo(buffer, value);
0947:                }
0948:
0949:                public void appendTo(StringBuffer buffer, int value) {
0950:                    mRule.appendTo(buffer, value);
0951:                }
0952:            }
0953:
0954:            private static class TwentyFourHourField implements  NumberRule {
0955:                private final NumberRule mRule;
0956:
0957:                TwentyFourHourField(NumberRule rule) {
0958:                    mRule = rule;
0959:                }
0960:
0961:                public int estimateLength() {
0962:                    return mRule.estimateLength();
0963:                }
0964:
0965:                public void appendTo(StringBuffer buffer, Calendar calendar) {
0966:                    int value = calendar.get(Calendar.HOUR_OF_DAY);
0967:                    if (value == 0) {
0968:                        value = calendar.getMaximum(Calendar.HOUR_OF_DAY) + 1;
0969:                    }
0970:                    mRule.appendTo(buffer, value);
0971:                }
0972:
0973:                public void appendTo(StringBuffer buffer, int value) {
0974:                    mRule.appendTo(buffer, value);
0975:                }
0976:            }
0977:
0978:            private static class TimeZoneRule implements  Rule {
0979:                private final TimeZone mTimeZone;
0980:                private final Locale mLocale;
0981:                private final int mStyle;
0982:                private final String mStandard;
0983:                private final String mDaylight;
0984:
0985:                TimeZoneRule(TimeZone timeZone, Locale locale, int style) {
0986:                    mTimeZone = timeZone;
0987:                    mLocale = locale;
0988:                    mStyle = style;
0989:
0990:                    if (timeZone != null) {
0991:                        mStandard = getTimeZoneDisplay(timeZone, false, style,
0992:                                locale);
0993:                        mDaylight = getTimeZoneDisplay(timeZone, true, style,
0994:                                locale);
0995:                    } else {
0996:                        mStandard = null;
0997:                        mDaylight = null;
0998:                    }
0999:                }
1000:
1001:                public int estimateLength() {
1002:                    if (mTimeZone != null) {
1003:                        return Math.max(mStandard.length(), mDaylight.length());
1004:                    } else if (mStyle == TimeZone.SHORT) {
1005:                        return 4;
1006:                    } else {
1007:                        return 40;
1008:                    }
1009:                }
1010:
1011:                public void appendTo(StringBuffer buffer, Calendar calendar) {
1012:                    TimeZone timeZone;
1013:                    if ((timeZone = mTimeZone) != null) {
1014:                        if (timeZone.useDaylightTime()
1015:                                && calendar.get(Calendar.DST_OFFSET) != 0) {
1016:
1017:                            buffer.append(mDaylight);
1018:                        } else {
1019:                            buffer.append(mStandard);
1020:                        }
1021:                    } else {
1022:                        timeZone = calendar.getTimeZone();
1023:                        if (timeZone.useDaylightTime()
1024:                                && calendar.get(Calendar.DST_OFFSET) != 0) {
1025:
1026:                            buffer.append(getTimeZoneDisplay(timeZone, true,
1027:                                    mStyle, mLocale));
1028:                        } else {
1029:                            buffer.append(getTimeZoneDisplay(timeZone, false,
1030:                                    mStyle, mLocale));
1031:                        }
1032:                    }
1033:                }
1034:            }
1035:
1036:            private static class TimeZoneDisplayKey {
1037:                private final TimeZone mTimeZone;
1038:                private final int mStyle;
1039:                private final Locale mLocale;
1040:
1041:                TimeZoneDisplayKey(TimeZone timeZone, boolean daylight,
1042:                        int style, Locale locale) {
1043:                    mTimeZone = timeZone;
1044:                    if (daylight) {
1045:                        style |= 0x80000000;
1046:                    }
1047:                    mStyle = style;
1048:                    mLocale = locale;
1049:                }
1050:
1051:                public int hashCode() {
1052:                    return mStyle * 31 + mLocale.hashCode();
1053:                }
1054:
1055:                public boolean equals(Object obj) {
1056:                    if (this  == obj) {
1057:                        return true;
1058:                    }
1059:                    if (obj instanceof  TimeZoneDisplayKey) {
1060:                        TimeZoneDisplayKey other = (TimeZoneDisplayKey) obj;
1061:                        return mTimeZone.equals(other.mTimeZone)
1062:                                && mStyle == other.mStyle
1063:                                && mLocale.equals(other.mLocale);
1064:                    }
1065:                    return false;
1066:                }
1067:            }
1068:
1069:            private static class Pair implements  Comparable,
1070:                    java.io.Serializable {
1071:                private final Object mObj1;
1072:                private final Object mObj2;
1073:
1074:                public Pair(Object obj1, Object obj2) {
1075:                    mObj1 = obj1;
1076:                    mObj2 = obj2;
1077:                }
1078:
1079:                public int compareTo(Object obj) {
1080:                    if (this  == obj) {
1081:                        return 0;
1082:                    }
1083:
1084:                    Pair other = (Pair) obj;
1085:
1086:                    Object a = mObj1;
1087:                    Object b = other.mObj1;
1088:
1089:                    firstTest: {
1090:                        if (a == null) {
1091:                            if (b != null) {
1092:                                return 1;
1093:                            }
1094:                            // Both a and b are null.
1095:                            break firstTest;
1096:                        } else {
1097:                            if (b == null) {
1098:                                return -1;
1099:                            }
1100:                        }
1101:
1102:                        int result = ((Comparable) a).compareTo(b);
1103:
1104:                        if (result != 0) {
1105:                            return result;
1106:                        }
1107:                    }
1108:
1109:                    a = mObj2;
1110:                    b = other.mObj2;
1111:
1112:                    if (a == null) {
1113:                        if (b != null) {
1114:                            return 1;
1115:                        }
1116:                        // Both a and b are null.
1117:                        return 0;
1118:                    } else {
1119:                        if (b == null) {
1120:                            return -1;
1121:                        }
1122:                    }
1123:
1124:                    return ((Comparable) a).compareTo(b);
1125:                }
1126:
1127:                public boolean equals(Object obj) {
1128:                    if (this  == obj) {
1129:                        return true;
1130:                    }
1131:
1132:                    if (!(obj instanceof  Pair)) {
1133:                        return false;
1134:                    }
1135:
1136:                    Pair key = (Pair) obj;
1137:
1138:                    return (mObj1 == null ? key.mObj1 == null : mObj1
1139:                            .equals(key.mObj1))
1140:                            && (mObj2 == null ? key.mObj2 == null : mObj2
1141:                                    .equals(key.mObj2));
1142:                }
1143:
1144:                public int hashCode() {
1145:                    return (mObj1 == null ? 0 : mObj1.hashCode())
1146:                            + (mObj2 == null ? 0 : mObj2.hashCode());
1147:                }
1148:
1149:                public String toString() {
1150:                    return "[" + mObj1 + ':' + mObj2 + ']';
1151:                }
1152:            }
1153:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.