KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > chrono > ISOChronology


1 /*
2  * Copyright 2001-2005 Stephen Colebourne
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.joda.time.chrono;
17
18 import java.io.IOException JavaDoc;
19 import java.io.ObjectInputStream JavaDoc;
20 import java.io.ObjectOutputStream JavaDoc;
21 import java.io.Serializable JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.joda.time.Chronology;
26 import org.joda.time.DateTimeFieldType;
27 import org.joda.time.DateTimeZone;
28 import org.joda.time.field.DividedDateTimeField;
29 import org.joda.time.field.RemainderDateTimeField;
30
31 /**
32  * Implements a chronology that follows the rules of the ISO8601 standard,
33  * which is compatible with Gregorian for all modern dates.
34  * When ISO does not define a field, but it can be determined (such as AM/PM)
35  * it is included.
36  * <p>
37  * With the exception of century related fields, ISOChronology is exactly the
38  * same as {@link GregorianChronology}. In this chronology, centuries and year
39  * of century are zero based. For all years, the century is determined by
40  * dropping the last two digits of the year, ignoring sign. The year of century
41  * is the value of the last two year digits.
42  * <p>
43  * ISOChronology is thread-safe and immutable.
44  *
45  * @author Stephen Colebourne
46  * @author Brian S O'Neill
47  * @since 1.0
48  */

49 public final class ISOChronology extends AssembledChronology {
50     
51     /** Serialization lock */
52     private static final long serialVersionUID = -6212696554273812441L;
53
54     /** Singleton instance of a UTC ISOChronology */
55     private static final ISOChronology INSTANCE_UTC;
56         
57     private static final int FAST_CACHE_SIZE = 64;
58
59     /** Fast cache of zone to chronology */
60     private static final ISOChronology[] cFastCache;
61
62     /** Cache of zone to chronology */
63     private static final Map JavaDoc cCache = new HashMap JavaDoc();
64     static {
65         cFastCache = new ISOChronology[FAST_CACHE_SIZE];
66         INSTANCE_UTC = new ISOChronology(GregorianChronology.getInstanceUTC());
67         cCache.put(DateTimeZone.UTC, INSTANCE_UTC);
68     }
69
70     /**
71      * Gets an instance of the ISOChronology.
72      * The time zone of the returned instance is UTC.
73      *
74      * @return a singleton UTC instance of the chronology
75      */

76     public static ISOChronology getInstanceUTC() {
77         return INSTANCE_UTC;
78     }
79
80     /**
81      * Gets an instance of the ISOChronology in the default time zone.
82      *
83      * @return a chronology in the default time zone
84      */

85     public static ISOChronology getInstance() {
86         return getInstance(DateTimeZone.getDefault());
87     }
88
89     /**
90      * Gets an instance of the ISOChronology in the given time zone.
91      *
92      * @param zone the time zone to get the chronology in, null is default
93      * @return a chronology in the specified time zone
94      */

95     public static ISOChronology getInstance(DateTimeZone zone) {
96         if (zone == null) {
97             zone = DateTimeZone.getDefault();
98         }
99         int index = System.identityHashCode(zone) & (FAST_CACHE_SIZE - 1);
100         ISOChronology chrono = cFastCache[index];
101         if (chrono != null && chrono.getZone() == zone) {
102             return chrono;
103         }
104         synchronized (cCache) {
105             chrono = (ISOChronology) cCache.get(zone);
106             if (chrono == null) {
107                 chrono = new ISOChronology(ZonedChronology.getInstance(INSTANCE_UTC, zone));
108                 cCache.put(zone, chrono);
109             }
110         }
111         cFastCache[index] = chrono;
112         return chrono;
113     }
114
115     // Constructors and instance variables
116
//-----------------------------------------------------------------------
117

118     /**
119      * Restricted constructor
120      */

121     private ISOChronology(Chronology base) {
122         super(base, null);
123     }
124
125     // Conversion
126
//-----------------------------------------------------------------------
127
/**
128      * Gets the Chronology in the UTC time zone.
129      *
130      * @return the chronology in UTC
131      */

132     public Chronology withUTC() {
133         return INSTANCE_UTC;
134     }
135
136     /**
137      * Gets the Chronology in a specific time zone.
138      *
139      * @param zone the zone to get the chronology in, null is default
140      * @return the chronology
141      */

142     public Chronology withZone(DateTimeZone zone) {
143         if (zone == null) {
144             zone = DateTimeZone.getDefault();
145         }
146         if (zone == getZone()) {
147             return this;
148         }
149         return getInstance(zone);
150     }
151
152     // Output
153
//-----------------------------------------------------------------------
154
/**
155      * Gets a debugging toString.
156      *
157      * @return a debugging string
158      */

159     public String JavaDoc toString() {
160         String JavaDoc str = "ISOChronology";
161         DateTimeZone zone = getZone();
162         if (zone != null) {
163             str = str + '[' + zone.getID() + ']';
164         }
165         return str;
166     }
167
168     protected void assemble(Fields fields) {
169         if (getBase().getZone() == DateTimeZone.UTC) {
170             // Use zero based century and year of century.
171
fields.centuryOfEra = new DividedDateTimeField(
172                 ISOYearOfEraDateTimeField.INSTANCE, DateTimeFieldType.centuryOfEra(), 100);
173             fields.yearOfCentury = new RemainderDateTimeField(
174                 (DividedDateTimeField) fields.centuryOfEra, DateTimeFieldType.yearOfCentury());
175             fields.weekyearOfCentury = new RemainderDateTimeField(
176                 (DividedDateTimeField) fields.centuryOfEra, DateTimeFieldType.weekyearOfCentury());
177
178             fields.centuries = fields.centuryOfEra.getDurationField();
179         }
180     }
181
182     /**
183      * Serialize ISOChronology instances using a small stub. This reduces the
184      * serialized size, and deserialized instances come from the cache.
185      */

186     private Object JavaDoc writeReplace() {
187         return new Stub(getZone());
188     }
189
190     private static final class Stub implements Serializable JavaDoc {
191         private static final long serialVersionUID = -6212696554273812441L;
192
193         private transient DateTimeZone iZone;
194
195         Stub(DateTimeZone zone) {
196             iZone = zone;
197         }
198
199         private Object JavaDoc readResolve() {
200             return ISOChronology.getInstance(iZone);
201         }
202
203         private void writeObject(ObjectOutputStream JavaDoc out) throws IOException JavaDoc {
204             out.writeObject(iZone);
205         }
206
207         private void readObject(ObjectInputStream JavaDoc in)
208             throws IOException JavaDoc, ClassNotFoundException JavaDoc
209         {
210             iZone = (DateTimeZone)in.readObject();
211         }
212     }
213
214 }
215
Popular Tags