]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/JavaTimeZone.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / JavaTimeZone.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2008-2010, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.impl;\r
8 \r
9 import java.io.IOException;\r
10 import java.io.ObjectInputStream;\r
11 import java.util.Date;\r
12 import java.util.TreeSet;\r
13 \r
14 import com.ibm.icu.util.TimeZone;\r
15 \r
16 /**\r
17  * JavaTimeZone inherits com.ibm.icu.util.TimeZone and wraps java.util.TimeZone.\r
18  * We used to have JDKTimeZone which wrapped Java TimeZone and used it as primary\r
19  * TimeZone implementation until ICU4J 3.4.1.  This class works exactly like\r
20  * JDKTimeZone and allows ICU users who use ICU4J and JDK date/time/calendar\r
21  * services in mix to maintain only JDK timezone rules.\r
22  *\r
23  * This TimeZone subclass is returned by the TimeZone factory method getTimeZone(String)\r
24  * when the default timezone type in TimeZone class is TimeZone.TIMEZONE_JDK.\r
25  */\r
26 public class JavaTimeZone extends TimeZone {\r
27 \r
28     private static final long serialVersionUID = 6977448185543929364L;\r
29 \r
30     private static final TreeSet<String> AVAILABLESET;\r
31 \r
32     private java.util.TimeZone javatz;\r
33     private transient java.util.Calendar javacal;\r
34 \r
35     static {\r
36         AVAILABLESET = new TreeSet<String>();\r
37         String[] availableIds = java.util.TimeZone.getAvailableIDs();\r
38         for (int i = 0; i < availableIds.length; i++) {\r
39             AVAILABLESET.add(availableIds[i]);\r
40         }\r
41     }\r
42 \r
43     /**\r
44      * Constructs a JavaTimeZone with the default Java TimeZone\r
45      */\r
46     public JavaTimeZone() {\r
47         javatz = java.util.TimeZone.getDefault();\r
48         setID(javatz.getID());\r
49         javacal = new java.util.GregorianCalendar(javatz);\r
50     }\r
51 \r
52     /**\r
53      * Constructs a JavaTimeZone with the given timezone ID.\r
54      * @param id A timezone ID, either a system ID or a custom ID.\r
55      */\r
56     public JavaTimeZone(String id) {\r
57         if (AVAILABLESET.contains(id)) {\r
58             javatz = java.util.TimeZone.getTimeZone(id);\r
59         }\r
60         if (javatz == null) {\r
61             // Use ICU's canonical ID mapping\r
62             boolean[] isSystemID = new boolean[1];\r
63             String canonicalID = TimeZone.getCanonicalID(id, isSystemID);\r
64             if (isSystemID[0] && AVAILABLESET.contains(canonicalID)) {\r
65                 javatz = java.util.TimeZone.getTimeZone(canonicalID);\r
66             }\r
67         }\r
68 \r
69         if (javatz == null){\r
70             int[] fields = new int[4];\r
71             if (ZoneMeta.parseCustomID(id, fields)) {\r
72                 // JDK does not support offset seconds.\r
73                 // If custom ID, we create java.util.SimpleTimeZone here.\r
74                 id = ZoneMeta.formatCustomID(fields[1], fields[2], fields[3], fields[0] < 0);\r
75                 int offset = fields[0] * ((fields[1] * 60 + fields[2]) * 60 + fields[3]) * 1000;\r
76                 javatz = new java.util.SimpleTimeZone(offset, id);\r
77             }\r
78         }\r
79         if (javatz == null) {\r
80             // Final fallback\r
81             id = "GMT";\r
82             javatz = java.util.TimeZone.getTimeZone(id);\r
83         }\r
84         setID(id);\r
85         javacal = new java.util.GregorianCalendar(javatz);\r
86     }\r
87 \r
88     /* (non-Javadoc)\r
89      * @see com.ibm.icu.util.TimeZone#getOffset(int, int, int, int, int, int)\r
90      */\r
91     public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {\r
92         return javatz.getOffset(era, year, month, day, dayOfWeek, milliseconds);\r
93     }\r
94 \r
95     /* (non-Javadoc)\r
96      * @see com.ibm.icu.util.TimeZone#getOffset(long, boolean, int[])\r
97      */\r
98     public void getOffset(long date, boolean local, int[] offsets) {\r
99         synchronized (javacal) {\r
100             if (local) {\r
101                 int fields[] = new int[6];\r
102                 Grego.timeToFields(date, fields);\r
103                 int hour, min, sec, mil;\r
104                 int tmp = fields[5];\r
105                 mil = tmp % 1000;\r
106                 tmp /= 1000;\r
107                 sec = tmp % 60;\r
108                 tmp /= 60;\r
109                 min = tmp % 60;\r
110                 hour = tmp / 60;\r
111                 javacal.clear();\r
112                 javacal.set(fields[0], fields[1], fields[2], hour, min, sec);\r
113                 javacal.set(java.util.Calendar.MILLISECOND, mil);\r
114 \r
115                 int doy1, hour1, min1, sec1, mil1;\r
116                 doy1 = javacal.get(java.util.Calendar.DAY_OF_YEAR);\r
117                 hour1 = javacal.get(java.util.Calendar.HOUR_OF_DAY);\r
118                 min1 = javacal.get(java.util.Calendar.MINUTE);\r
119                 sec1 = javacal.get(java.util.Calendar.SECOND);\r
120                 mil1 = javacal.get(java.util.Calendar.MILLISECOND);\r
121 \r
122                 if (fields[4] != doy1 || hour != hour1 || min != min1 || sec != sec1 || mil != mil1) {\r
123                     // Calendar field(s) were changed due to the adjustment for non-existing time\r
124                     // Note: This code does not support non-existing local time at year boundary properly.\r
125                     // But, it should work fine for real timezones.\r
126                     int dayDelta = Math.abs(doy1 - fields[4]) > 1 ? 1 : doy1 - fields[4];\r
127                     int delta = ((((dayDelta * 24) + hour1 - hour) * 60 + min1 - min) * 60 + sec1 - sec) * 1000 + mil1 - mil;\r
128 \r
129                     // In this case, we use the offsets before the transition\r
130                    javacal.setTimeInMillis(javacal.getTimeInMillis() - delta - 1);\r
131                 }\r
132             } else {\r
133                 javacal.setTimeInMillis(date);\r
134             }\r
135             offsets[0] = javacal.get(java.util.Calendar.ZONE_OFFSET);\r
136             offsets[1] = javacal.get(java.util.Calendar.DST_OFFSET);\r
137         }\r
138     }\r
139 \r
140     /* (non-Javadoc)\r
141      * @see com.ibm.icu.util.TimeZone#getRawOffset()\r
142      */\r
143     public int getRawOffset() {\r
144         return javatz.getRawOffset();\r
145     }\r
146 \r
147     /* (non-Javadoc)\r
148      * @see com.ibm.icu.util.TimeZone#inDaylightTime(java.util.Date)\r
149      */\r
150     public boolean inDaylightTime(Date date) {\r
151         return javatz.inDaylightTime(date);\r
152     }\r
153 \r
154     /* (non-Javadoc)\r
155      * @see com.ibm.icu.util.TimeZone#setRawOffset(int)\r
156      */\r
157     public void setRawOffset(int offsetMillis) {\r
158         javatz.setRawOffset(offsetMillis);\r
159     }\r
160 \r
161     /* (non-Javadoc)\r
162      * @see com.ibm.icu.util.TimeZone#useDaylightTime()\r
163      */\r
164     public boolean useDaylightTime() {\r
165         return javatz.useDaylightTime();\r
166     }\r
167 \r
168     /* (non-Javadoc)\r
169      * @see com.ibm.icu.util.TimeZone#getDSTSavings()\r
170      */\r
171     public int getDSTSavings() {\r
172         int dstSavings = super.getDSTSavings();\r
173         try {\r
174             // hack so test compiles and runs in both JDK 1.3 and JDK 1.4+\r
175             final Object[] args = new Object[0];\r
176             final Class<?>[] argtypes = new Class[0];\r
177             java.lang.reflect.Method m = javatz.getClass().getMethod("getDSTSavings", argtypes); \r
178             dstSavings = ((Integer) m.invoke(javatz, args)).intValue();\r
179         } catch (Exception e) {\r
180             // just use the result returned by super.getDSTSavings()\r
181         }\r
182         return dstSavings;\r
183     }\r
184 \r
185     public java.util.TimeZone unwrap() {\r
186         return javatz;\r
187     }\r
188 \r
189     /* (non-Javadoc)\r
190      * @see com.ibm.icu.util.TimeZone#clone()\r
191      */\r
192     public Object clone() {\r
193         JavaTimeZone other = (JavaTimeZone)super.clone();\r
194         other.javatz = (java.util.TimeZone)javatz.clone();\r
195         return other;\r
196     }\r
197 \r
198     /* (non-Javadoc)\r
199      * @see com.ibm.icu.util.TimeZone#hashCode()\r
200      */\r
201     public int hashCode() {\r
202         return super.hashCode() + javatz.hashCode();\r
203     }\r
204 \r
205     private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {\r
206         s.defaultReadObject();\r
207         javacal = new java.util.GregorianCalendar(javatz);\r
208     }\r
209 }\r