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