Source Code Cross Referenced for TimeZone.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1996-2005 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        /*
027         * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
028         * (C) Copyright IBM Corp. 1996 - All Rights Reserved
029         *
030         *   The original version of this source code and documentation is copyrighted
031         * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
032         * materials are provided under terms of a License Agreement between Taligent
033         * and Sun. This technology is protected by multiple US and International
034         * patents. This notice and attribution to Taligent may not be removed.
035         *   Taligent is a registered trademark of Taligent, Inc.
036         *
037         */
038
039        package java.util;
040
041        import java.io.Serializable;
042        import java.lang.ref.SoftReference;
043        import java.security.AccessController;
044        import java.security.PrivilegedAction;
045        import java.util.concurrent.ConcurrentHashMap;
046        import sun.security.action.GetPropertyAction;
047        import sun.util.TimeZoneNameUtility;
048        import sun.util.calendar.ZoneInfo;
049        import sun.util.calendar.ZoneInfoFile;
050
051        /**
052         * <code>TimeZone</code> represents a time zone offset, and also figures out daylight
053         * savings.
054         *
055         * <p>
056         * Typically, you get a <code>TimeZone</code> using <code>getDefault</code>
057         * which creates a <code>TimeZone</code> based on the time zone where the program
058         * is running. For example, for a program running in Japan, <code>getDefault</code>
059         * creates a <code>TimeZone</code> object based on Japanese Standard Time.
060         *
061         * <p>
062         * You can also get a <code>TimeZone</code> using <code>getTimeZone</code>
063         * along with a time zone ID. For instance, the time zone ID for the
064         * U.S. Pacific Time zone is "America/Los_Angeles". So, you can get a
065         * U.S. Pacific Time <code>TimeZone</code> object with:
066         * <blockquote><pre>
067         * TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
068         * </pre></blockquote>
069         * You can use the <code>getAvailableIDs</code> method to iterate through
070         * all the supported time zone IDs. You can then choose a
071         * supported ID to get a <code>TimeZone</code>.
072         * If the time zone you want is not represented by one of the
073         * supported IDs, then a custom time zone ID can be specified to
074         * produce a TimeZone. The syntax of a custom time zone ID is:
075         *
076         * <blockquote><pre>
077         * <a name="CustomID"><i>CustomID:</i></a>
078         *         <code>GMT</code> <i>Sign</i> <i>Hours</i> <code>:</code> <i>Minutes</i>
079         *         <code>GMT</code> <i>Sign</i> <i>Hours</i> <i>Minutes</i>
080         *         <code>GMT</code> <i>Sign</i> <i>Hours</i>
081         * <i>Sign:</i> one of
082         *         <code>+ -</code>
083         * <i>Hours:</i>
084         *         <i>Digit</i>
085         *         <i>Digit</i> <i>Digit</i>
086         * <i>Minutes:</i>
087         *         <i>Digit</i> <i>Digit</i>
088         * <i>Digit:</i> one of
089         *         <code>0 1 2 3 4 5 6 7 8 9</code>
090         * </pre></blockquote>
091         *
092         * <i>Hours</i> must be between 0 to 23 and <i>Minutes</i> must be
093         * between 00 to 59.  For example, "GMT+10" and "GMT+0010" mean ten
094         * hours and ten minutes ahead of GMT, respectively.
095         * <p>
096         * The format is locale independent and digits must be taken from the
097         * Basic Latin block of the Unicode standard. No daylight saving time
098         * transition schedule can be specified with a custom time zone ID. If
099         * the specified string doesn't match the syntax, <code>"GMT"</code>
100         * is used.
101         * <p>
102         * When creating a <code>TimeZone</code>, the specified custom time
103         * zone ID is normalized in the following syntax:
104         * <blockquote><pre>
105         * <a name="NormalizedCustomID"><i>NormalizedCustomID:</i></a>
106         *         <code>GMT</code> <i>Sign</i> <i>TwoDigitHours</i> <code>:</code> <i>Minutes</i>
107         * <i>Sign:</i> one of
108         *         <code>+ -</code>
109         * <i>TwoDigitHours:</i>
110         *         <i>Digit</i> <i>Digit</i>
111         * <i>Minutes:</i>
112         *         <i>Digit</i> <i>Digit</i>
113         * <i>Digit:</i> one of
114         *         <code>0 1 2 3 4 5 6 7 8 9</code>
115         * </pre></blockquote>
116         * For example, TimeZone.getTimeZone("GMT-8").getID() returns "GMT-08:00".
117         *
118         * <h4>Three-letter time zone IDs</h4>
119         * 
120         * For compatibility with JDK 1.1.x, some other three-letter time zone IDs
121         * (such as "PST", "CTT", "AST") are also supported. However, <strong>their
122         * use is deprecated</strong> because the same abbreviation is often used
123         * for multiple time zones (for example, "CST" could be U.S. "Central Standard
124         * Time" and "China Standard Time"), and the Java platform can then only
125         * recognize one of them.
126         *
127         *
128         * @see          Calendar
129         * @see          GregorianCalendar
130         * @see          SimpleTimeZone
131         * @version      1.81 05/05/07
132         * @author       Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
133         * @since        JDK1.1
134         */
135        abstract public class TimeZone implements  Serializable, Cloneable {
136            /**
137             * Sole constructor.  (For invocation by subclass constructors, typically
138             * implicit.)
139             */
140            public TimeZone() {
141            }
142
143            /**
144             * A style specifier for <code>getDisplayName()</code> indicating
145             * a short name, such as "PST."
146             * @see #LONG
147             * @since 1.2
148             */
149            public static final int SHORT = 0;
150
151            /**
152             * A style specifier for <code>getDisplayName()</code> indicating
153             * a long name, such as "Pacific Standard Time."
154             * @see #SHORT
155             * @since 1.2
156             */
157            public static final int LONG = 1;
158
159            // Constants used internally; unit is milliseconds
160            private static final int ONE_MINUTE = 60 * 1000;
161            private static final int ONE_HOUR = 60 * ONE_MINUTE;
162            private static final int ONE_DAY = 24 * ONE_HOUR;
163
164            /**
165             * Cache to hold the SimpleDateFormat objects for a Locale.
166             */
167            private static Hashtable cachedLocaleData = new Hashtable(3);
168
169            // Proclaim serialization compatibility with JDK 1.1
170            static final long serialVersionUID = 3581463369166924961L;
171
172            /**
173             * Gets the time zone offset, for current date, modified in case of
174             * daylight savings. This is the offset to add to UTC to get local time.
175             * <p>
176             * This method returns a historically correct offset if an
177             * underlying <code>TimeZone</code> implementation subclass
178             * supports historical Daylight Saving Time schedule and GMT
179             * offset changes.
180             *
181             * @param era the era of the given date.
182             * @param year the year in the given date.
183             * @param month the month in the given date.
184             * Month is 0-based. e.g., 0 for January.
185             * @param day the day-in-month of the given date.
186             * @param dayOfWeek the day-of-week of the given date.
187             * @param milliseconds the milliseconds in day in <em>standard</em>
188             * local time.
189             *
190             * @return the offset in milliseconds to add to GMT to get local time.
191             *
192             * @see Calendar#ZONE_OFFSET
193             * @see Calendar#DST_OFFSET
194             */
195            public abstract int getOffset(int era, int year, int month,
196                    int day, int dayOfWeek, int milliseconds);
197
198            /**
199             * Returns the offset of this time zone from UTC at the specified
200             * date. If Daylight Saving Time is in effect at the specified
201             * date, the offset value is adjusted with the amount of daylight
202             * saving.
203             * <p>
204             * This method returns a historically correct offset value if an
205             * underlying TimeZone implementation subclass supports historical
206             * Daylight Saving Time schedule and GMT offset changes.
207             *
208             * @param date the date represented in milliseconds since January 1, 1970 00:00:00 GMT
209             * @return the amount of time in milliseconds to add to UTC to get local time.
210             *
211             * @see Calendar#ZONE_OFFSET
212             * @see Calendar#DST_OFFSET
213             * @since 1.4
214             */
215            public int getOffset(long date) {
216                if (inDaylightTime(new Date(date))) {
217                    return getRawOffset() + getDSTSavings();
218                }
219                return getRawOffset();
220            }
221
222            /**
223             * Gets the raw GMT offset and the amount of daylight saving of this
224             * time zone at the given time.
225             * @param date the milliseconds (since January 1, 1970,
226             * 00:00:00.000 GMT) at which the time zone offset and daylight
227             * saving amount are found
228             * @param offset an array of int where the raw GMT offset
229             * (offset[0]) and daylight saving amount (offset[1]) are stored,
230             * or null if those values are not needed. The method assumes that
231             * the length of the given array is two or larger.
232             * @return the total amount of the raw GMT offset and daylight
233             * saving at the specified date.
234             *
235             * @see Calendar#ZONE_OFFSET
236             * @see Calendar#DST_OFFSET
237             */
238            int getOffsets(long date, int[] offsets) {
239                int rawoffset = getRawOffset();
240                int dstoffset = 0;
241                if (inDaylightTime(new Date(date))) {
242                    dstoffset = getDSTSavings();
243                }
244                if (offsets != null) {
245                    offsets[0] = rawoffset;
246                    offsets[1] = dstoffset;
247                }
248                return rawoffset + dstoffset;
249            }
250
251            /**
252             * Sets the base time zone offset to GMT.
253             * This is the offset to add to UTC to get local time.
254             * <p>
255             * If an underlying <code>TimeZone</code> implementation subclass
256             * supports historical GMT offset changes, the specified GMT
257             * offset is set as the latest GMT offset and the difference from
258             * the known latest GMT offset value is used to adjust all
259             * historical GMT offset values.
260             *
261             * @param offsetMillis the given base time zone offset to GMT.
262             */
263            abstract public void setRawOffset(int offsetMillis);
264
265            /**
266             * Returns the amount of time in milliseconds to add to UTC to get
267             * standard time in this time zone. Because this value is not
268             * affected by daylight saving time, it is called <I>raw
269             * offset</I>.
270             * <p>
271             * If an underlying <code>TimeZone</code> implementation subclass
272             * supports historical GMT offset changes, the method returns the
273             * raw offset value of the current date. In Honolulu, for example,
274             * its raw offset changed from GMT-10:30 to GMT-10:00 in 1947, and
275             * this method always returns -36000000 milliseconds (i.e., -10
276             * hours).
277             *
278             * @return the amount of raw offset time in milliseconds to add to UTC.
279             * @see Calendar#ZONE_OFFSET
280             */
281            public abstract int getRawOffset();
282
283            /**
284             * Gets the ID of this time zone.
285             * @return the ID of this time zone.
286             */
287            public String getID() {
288                return ID;
289            }
290
291            /**
292             * Sets the time zone ID. This does not change any other data in
293             * the time zone object.
294             * @param ID the new time zone ID.
295             */
296            public void setID(String ID) {
297                if (ID == null) {
298                    throw new NullPointerException();
299                }
300                this .ID = ID;
301            }
302
303            /**
304             * Returns a name of this time zone suitable for presentation to the user
305             * in the default locale.
306             * This method returns the long name, not including daylight savings.
307             * If the display name is not available for the locale,
308             * then this method returns a string in the 
309             * <a href="#NormalizedCustomID">normalized custom ID format</a>.
310             * @return the human-readable name of this time zone in the default locale.
311             * @since 1.2
312             */
313            public final String getDisplayName() {
314                return getDisplayName(false, LONG, Locale.getDefault());
315            }
316
317            /**
318             * Returns a name of this time zone suitable for presentation to the user
319             * in the specified locale.
320             * This method returns the long name, not including daylight savings.
321             * If the display name is not available for the locale,
322             * then this method returns a string in the 
323             * <a href="#NormalizedCustomID">normalized custom ID format</a>.
324             * @param locale the locale in which to supply the display name.
325             * @return the human-readable name of this time zone in the given locale.
326             * @since 1.2
327             */
328            public final String getDisplayName(Locale locale) {
329                return getDisplayName(false, LONG, locale);
330            }
331
332            /**
333             * Returns a name of this time zone suitable for presentation to the user
334             * in the default locale.
335             * If the display name is not available for the locale, then this
336             * method returns a string in the 
337             * <a href="#NormalizedCustomID">normalized custom ID format</a>.
338             * @param daylight if true, return the daylight savings name.
339             * @param style either <code>LONG</code> or <code>SHORT</code>
340             * @return the human-readable name of this time zone in the default locale.
341             * @since 1.2
342             */
343            public final String getDisplayName(boolean daylight, int style) {
344                return getDisplayName(daylight, style, Locale.getDefault());
345            }
346
347            /**
348             * Returns a name of this time zone suitable for presentation to the user
349             * in the specified locale.
350             * If the display name is not available for the locale,
351             * then this method returns a string in the 
352             * <a href="#NormalizedCustomID">normalized custom ID format</a>.
353             * @param daylight if true, return the daylight savings name.
354             * @param style either <code>LONG</code> or <code>SHORT</code>
355             * @param locale the locale in which to supply the display name.
356             * @return the human-readable name of this time zone in the given locale.
357             * @exception IllegalArgumentException style is invalid.
358             * @since 1.2
359             */
360            public String getDisplayName(boolean daylight, int style,
361                    Locale locale) {
362                if (style != SHORT && style != LONG) {
363                    throw new IllegalArgumentException("Illegal style: "
364                            + style);
365                }
366
367                String id = getID();
368                String[] names = getDisplayNames(id, locale);
369                if (names == null) {
370                    if (id.startsWith("GMT")) {
371                        char sign = id.charAt(3);
372                        if (sign == '+' || sign == '-') {
373                            return id;
374                        }
375                    }
376                    int offset = getRawOffset();
377                    if (daylight) {
378                        offset += getDSTSavings();
379                    }
380                    return ZoneInfoFile.toCustomID(offset);
381                }
382
383                int index = daylight ? 3 : 1;
384                if (style == SHORT) {
385                    index++;
386                }
387                return names[index];
388            }
389
390            private static class DisplayNames {
391                // Cache for managing display names per timezone per locale
392                // The structure is:
393                //   Map(key=id, value=SoftReference(Map(key=locale, value=displaynames)))
394                private static final Map<String, SoftReference<Map<Locale, String[]>>> CACHE = new ConcurrentHashMap<String, SoftReference<Map<Locale, String[]>>>();
395            }
396
397            private static final String[] getDisplayNames(String id,
398                    Locale locale) {
399                Map<String, SoftReference<Map<Locale, String[]>>> displayNames = DisplayNames.CACHE;
400
401                SoftReference<Map<Locale, String[]>> ref = displayNames.get(id);
402                if (ref != null) {
403                    Map<Locale, String[]> perLocale = ref.get();
404                    if (perLocale != null) {
405                        String[] names = perLocale.get(locale);
406                        if (names != null) {
407                            return names;
408                        }
409                        names = TimeZoneNameUtility.retrieveDisplayNames(id,
410                                locale);
411                        if (names != null) {
412                            perLocale.put(locale, names);
413                        }
414                        return names;
415                    }
416                }
417
418                String[] names = TimeZoneNameUtility.retrieveDisplayNames(id,
419                        locale);
420                if (names != null) {
421                    Map<Locale, String[]> perLocale = new ConcurrentHashMap<Locale, String[]>();
422                    perLocale.put(locale, names);
423                    ref = new SoftReference<Map<Locale, String[]>>(perLocale);
424                    displayNames.put(id, ref);
425                }
426                return names;
427            }
428
429            /**
430             * Returns the amount of time to be added to local standard time
431             * to get local wall clock time.
432             * <p>
433             * The default implementation always returns 3600000 milliseconds
434             * (i.e., one hour) if this time zone observes Daylight Saving
435             * Time. Otherwise, 0 (zero) is returned.
436             * <p>
437             * If an underlying TimeZone implementation subclass supports
438             * historical Daylight Saving Time changes, this method returns
439             * the known latest daylight saving value.
440             *
441             * @return the amount of saving time in milliseconds
442             * @since 1.4
443             */
444            public int getDSTSavings() {
445                if (useDaylightTime()) {
446                    return 3600000;
447                }
448                return 0;
449            }
450
451            /**
452             * Queries if this time zone uses daylight savings time.
453             * <p>
454             * If an underlying <code>TimeZone</code> implementation subclass
455             * supports historical Daylight Saving Time schedule changes, the
456             * method refers to the latest Daylight Saving Time schedule
457             * information.
458             *
459             * @return true if this time zone uses daylight savings time,
460             * false, otherwise.
461             */
462            public abstract boolean useDaylightTime();
463
464            /**
465             * Queries if the given date is in daylight savings time in
466             * this time zone.
467             * @param date the given Date.
468             * @return true if the given date is in daylight savings time,
469             * false, otherwise.
470             */
471            abstract public boolean inDaylightTime(Date date);
472
473            /**
474             * Gets the <code>TimeZone</code> for the given ID.
475             *
476             * @param ID the ID for a <code>TimeZone</code>, either an abbreviation
477             * such as "PST", a full name such as "America/Los_Angeles", or a custom
478             * ID such as "GMT-8:00". Note that the support of abbreviations is
479             * for JDK 1.1.x compatibility only and full names should be used.
480             *
481             * @return the specified <code>TimeZone</code>, or the GMT zone if the given ID
482             * cannot be understood.
483             */
484            public static synchronized TimeZone getTimeZone(String ID) {
485                return getTimeZone(ID, true);
486            }
487
488            private static TimeZone getTimeZone(String ID, boolean fallback) {
489                TimeZone tz = ZoneInfo.getTimeZone(ID);
490                if (tz == null) {
491                    tz = parseCustomTimeZone(ID);
492                    if (tz == null && fallback) {
493                        tz = new ZoneInfo(GMT_ID, 0);
494                    }
495                }
496                return tz;
497            }
498
499            /**
500             * Gets the available IDs according to the given time zone offset in milliseconds.
501             *
502             * @param rawOffset the given time zone GMT offset in milliseconds.
503             * @return an array of IDs, where the time zone for that ID has
504             * the specified GMT offset. For example, "America/Phoenix" and "America/Denver"
505             * both have GMT-07:00, but differ in daylight savings behavior.
506             * @see #getRawOffset()
507             */
508            public static synchronized String[] getAvailableIDs(int rawOffset) {
509                return ZoneInfo.getAvailableIDs(rawOffset);
510            }
511
512            /**
513             * Gets all the available IDs supported.
514             * @return an array of IDs.
515             */
516            public static synchronized String[] getAvailableIDs() {
517                return ZoneInfo.getAvailableIDs();
518            }
519
520            /**
521             * Gets the platform defined TimeZone ID.
522             **/
523            private static native String getSystemTimeZoneID(String javaHome,
524                    String country);
525
526            /**
527             * Gets the custom time zone ID based on the GMT offset of the
528             * platform. (e.g., "GMT+08:00")
529             */
530            private static native String getSystemGMTOffsetID();
531
532            /**
533             * Gets the default <code>TimeZone</code> for this host.
534             * The source of the default <code>TimeZone</code> 
535             * may vary with implementation.
536             * @return a default <code>TimeZone</code>.
537             * @see #setDefault
538             */
539            public static TimeZone getDefault() {
540                return (TimeZone) getDefaultRef().clone();
541            }
542
543            /**
544             * Returns the reference to the default TimeZone object. This
545             * method doesn't create a clone.
546             */
547            static TimeZone getDefaultRef() {
548                TimeZone defaultZone = defaultZoneTL.get();
549                if (defaultZone == null) {
550                    defaultZone = defaultTimeZone;
551                    if (defaultZone == null) {
552                        // Need to initialize the default time zone.
553                        defaultZone = setDefaultZone();
554                        assert defaultZone != null;
555                    }
556                }
557                // Don't clone here.
558                return defaultZone;
559            }
560
561            private static synchronized TimeZone setDefaultZone() {
562                TimeZone tz = null;
563                // get the time zone ID from the system properties
564                String zoneID = AccessController
565                        .doPrivileged(new GetPropertyAction("user.timezone"));
566
567                // if the time zone ID is not set (yet), perform the
568                // platform to Java time zone ID mapping.
569                if (zoneID == null || zoneID.equals("")) {
570                    String country = AccessController
571                            .doPrivileged(new GetPropertyAction("user.country"));
572                    String javaHome = AccessController
573                            .doPrivileged(new GetPropertyAction("java.home"));
574                    try {
575                        zoneID = getSystemTimeZoneID(javaHome, country);
576                        if (zoneID == null) {
577                            zoneID = GMT_ID;
578                        }
579                    } catch (NullPointerException e) {
580                        zoneID = GMT_ID;
581                    }
582                }
583
584                // Get the time zone for zoneID. But not fall back to
585                // "GMT" here.
586                tz = getTimeZone(zoneID, false);
587
588                if (tz == null) {
589                    // If the given zone ID is unknown in Java, try to
590                    // get the GMT-offset-based time zone ID,
591                    // a.k.a. custom time zone ID (e.g., "GMT-08:00").
592                    String gmtOffsetID = getSystemGMTOffsetID();
593                    if (gmtOffsetID != null) {
594                        zoneID = gmtOffsetID;
595                    }
596                    tz = getTimeZone(zoneID, true);
597                }
598                assert tz != null;
599
600                final String id = zoneID;
601                AccessController.doPrivileged(new PrivilegedAction<Object>() {
602                    public Object run() {
603                        System.setProperty("user.timezone", id);
604                        return null;
605                    }
606                });
607
608                if (hasPermission()) {
609                    defaultTimeZone = tz;
610                } else {
611                    defaultZoneTL.set(tz);
612                }
613                return tz;
614            }
615
616            private static boolean hasPermission() {
617                boolean hasPermission = true;
618                SecurityManager sm = System.getSecurityManager();
619                if (sm != null) {
620                    try {
621                        sm.checkPermission(new PropertyPermission(
622                                "user.timezone", "write"));
623                    } catch (SecurityException e) {
624                        hasPermission = false;
625                    }
626                }
627                return hasPermission;
628            }
629
630            /**
631             * Sets the <code>TimeZone</code> that is
632             * returned by the <code>getDefault</code> method.  If <code>zone</code>
633             * is null, reset the default to the value it had originally when the
634             * VM first started.
635             * @param zone the new default time zone
636             * @see #getDefault
637             */
638            public static void setDefault(TimeZone zone) {
639                if (hasPermission()) {
640                    synchronized (TimeZone.class) {
641                        defaultTimeZone = zone;
642                    }
643                } else {
644                    defaultZoneTL.set(zone);
645                }
646            }
647
648            /**
649             * Returns true if this zone has the same rule and offset as another zone.
650             * That is, if this zone differs only in ID, if at all.  Returns false
651             * if the other zone is null.
652             * @param other the <code>TimeZone</code> object to be compared with
653             * @return true if the other zone is not null and is the same as this one,
654             * with the possible exception of the ID
655             * @since 1.2
656             */
657            public boolean hasSameRules(TimeZone other) {
658                return other != null && getRawOffset() == other.getRawOffset()
659                        && useDaylightTime() == other.useDaylightTime();
660            }
661
662            /**
663             * Creates a copy of this <code>TimeZone</code>.
664             *
665             * @return a clone of this <code>TimeZone</code>
666             */
667            public Object clone() {
668                try {
669                    TimeZone other = (TimeZone) super .clone();
670                    other.ID = ID;
671                    return other;
672                } catch (CloneNotSupportedException e) {
673                    throw new InternalError();
674                }
675            }
676
677            /**
678             * The null constant as a TimeZone.
679             */
680            static final TimeZone NO_TIMEZONE = null;
681
682            // =======================privates===============================
683
684            /**
685             * The string identifier of this <code>TimeZone</code>.  This is a
686             * programmatic identifier used internally to look up <code>TimeZone</code>
687             * objects from the system table and also to map them to their localized
688             * display names.  <code>ID</code> values are unique in the system
689             * table but may not be for dynamically created zones.
690             * @serial
691             */
692            private String ID;
693            private static volatile TimeZone defaultTimeZone;
694            private static final InheritableThreadLocal<TimeZone> defaultZoneTL = new InheritableThreadLocal<TimeZone>();
695
696            static final String GMT_ID = "GMT";
697            private static final int GMT_ID_LENGTH = 3;
698
699            /**
700             * Parses a custom time zone identifier and returns a corresponding zone.
701             * This method doesn't support the RFC 822 time zone format. (e.g., +hhmm)
702             *
703             * @param id a string of the <a href="#CustomID">custom ID form</a>.
704             * @return a newly created TimeZone with the given offset and
705             * no daylight saving time, or null if the id cannot be parsed.
706             */
707            private static final TimeZone parseCustomTimeZone(String id) {
708                int length;
709
710                // Error if the length of id isn't long enough or id doesn't
711                // start with "GMT".
712                if ((length = id.length()) < (GMT_ID_LENGTH + 2)
713                        || id.indexOf(GMT_ID) != 0) {
714                    return null;
715                }
716
717                ZoneInfo zi;
718
719                // First, we try to find it in the cache with the given
720                // id. Even the id is not normalized, the returned ZoneInfo
721                // should have its normalized id.
722                zi = ZoneInfoFile.getZoneInfo(id);
723                if (zi != null) {
724                    return zi;
725                }
726
727                int index = GMT_ID_LENGTH;
728                boolean negative = false;
729                char c = id.charAt(index++);
730                if (c == '-') {
731                    negative = true;
732                } else if (c != '+') {
733                    return null;
734                }
735
736                int hours = 0;
737                int num = 0;
738                int countDelim = 0;
739                int len = 0;
740                while (index < length) {
741                    c = id.charAt(index++);
742                    if (c == ':') {
743                        if (countDelim > 0) {
744                            return null;
745                        }
746                        if (len > 2) {
747                            return null;
748                        }
749                        hours = num;
750                        countDelim++;
751                        num = 0;
752                        len = 0;
753                        continue;
754                    }
755                    if (c < '0' || c > '9') {
756                        return null;
757                    }
758                    num = num * 10 + (c - '0');
759                    len++;
760                }
761                if (index != length) {
762                    return null;
763                }
764                if (countDelim == 0) {
765                    if (len <= 2) {
766                        hours = num;
767                        num = 0;
768                    } else {
769                        hours = num / 100;
770                        num %= 100;
771                    }
772                } else {
773                    if (len != 2) {
774                        return null;
775                    }
776                }
777                if (hours > 23 || num > 59) {
778                    return null;
779                }
780                int gmtOffset = (hours * 60 + num) * 60 * 1000;
781
782                if (gmtOffset == 0) {
783                    zi = ZoneInfoFile.getZoneInfo(GMT_ID);
784                    if (negative) {
785                        zi.setID("GMT-00:00");
786                    } else {
787                        zi.setID("GMT+00:00");
788                    }
789                } else {
790                    zi = ZoneInfoFile.getCustomTimeZone(id,
791                            negative ? -gmtOffset : gmtOffset);
792                }
793                return zi;
794            }
795        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.