]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/classes/core/src/com/ibm/icu/impl/JavaTimeZone.java
Clean up imports.
[Dictionary.git] / jars / icu4j-52_1 / main / classes / core / src / com / ibm / icu / impl / JavaTimeZone.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 2008-2012, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.impl;
8
9 import java.io.IOException;
10 import java.io.ObjectInputStream;
11 import java.lang.reflect.InvocationTargetException;
12 import java.lang.reflect.Method;
13 import java.util.Date;
14 import java.util.TreeSet;
15
16 import com.ibm.icu.util.TimeZone;
17
18 /**
19  * JavaTimeZone inherits com.ibm.icu.util.TimeZone and wraps java.util.TimeZone.
20  * We used to have JDKTimeZone which wrapped Java TimeZone and used it as primary
21  * TimeZone implementation until ICU4J 3.4.1.  This class works exactly like
22  * JDKTimeZone and allows ICU users who use ICU4J and JDK date/time/calendar
23  * services in mix to maintain only JDK timezone rules.
24  *
25  * This TimeZone subclass is returned by the TimeZone factory method getTimeZone(String)
26  * when the default timezone type in TimeZone class is TimeZone.TIMEZONE_JDK.
27  */
28 public class JavaTimeZone extends TimeZone {
29
30     private static final long serialVersionUID = 6977448185543929364L;
31
32     private static final TreeSet<String> AVAILABLESET;
33
34     private java.util.TimeZone javatz;
35     private transient java.util.Calendar javacal;
36     private static Method mObservesDaylightTime;
37
38     static {
39         AVAILABLESET = new TreeSet<String>();
40         String[] availableIds = java.util.TimeZone.getAvailableIDs();
41         for (int i = 0; i < availableIds.length; i++) {
42             AVAILABLESET.add(availableIds[i]);
43         }
44
45         try {
46             mObservesDaylightTime = java.util.TimeZone.class.getMethod("observesDaylightTime", (Class[]) null);
47         } catch (NoSuchMethodException e) {
48             // Java 6 or older
49         } catch (SecurityException e) {
50             // not visible
51         }
52     }
53
54     /**
55      * Constructs a JavaTimeZone with the default Java TimeZone
56      */
57     public JavaTimeZone() {
58         this(java.util.TimeZone.getDefault(), null);
59     }
60
61     /**
62      * Constructs a JavaTimeZone with the specified Java TimeZone and ID.
63      * @param jtz the Java TimeZone
64      * @param id the ID of the zone. if null, the zone ID is initialized
65      * by the given Java TimeZone's ID.
66      */
67     public JavaTimeZone(java.util.TimeZone jtz, String id) {
68         if (id == null) {
69             id = jtz.getID();
70         }
71         javatz = jtz;
72         setID(id);
73         javacal = new java.util.GregorianCalendar(javatz);
74     }
75
76     /**
77      * Creates an instance of JavaTimeZone with the given timezone ID.
78      * @param id A timezone ID, either a system ID or a custom ID.
79      * @return An instance of JavaTimeZone for the given ID, or null
80      * when the ID cannot be understood.
81      */
82     public static JavaTimeZone createTimeZone(String id) {
83         java.util.TimeZone jtz = null;
84
85         if (AVAILABLESET.contains(id)) {
86             jtz = java.util.TimeZone.getTimeZone(id);
87         }
88
89         if (jtz == null) {
90             // Use ICU's canonical ID mapping
91             boolean[] isSystemID = new boolean[1];
92             String canonicalID = TimeZone.getCanonicalID(id, isSystemID);
93             if (isSystemID[0] && AVAILABLESET.contains(canonicalID)) {
94                 jtz = java.util.TimeZone.getTimeZone(canonicalID);
95             }
96         }
97
98         if (jtz == null) {
99             return null;
100         }
101
102         return new JavaTimeZone(jtz, id);
103     }
104
105     /* (non-Javadoc)
106      * @see com.ibm.icu.util.TimeZone#getOffset(int, int, int, int, int, int)
107      */
108     public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {
109         return javatz.getOffset(era, year, month, day, dayOfWeek, milliseconds);
110     }
111
112     /* (non-Javadoc)
113      * @see com.ibm.icu.util.TimeZone#getOffset(long, boolean, int[])
114      */
115     public void getOffset(long date, boolean local, int[] offsets) {
116         synchronized (javacal) {
117             if (local) {
118                 int fields[] = new int[6];
119                 Grego.timeToFields(date, fields);
120                 int hour, min, sec, mil;
121                 int tmp = fields[5];
122                 mil = tmp % 1000;
123                 tmp /= 1000;
124                 sec = tmp % 60;
125                 tmp /= 60;
126                 min = tmp % 60;
127                 hour = tmp / 60;
128                 javacal.clear();
129                 javacal.set(fields[0], fields[1], fields[2], hour, min, sec);
130                 javacal.set(java.util.Calendar.MILLISECOND, mil);
131
132                 int doy1, hour1, min1, sec1, mil1;
133                 doy1 = javacal.get(java.util.Calendar.DAY_OF_YEAR);
134                 hour1 = javacal.get(java.util.Calendar.HOUR_OF_DAY);
135                 min1 = javacal.get(java.util.Calendar.MINUTE);
136                 sec1 = javacal.get(java.util.Calendar.SECOND);
137                 mil1 = javacal.get(java.util.Calendar.MILLISECOND);
138
139                 if (fields[4] != doy1 || hour != hour1 || min != min1 || sec != sec1 || mil != mil1) {
140                     // Calendar field(s) were changed due to the adjustment for non-existing time
141                     // Note: This code does not support non-existing local time at year boundary properly.
142                     // But, it should work fine for real timezones.
143                     int dayDelta = Math.abs(doy1 - fields[4]) > 1 ? 1 : doy1 - fields[4];
144                     int delta = ((((dayDelta * 24) + hour1 - hour) * 60 + min1 - min) * 60 + sec1 - sec) * 1000 + mil1 - mil;
145
146                     // In this case, we use the offsets before the transition
147                    javacal.setTimeInMillis(javacal.getTimeInMillis() - delta - 1);
148                 }
149             } else {
150                 javacal.setTimeInMillis(date);
151             }
152             offsets[0] = javacal.get(java.util.Calendar.ZONE_OFFSET);
153             offsets[1] = javacal.get(java.util.Calendar.DST_OFFSET);
154         }
155     }
156
157     /* (non-Javadoc)
158      * @see com.ibm.icu.util.TimeZone#getRawOffset()
159      */
160     public int getRawOffset() {
161         return javatz.getRawOffset();
162     }
163
164     /* (non-Javadoc)
165      * @see com.ibm.icu.util.TimeZone#inDaylightTime(java.util.Date)
166      */
167     public boolean inDaylightTime(Date date) {
168         return javatz.inDaylightTime(date);
169     }
170
171     /* (non-Javadoc)
172      * @see com.ibm.icu.util.TimeZone#setRawOffset(int)
173      */
174     public void setRawOffset(int offsetMillis) {
175         if (isFrozen()) {
176             throw new UnsupportedOperationException("Attempt to modify a frozen JavaTimeZone instance.");
177         }
178         javatz.setRawOffset(offsetMillis);
179     }
180
181     /* (non-Javadoc)
182      * @see com.ibm.icu.util.TimeZone#useDaylightTime()
183      */
184     public boolean useDaylightTime() {
185         return javatz.useDaylightTime();
186     }
187
188     /* (non-Javadoc)
189      * @see com.ibm.icu.util.TimeZone#observesDaylightTime()
190      */
191     public boolean observesDaylightTime() {
192         if (mObservesDaylightTime != null) {
193             // Java 7+
194             try {
195                 return (Boolean)mObservesDaylightTime.invoke(javatz, (Object[]) null);
196             } catch (IllegalAccessException e) {
197             } catch (IllegalArgumentException e) {
198             } catch (InvocationTargetException e) {
199             }
200         }
201         return super.observesDaylightTime();
202     }
203
204     /* (non-Javadoc)
205      * @see com.ibm.icu.util.TimeZone#getDSTSavings()
206      */
207     public int getDSTSavings() {
208         return javatz.getDSTSavings();
209     }
210
211     public java.util.TimeZone unwrap() {
212         return javatz;
213     }
214
215     /* (non-Javadoc)
216      * @see com.ibm.icu.util.TimeZone#clone()
217      */
218     public Object clone() {
219         if (isFrozen()) {
220             return this;
221         }
222         return cloneAsThawed();
223     }
224
225     /* (non-Javadoc)
226      * @see com.ibm.icu.util.TimeZone#hashCode()
227      */
228     public int hashCode() {
229         return super.hashCode() + javatz.hashCode();
230     }
231
232     private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
233         s.defaultReadObject();
234         javacal = new java.util.GregorianCalendar(javatz);
235     }
236
237     // Freezable stuffs
238     private transient boolean isFrozen = false;
239
240     /* (non-Javadoc)
241      * @see com.ibm.icu.util.TimeZone#isFrozen()
242      */
243     public boolean isFrozen() {
244         return isFrozen;
245     }
246
247     /* (non-Javadoc)
248      * @see com.ibm.icu.util.TimeZone#freeze()
249      */
250     public TimeZone freeze() {
251         isFrozen = true;
252         return this;
253     }
254
255     /* (non-Javadoc)
256      * @see com.ibm.icu.util.TimeZone#cloneAsThawed()
257      */
258     public TimeZone cloneAsThawed() {
259         JavaTimeZone tz = (JavaTimeZone)super.cloneAsThawed();
260         tz.javatz = (java.util.TimeZone)javatz.clone();
261         tz.javacal = (java.util.GregorianCalendar)javacal.clone();
262         tz.isFrozen = false;
263         return tz;
264     }
265
266 }