OSDN Git Service

974065a6e6581b733258c9a22a2e583f87c74677
[pf3gnuchains/gcc-fork.git] / libjava / java / util / TimeZone.java
1 /* java.util.TimeZone
2    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.util;
40 import java.text.DateFormatSymbols;
41
42 /**
43  * This class represents a time zone offset and handles daylight savings.
44  * 
45  * You can get the default time zone with <code>getDefault</code>.
46  * This represents the time zone where program is running.
47  *
48  * Another way to create a time zone is <code>getTimeZone</code>, where
49  * you can give an identifier as parameter.  For instance, the identifier
50  * of the Central European Time zone is "CET".
51  *
52  * With the <code>getAvailableIDs</code> method, you can get all the
53  * supported time zone identifiers.
54  *
55  * @see Calendar
56  * @see SimpleTimeZone
57  * @author Jochen Hoenicke
58  */
59 public abstract class TimeZone implements java.io.Serializable, Cloneable
60 {
61
62   /**
63    * Constant used to indicate that a short timezone abbreviation should
64    * be returned, such as "EST"
65    */
66   public static final int SHORT = 0;
67
68   /**
69    * Constant used to indicate that a long timezone name should be
70    * returned, such as "Eastern Standard Time".
71    */
72   public static final int LONG = 1;
73
74   /**
75    * The time zone identifier, e.g. PST.
76    */
77   private String ID;
78
79   /**
80    * The default time zone, as returned by getDefault.
81    */
82   private static TimeZone defaultZone;
83
84   private static final long serialVersionUID = 3581463369166924961L;
85
86   /**
87    * Hashtable for timezones by ID.  
88    */
89   private static final Hashtable timezones = new Hashtable();
90
91   static
92   {
93     TimeZone tz;
94     // Automatically generated by scripts/timezones.pl
95     // XXX - Should we read this data from a file?
96     tz = new SimpleTimeZone(-11000 * 3600, "MIT");
97     timezones.put("MIT", tz);
98     timezones.put("Pacific/Apia", tz);
99     timezones.put("Pacific/Midway", tz);
100     timezones.put("Pacific/Niue", tz);
101     timezones.put("Pacific/Pago_Pago", tz);
102     tz = new SimpleTimeZone
103       (-10000 * 3600, "America/Adak",
104        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
105        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
106     timezones.put("America/Adak", tz);
107     tz = new SimpleTimeZone(-10000 * 3600, "HST");
108     timezones.put("HST", tz);
109     timezones.put("Pacific/Fakaofo", tz);
110     timezones.put("Pacific/Honolulu", tz);
111     timezones.put("Pacific/Johnston", tz);
112     timezones.put("Pacific/Rarotonga", tz);
113     timezones.put("Pacific/Tahiti", tz);
114     tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas");
115     timezones.put("Pacific/Marquesas", tz);
116     tz = new SimpleTimeZone
117       (-9000 * 3600, "AST",
118        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
119        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
120     timezones.put("AST", tz);
121     timezones.put("America/Anchorage", tz);
122     timezones.put("America/Juneau", tz);
123     timezones.put("America/Nome", tz);
124     timezones.put("America/Yakutat", tz);
125     tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier");
126     timezones.put("Pacific/Gambier", tz);
127     tz = new SimpleTimeZone
128       (-8000 * 3600, "PST",
129        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
130        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
131     timezones.put("PST", tz);
132     timezones.put("PST8PDT", tz);
133     timezones.put("America/Dawson", tz);
134     timezones.put("America/Los_Angeles", tz);
135     timezones.put("America/Tijuana", tz);
136     timezones.put("America/Vancouver", tz);
137     timezones.put("America/Whitehorse", tz);
138     timezones.put("US/Pacific-New", tz);
139     tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn");
140     timezones.put("Pacific/Pitcairn", tz);
141     tz = new SimpleTimeZone
142       (-7000 * 3600, "MST",
143        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
144        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
145     timezones.put("MST", tz);
146     timezones.put("MST7MDT", tz);
147     timezones.put("America/Boise", tz);
148     timezones.put("America/Chihuahua", tz);
149     timezones.put("America/Denver", tz);
150     timezones.put("America/Edmonton", tz);
151     timezones.put("America/Inuvik", tz);
152     timezones.put("America/Mazatlan", tz);
153     timezones.put("America/Shiprock", tz);
154     timezones.put("America/Yellowknife", tz);
155     tz = new SimpleTimeZone(-7000 * 3600, "MST7");
156     timezones.put("MST7", tz);
157     timezones.put("PNT", tz);
158     timezones.put("America/Dawson_Creek", tz);
159     timezones.put("America/Hermosillo", tz);
160     timezones.put("America/Phoenix", tz);
161     tz = new SimpleTimeZone
162       (-6000 * 3600, "CST",
163        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
164        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
165     timezones.put("CST", tz);
166     timezones.put("CST6CDT", tz);
167     timezones.put("America/Cambridge_Bay", tz);
168     timezones.put("America/Cancun", tz);
169     timezones.put("America/Chicago", tz);
170     timezones.put("America/Menominee", tz);
171     timezones.put("America/Merida", tz);
172     timezones.put("America/Mexico_City", tz);
173     timezones.put("America/Monterrey", tz);
174     timezones.put("America/Rainy_River", tz);
175     timezones.put("America/Winnipeg", tz);
176     tz = new SimpleTimeZone(-6000 * 3600, "America/Belize");
177     timezones.put("America/Belize", tz);
178     timezones.put("America/Costa_Rica", tz);
179     timezones.put("America/El_Salvador", tz);
180     timezones.put("America/Guatemala", tz);
181     timezones.put("America/Managua", tz);
182     timezones.put("America/Regina", tz);
183     timezones.put("America/Swift_Current", tz);
184     timezones.put("America/Tegucigalpa", tz);
185     timezones.put("Pacific/Galapagos", tz);
186     tz = new SimpleTimeZone
187       (-6000 * 3600, "Pacific/Easter",
188        Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600,
189        Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600);
190     timezones.put("Pacific/Easter", tz);
191     tz = new SimpleTimeZone
192       (-5000 * 3600, "America/Grand_Turk",
193        Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600,
194        Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
195     timezones.put("America/Grand_Turk", tz);
196     timezones.put("America/Havana", tz);
197     tz = new SimpleTimeZone(-5000 * 3600, "EST5");
198     timezones.put("EST5", tz);
199     timezones.put("IET", tz);
200     timezones.put("America/Bogota", tz);
201     timezones.put("America/Cayman", tz);
202     timezones.put("America/Eirunepe", tz);
203     timezones.put("America/Guayaquil", tz);
204     timezones.put("America/Indiana/Indianapolis", tz);
205     timezones.put("America/Indiana/Knox", tz);
206     timezones.put("America/Indiana/Marengo", tz);
207     timezones.put("America/Indiana/Vevay", tz);
208     timezones.put("America/Indianapolis", tz);
209     timezones.put("America/Iqaluit", tz);
210     timezones.put("America/Jamaica", tz);
211     timezones.put("America/Lima", tz);
212     timezones.put("America/Panama", tz);
213     timezones.put("America/Pangnirtung", tz);
214     timezones.put("America/Port-au-Prince", tz);
215     timezones.put("America/Porto_Acre", tz);
216     timezones.put("America/Rankin_Inlet", tz);
217     tz = new SimpleTimeZone
218       (-5000 * 3600, "EST",
219        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
220        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
221     timezones.put("EST", tz);
222     timezones.put("EST5EDT", tz);
223     timezones.put("America/Detroit", tz);
224     timezones.put("America/Kentucky/Louisville", tz);
225     timezones.put("America/Kentucky/Monticello", tz);
226     timezones.put("America/Louisville", tz);
227     timezones.put("America/Montreal", tz);
228     timezones.put("America/Nassau", tz);
229     timezones.put("America/New_York", tz);
230     timezones.put("America/Nipigon", tz);
231     timezones.put("America/Thunder_Bay", tz);
232     tz = new SimpleTimeZone(-4000 * 3600, "PRT");
233     timezones.put("PRT", tz);
234     timezones.put("America/Anguilla", tz);
235     timezones.put("America/Antigua", tz);
236     timezones.put("America/Aruba", tz);
237     timezones.put("America/Barbados", tz);
238     timezones.put("America/Boa_Vista", tz);
239     timezones.put("America/Caracas", tz);
240     timezones.put("America/Curacao", tz);
241     timezones.put("America/Dominica", tz);
242     timezones.put("America/Grenada", tz);
243     timezones.put("America/Guadeloupe", tz);
244     timezones.put("America/Guyana", tz);
245     timezones.put("America/La_Paz", tz);
246     timezones.put("America/Manaus", tz);
247     timezones.put("America/Martinique", tz);
248     timezones.put("America/Montserrat", tz);
249     timezones.put("America/Port_of_Spain", tz);
250     timezones.put("America/Porto_Velho", tz);
251     timezones.put("America/Puerto_Rico", tz);
252     timezones.put("America/Santo_Domingo", tz);
253     timezones.put("America/St_Kitts", tz);
254     timezones.put("America/St_Lucia", tz);
255     timezones.put("America/St_Thomas", tz);
256     timezones.put("America/St_Vincent", tz);
257     timezones.put("America/Tortola", tz);
258     tz = new SimpleTimeZone
259       (-4000 * 3600, "America/Asuncion",
260        Calendar.OCTOBER, 1, Calendar.SUNDAY, 0 * 3600,
261        Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600);
262     timezones.put("America/Asuncion", tz);
263     tz = new SimpleTimeZone
264       (-4000 * 3600, "America/Cuiaba",
265        Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600,
266        Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600);
267     timezones.put("America/Cuiaba", tz);
268     tz = new SimpleTimeZone
269       (-4000 * 3600, "America/Goose_Bay",
270        Calendar.APRIL, 1, Calendar.SUNDAY, 60000,
271        Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000);
272     timezones.put("America/Goose_Bay", tz);
273     tz = new SimpleTimeZone
274       (-4000 * 3600, "America/Glace_Bay",
275        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
276        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
277     timezones.put("America/Glace_Bay", tz);
278     timezones.put("America/Halifax", tz);
279     timezones.put("America/Thule", tz);
280     timezones.put("Atlantic/Bermuda", tz);
281     tz = new SimpleTimeZone
282       (-4000 * 3600, "America/Santiago",
283        Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600,
284        Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600);
285     timezones.put("America/Santiago", tz);
286     timezones.put("Antarctica/Palmer", tz);
287     tz = new SimpleTimeZone
288       (-4000 * 3600, "Atlantic/Stanley",
289        Calendar.SEPTEMBER, 2, Calendar.SUNDAY, 0 * 3600,
290        Calendar.APRIL, 16, -Calendar.SUNDAY, 0 * 3600);
291     timezones.put("Atlantic/Stanley", tz);
292     tz = new SimpleTimeZone
293       (-3500 * 3600, "CNT",
294        Calendar.APRIL, 1, Calendar.SUNDAY, 60000,
295        Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000);
296     timezones.put("CNT", tz);
297     timezones.put("America/St_Johns", tz);
298     tz = new SimpleTimeZone
299       (-3000 * 3600, "America/Araguaina",
300        Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600,
301        Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600);
302     timezones.put("America/Araguaina", tz);
303     timezones.put("America/Sao_Paulo", tz);
304     tz = new SimpleTimeZone(-3000 * 3600, "AGT");
305     timezones.put("AGT", tz);
306     timezones.put("America/Belem", tz);
307     timezones.put("America/Buenos_Aires", tz);
308     timezones.put("America/Catamarca", tz);
309     timezones.put("America/Cayenne", tz);
310     timezones.put("America/Cordoba", tz);
311     timezones.put("America/Fortaleza", tz);
312     timezones.put("America/Jujuy", tz);
313     timezones.put("America/Maceio", tz);
314     timezones.put("America/Mendoza", tz);
315     timezones.put("America/Montevideo", tz);
316     timezones.put("America/Paramaribo", tz);
317     timezones.put("America/Recife", tz);
318     timezones.put("America/Rosario", tz);
319     tz = new SimpleTimeZone
320       (-3000 * 3600, "America/Godthab",
321        Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600,
322        Calendar.OCTOBER, 30, -Calendar.SATURDAY, 22000 * 3600);
323     timezones.put("America/Godthab", tz);
324     tz = new SimpleTimeZone
325       (-3000 * 3600, "America/Miquelon",
326        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
327        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
328     timezones.put("America/Miquelon", tz);
329     tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha");
330     timezones.put("America/Noronha", tz);
331     timezones.put("Atlantic/South_Georgia", tz);
332     tz = new SimpleTimeZone
333       (-1000 * 3600, "America/Scoresbysund",
334        Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
335        Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
336     timezones.put("America/Scoresbysund", tz);
337     timezones.put("Atlantic/Azores", tz);
338     tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde");
339     timezones.put("Atlantic/Cape_Verde", tz);
340     timezones.put("Atlantic/Jan_Mayen", tz);
341     tz = new SimpleTimeZone(0 * 3600, "GMT");
342     timezones.put("GMT", tz);
343     timezones.put("UTC", tz);
344     timezones.put("Africa/Abidjan", tz);
345     timezones.put("Africa/Accra", tz);
346     timezones.put("Africa/Bamako", tz);
347     timezones.put("Africa/Banjul", tz);
348     timezones.put("Africa/Bissau", tz);
349     timezones.put("Africa/Casablanca", tz);
350     timezones.put("Africa/Conakry", tz);
351     timezones.put("Africa/Dakar", tz);
352     timezones.put("Africa/El_Aaiun", tz);
353     timezones.put("Africa/Freetown", tz);
354     timezones.put("Africa/Lome", tz);
355     timezones.put("Africa/Monrovia", tz);
356     timezones.put("Africa/Nouakchott", tz);
357     timezones.put("Africa/Ouagadougou", tz);
358     timezones.put("Africa/Sao_Tome", tz);
359     timezones.put("Africa/Timbuktu", tz);
360     timezones.put("Atlantic/Reykjavik", tz);
361     timezones.put("Atlantic/St_Helena", tz);
362     timezones.put("Europe/Belfast", tz);
363     timezones.put("Europe/Dublin", tz);
364     timezones.put("Europe/London", tz);
365     tz = new SimpleTimeZone
366       (0 * 3600, "WET",
367        Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600,
368        Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
369     timezones.put("WET", tz);
370     timezones.put("Atlantic/Canary", tz);
371     timezones.put("Atlantic/Faeroe", tz);
372     timezones.put("Atlantic/Madeira", tz);
373     timezones.put("Europe/Lisbon", tz);
374     tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers");
375     timezones.put("Africa/Algiers", tz);
376     timezones.put("Africa/Bangui", tz);
377     timezones.put("Africa/Brazzaville", tz);
378     timezones.put("Africa/Douala", tz);
379     timezones.put("Africa/Kinshasa", tz);
380     timezones.put("Africa/Lagos", tz);
381     timezones.put("Africa/Libreville", tz);
382     timezones.put("Africa/Luanda", tz);
383     timezones.put("Africa/Malabo", tz);
384     timezones.put("Africa/Ndjamena", tz);
385     timezones.put("Africa/Niamey", tz);
386     timezones.put("Africa/Porto-Novo", tz);
387     timezones.put("Africa/Tunis", tz);
388     tz = new SimpleTimeZone
389       (1000 * 3600, "Africa/Windhoek",
390        Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600,
391        Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600);
392     timezones.put("Africa/Windhoek", tz);
393     tz = new SimpleTimeZone
394       (1000 * 3600, "CET",
395        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
396        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
397     timezones.put("CET", tz);
398     timezones.put("ECT", tz);
399     timezones.put("MET", tz);
400     timezones.put("Africa/Ceuta", tz);
401     timezones.put("Arctic/Longyearbyen", tz);
402     timezones.put("Europe/Amsterdam", tz);
403     timezones.put("Europe/Andorra", tz);
404     timezones.put("Europe/Belgrade", tz);
405     timezones.put("Europe/Berlin", tz);
406     timezones.put("Europe/Bratislava", tz);
407     timezones.put("Europe/Brussels", tz);
408     timezones.put("Europe/Budapest", tz);
409     timezones.put("Europe/Copenhagen", tz);
410     timezones.put("Europe/Gibraltar", tz);
411     timezones.put("Europe/Ljubljana", tz);
412     timezones.put("Europe/Luxembourg", tz);
413     timezones.put("Europe/Madrid", tz);
414     timezones.put("Europe/Malta", tz);
415     timezones.put("Europe/Monaco", tz);
416     timezones.put("Europe/Oslo", tz);
417     timezones.put("Europe/Paris", tz);
418     timezones.put("Europe/Prague", tz);
419     timezones.put("Europe/Rome", tz);
420     timezones.put("Europe/San_Marino", tz);
421     timezones.put("Europe/Sarajevo", tz);
422     timezones.put("Europe/Skopje", tz);
423     timezones.put("Europe/Stockholm", tz);
424     timezones.put("Europe/Tirane", tz);
425     timezones.put("Europe/Vaduz", tz);
426     timezones.put("Europe/Vatican", tz);
427     timezones.put("Europe/Vienna", tz);
428     timezones.put("Europe/Warsaw", tz);
429     timezones.put("Europe/Zagreb", tz);
430     timezones.put("Europe/Zurich", tz);
431     tz = new SimpleTimeZone
432       (2000 * 3600, "ART",
433        Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600,
434        Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 23000 * 3600);
435     timezones.put("ART", tz);
436     timezones.put("Africa/Cairo", tz);
437     tz = new SimpleTimeZone(2000 * 3600, "CAT");
438     timezones.put("CAT", tz);
439     timezones.put("Africa/Blantyre", tz);
440     timezones.put("Africa/Bujumbura", tz);
441     timezones.put("Africa/Gaborone", tz);
442     timezones.put("Africa/Harare", tz);
443     timezones.put("Africa/Johannesburg", tz);
444     timezones.put("Africa/Kigali", tz);
445     timezones.put("Africa/Lubumbashi", tz);
446     timezones.put("Africa/Lusaka", tz);
447     timezones.put("Africa/Maputo", tz);
448     timezones.put("Africa/Maseru", tz);
449     timezones.put("Africa/Mbabane", tz);
450     timezones.put("Africa/Tripoli", tz);
451     timezones.put("Europe/Riga", tz);
452     timezones.put("Europe/Tallinn", tz);
453     timezones.put("Europe/Vilnius", tz);
454     tz = new SimpleTimeZone
455       (2000 * 3600, "Asia/Amman",
456        Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600,
457        Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 0 * 3600);
458     timezones.put("Asia/Amman", tz);
459     tz = new SimpleTimeZone
460       (2000 * 3600, "Asia/Beirut",
461        Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
462        Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
463     timezones.put("Asia/Beirut", tz);
464     tz = new SimpleTimeZone
465       (2000 * 3600, "Asia/Damascus",
466        Calendar.APRIL, 1, 0, 0 * 3600,
467        Calendar.OCTOBER, 1, 0, 0 * 3600);
468     timezones.put("Asia/Damascus", tz);
469     tz = new SimpleTimeZone
470       (2000 * 3600, "Asia/Gaza",
471        Calendar.APRIL, 3, Calendar.FRIDAY, 0 * 3600,
472        Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600);
473     timezones.put("Asia/Gaza", tz);
474     tz = new SimpleTimeZone
475       (2000 * 3600, "Asia/Jerusalem",
476        Calendar.APRIL, 1, 0, 1000 * 3600,
477        Calendar.OCTOBER, 1, 0, 1000 * 3600);
478     timezones.put("Asia/Jerusalem", tz);
479     tz = new SimpleTimeZone
480       (2000 * 3600, "EET",
481        Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600,
482        Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
483     timezones.put("EET", tz);
484     timezones.put("Asia/Istanbul", tz);
485     timezones.put("Asia/Nicosia", tz);
486     timezones.put("Europe/Athens", tz);
487     timezones.put("Europe/Bucharest", tz);
488     timezones.put("Europe/Chisinau", tz);
489     timezones.put("Europe/Helsinki", tz);
490     timezones.put("Europe/Istanbul", tz);
491     timezones.put("Europe/Kiev", tz);
492     timezones.put("Europe/Nicosia", tz);
493     timezones.put("Europe/Simferopol", tz);
494     timezones.put("Europe/Sofia", tz);
495     timezones.put("Europe/Uzhgorod", tz);
496     timezones.put("Europe/Zaporozhye", tz);
497     tz = new SimpleTimeZone
498       (2000 * 3600, "Europe/Kaliningrad",
499        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
500        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
501     timezones.put("Europe/Kaliningrad", tz);
502     timezones.put("Europe/Minsk", tz);
503     tz = new SimpleTimeZone
504       (3000 * 3600, "Asia/Baghdad",
505        Calendar.APRIL, 1, 0, 3000 * 3600,
506        Calendar.OCTOBER, 1, 0, 3000 * 3600);
507     timezones.put("Asia/Baghdad", tz);
508     tz = new SimpleTimeZone
509       (3000 * 3600, "Europe/Moscow",
510        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
511        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
512     timezones.put("Europe/Moscow", tz);
513     timezones.put("Europe/Tiraspol", tz);
514     tz = new SimpleTimeZone(3000 * 3600, "EAT");
515     timezones.put("EAT", tz);
516     timezones.put("Africa/Addis_Ababa", tz);
517     timezones.put("Africa/Asmera", tz);
518     timezones.put("Africa/Dar_es_Salaam", tz);
519     timezones.put("Africa/Djibouti", tz);
520     timezones.put("Africa/Kampala", tz);
521     timezones.put("Africa/Khartoum", tz);
522     timezones.put("Africa/Mogadishu", tz);
523     timezones.put("Africa/Nairobi", tz);
524     timezones.put("Antarctica/Syowa", tz);
525     timezones.put("Asia/Aden", tz);
526     timezones.put("Asia/Bahrain", tz);
527     timezones.put("Asia/Kuwait", tz);
528     timezones.put("Asia/Qatar", tz);
529     timezones.put("Asia/Riyadh", tz);
530     timezones.put("Indian/Antananarivo", tz);
531     timezones.put("Indian/Comoro", tz);
532     timezones.put("Indian/Mayotte", tz);
533     tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran");
534     timezones.put("Asia/Tehran", tz);
535     tz = new SimpleTimeZone
536       (4000 * 3600, "Asia/Baku",
537        Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600,
538        Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
539     timezones.put("Asia/Baku", tz);
540     tz = new SimpleTimeZone
541       (4000 * 3600, "Asia/Aqtau",
542        Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
543        Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
544     timezones.put("Asia/Aqtau", tz);
545     timezones.put("Asia/Tbilisi", tz);
546     tz = new SimpleTimeZone
547       (4000 * 3600, "Asia/Yerevan",
548        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
549        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
550     timezones.put("Asia/Yerevan", tz);
551     timezones.put("Europe/Samara", tz);
552     tz = new SimpleTimeZone(4000 * 3600, "NET");
553     timezones.put("NET", tz);
554     timezones.put("Asia/Dubai", tz);
555     timezones.put("Asia/Muscat", tz);
556     timezones.put("Indian/Mahe", tz);
557     timezones.put("Indian/Mauritius", tz);
558     timezones.put("Indian/Reunion", tz);
559     tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul");
560     timezones.put("Asia/Kabul", tz);
561     tz = new SimpleTimeZone
562       (5000 * 3600, "Asia/Aqtobe",
563        Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
564        Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
565     timezones.put("Asia/Aqtobe", tz);
566     tz = new SimpleTimeZone
567       (5000 * 3600, "Asia/Bishkek",
568        Calendar.MARCH, -1, Calendar.SUNDAY, 2500 * 3600,
569        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2500 * 3600);
570     timezones.put("Asia/Bishkek", tz);
571     tz = new SimpleTimeZone
572       (5000 * 3600, "Asia/Yekaterinburg",
573        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
574        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
575     timezones.put("Asia/Yekaterinburg", tz);
576     tz = new SimpleTimeZone(5000 * 3600, "PLT");
577     timezones.put("PLT", tz);
578     timezones.put("Asia/Ashgabat", tz);
579     timezones.put("Asia/Dushanbe", tz);
580     timezones.put("Asia/Karachi", tz);
581     timezones.put("Asia/Samarkand", tz);
582     timezones.put("Asia/Tashkent", tz);
583     timezones.put("Indian/Chagos", tz);
584     timezones.put("Indian/Kerguelen", tz);
585     timezones.put("Indian/Maldives", tz);
586     tz = new SimpleTimeZone(5500 * 3600, "IST");
587     timezones.put("IST", tz);
588     timezones.put("Asia/Calcutta", tz);
589     tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu");
590     timezones.put("Asia/Katmandu", tz);
591     tz = new SimpleTimeZone(6000 * 3600, "BST");
592     timezones.put("BST", tz);
593     timezones.put("Antarctica/Mawson", tz);
594     timezones.put("Asia/Colombo", tz);
595     timezones.put("Asia/Dhaka", tz);
596     timezones.put("Asia/Thimphu", tz);
597     tz = new SimpleTimeZone
598       (6000 * 3600, "Asia/Almaty",
599        Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
600        Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
601     timezones.put("Asia/Almaty", tz);
602     tz = new SimpleTimeZone
603       (6000 * 3600, "Asia/Novosibirsk",
604        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
605        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
606     timezones.put("Asia/Novosibirsk", tz);
607     timezones.put("Asia/Omsk", tz);
608     tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon");
609     timezones.put("Asia/Rangoon", tz);
610     timezones.put("Indian/Cocos", tz);
611     tz = new SimpleTimeZone(7000 * 3600, "VST");
612     timezones.put("VST", tz);
613     timezones.put("Antarctica/Davis", tz);
614     timezones.put("Asia/Bangkok", tz);
615     timezones.put("Asia/Hovd", tz);
616     timezones.put("Asia/Jakarta", tz);
617     timezones.put("Asia/Phnom_Penh", tz);
618     timezones.put("Asia/Saigon", tz);
619     timezones.put("Asia/Vientiane", tz);
620     timezones.put("Indian/Christmas", tz);
621     tz = new SimpleTimeZone
622       (7000 * 3600, "Asia/Krasnoyarsk",
623        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
624        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
625     timezones.put("Asia/Krasnoyarsk", tz);
626     tz = new SimpleTimeZone(8000 * 3600, "CTT");
627     timezones.put("CTT", tz);
628     timezones.put("Antarctica/Casey", tz);
629     timezones.put("Asia/Brunei", tz);
630     timezones.put("Asia/Chungking", tz);
631     timezones.put("Asia/Harbin", tz);
632     timezones.put("Asia/Hong_Kong", tz);
633     timezones.put("Asia/Kashgar", tz);
634     timezones.put("Asia/Kuala_Lumpur", tz);
635     timezones.put("Asia/Kuching", tz);
636     timezones.put("Asia/Macao", tz);
637     timezones.put("Asia/Manila", tz);
638     timezones.put("Asia/Shanghai", tz);
639     timezones.put("Asia/Singapore", tz);
640     timezones.put("Asia/Taipei", tz);
641     timezones.put("Asia/Ujung_Pandang", tz);
642     timezones.put("Asia/Ulaanbaatar", tz);
643     timezones.put("Asia/Urumqi", tz);
644     timezones.put("Australia/Perth", tz);
645     tz = new SimpleTimeZone
646       (8000 * 3600, "Asia/Irkutsk",
647        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
648        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
649     timezones.put("Asia/Irkutsk", tz);
650     tz = new SimpleTimeZone(9000 * 3600, "JST");
651     timezones.put("JST", tz);
652     timezones.put("Asia/Dili", tz);
653     timezones.put("Asia/Jayapura", tz);
654     timezones.put("Asia/Pyongyang", tz);
655     timezones.put("Asia/Seoul", tz);
656     timezones.put("Asia/Tokyo", tz);
657     timezones.put("Pacific/Palau", tz);
658     tz = new SimpleTimeZone
659       (9000 * 3600, "Asia/Yakutsk",
660        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
661        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
662     timezones.put("Asia/Yakutsk", tz);
663     tz = new SimpleTimeZone
664       (9500 * 3600, "Australia/Adelaide",
665        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
666        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600);
667     timezones.put("Australia/Adelaide", tz);
668     timezones.put("Australia/Broken_Hill", tz);
669     tz = new SimpleTimeZone(9500 * 3600, "ACT");
670     timezones.put("ACT", tz);
671     timezones.put("Australia/Darwin", tz);
672     tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville");
673     timezones.put("Antarctica/DumontDUrville", tz);
674     timezones.put("Australia/Brisbane", tz);
675     timezones.put("Australia/Lindeman", tz);
676     timezones.put("Pacific/Guam", tz);
677     timezones.put("Pacific/Port_Moresby", tz);
678     timezones.put("Pacific/Saipan", tz);
679     timezones.put("Pacific/Truk", tz);
680     timezones.put("Pacific/Yap", tz);
681     tz = new SimpleTimeZone
682       (10000 * 3600, "Asia/Vladivostok",
683        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
684        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
685     timezones.put("Asia/Vladivostok", tz);
686     tz = new SimpleTimeZone
687       (10000 * 3600, "Australia/Hobart",
688        Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
689        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600);
690     timezones.put("Australia/Hobart", tz);
691     tz = new SimpleTimeZone
692       (10000 * 3600, "AET",
693        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
694        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600);
695     timezones.put("AET", tz);
696     timezones.put("Australia/Melbourne", tz);
697     timezones.put("Australia/Sydney", tz);
698     tz = new SimpleTimeZone
699       (10500 * 3600, "Australia/Lord_Howe",
700        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
701        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600);
702     timezones.put("Australia/Lord_Howe", tz);
703     tz = new SimpleTimeZone
704       (11000 * 3600, "Asia/Magadan",
705        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
706        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
707     timezones.put("Asia/Magadan", tz);
708     tz = new SimpleTimeZone(11000 * 3600, "SST");
709     timezones.put("SST", tz);
710     timezones.put("Pacific/Efate", tz);
711     timezones.put("Pacific/Guadalcanal", tz);
712     timezones.put("Pacific/Kosrae", tz);
713     timezones.put("Pacific/Noumea", tz);
714     timezones.put("Pacific/Ponape", tz);
715     tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk");
716     timezones.put("Pacific/Norfolk", tz);
717     tz = new SimpleTimeZone
718       (12000 * 3600, "NST",
719        Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
720        Calendar.MARCH, 3, Calendar.SUNDAY, 2000 * 3600);
721     timezones.put("NST", tz);
722     timezones.put("Antarctica/McMurdo", tz);
723     timezones.put("Antarctica/South_Pole", tz);
724     timezones.put("Pacific/Auckland", tz);
725     tz = new SimpleTimeZone
726       (12000 * 3600, "Asia/Anadyr",
727        Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
728        Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
729     timezones.put("Asia/Anadyr", tz);
730     timezones.put("Asia/Kamchatka", tz);
731     tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji");
732     timezones.put("Pacific/Fiji", tz);
733     timezones.put("Pacific/Funafuti", tz);
734     timezones.put("Pacific/Kwajalein", tz);
735     timezones.put("Pacific/Majuro", tz);
736     timezones.put("Pacific/Nauru", tz);
737     timezones.put("Pacific/Tarawa", tz);
738     timezones.put("Pacific/Wake", tz);
739     timezones.put("Pacific/Wallis", tz);
740     tz = new SimpleTimeZone
741       (12750 * 3600, "Pacific/Chatham",
742        Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600,
743        Calendar.MARCH, 3, Calendar.SUNDAY, 2750 * 3600);
744     timezones.put("Pacific/Chatham", tz);
745     tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury");
746     timezones.put("Pacific/Enderbury", tz);
747     timezones.put("Pacific/Tongatapu", tz);
748     tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati");
749     timezones.put("Pacific/Kiritimati", tz);
750   }
751
752
753   /* Look up default timezone */
754   static
755   {
756     // System.loadLibrary("javautil");
757
758     String tzid = System.getProperty("user.timezone");
759
760     if (tzid == null)
761       tzid = "GMT";
762
763     defaultZone = getTimeZone(tzid);
764   }
765
766   /**
767    * Gets the time zone offset, for current date, modified in case of 
768    * daylight savings.  This is the offset to add to UTC to get the local
769    * time.
770    * @param era the era of the given date
771    * @param year the year of the given date
772    * @param month the month of the given date, 0 for January.
773    * @param day the day of month
774    * @param dayOfWeek the day of week
775    * @param milliseconds the millis in the day (in local standard time)
776    * @return the time zone offset in milliseconds.
777    */
778   public abstract int getOffset(int era, int year, int month,
779                                 int day, int dayOfWeek, int milliseconds);
780
781   /**
782    * Gets the time zone offset, ignoring daylight savings.  This is
783    * the offset to add to UTC to get the local time.
784    * @return the time zone offset in milliseconds.  
785    */
786   public abstract int getRawOffset();
787
788   /**
789    * Sets the time zone offset, ignoring daylight savings.  This is
790    * the offset to add to UTC to get the local time.
791    * @param offsetMillis the time zone offset to GMT.
792    */
793   public abstract void setRawOffset(int offsetMillis);
794
795   /**
796    * Gets the identifier of this time zone. For instance, PST for
797    * Pacific Standard Time.
798    * @returns the ID of this time zone.  
799    */
800   public String getID()
801   {
802     return ID;
803   }
804
805   /**
806    * Sets the identifier of this time zone. For instance, PST for
807    * Pacific Standard Time.
808    * @param id the new time zone ID.
809    */
810   public void setID(String id)
811   {
812     this.ID = id;
813   }
814
815   /**
816    * This method returns a string name of the time zone suitable
817    * for displaying to the user.  The string returned will be the long
818    * description of the timezone in the current locale.  The name
819    * displayed will assume daylight savings time is not in effect.
820    *
821    * @return The name of the time zone.
822    */
823   public final String getDisplayName()
824   {
825     return (getDisplayName(false, LONG, Locale.getDefault()));
826   }
827
828   /**
829    * This method returns a string name of the time zone suitable
830    * for displaying to the user.  The string returned will be the long
831    * description of the timezone in the specified locale. The name
832    * displayed will assume daylight savings time is not in effect.
833    *
834    * @param locale The locale for this timezone name.
835    *
836    * @return The name of the time zone.
837    */
838   public final String getDisplayName(Locale locale)
839   {
840     return (getDisplayName(false, LONG, locale));
841   }
842
843   /**
844    * This method returns a string name of the time zone suitable
845    * for displaying to the user.  The string returned will be of the
846    * specified type in the current locale. 
847    *
848    * @param dst Whether or not daylight savings time is in effect.
849    * @param style <code>LONG</code> for a long name, <code>SHORT</code> for
850    * a short abbreviation.
851    *
852    * @return The name of the time zone.
853    */
854   public final String getDisplayName(boolean dst, int style)
855   {
856     return (getDisplayName(dst, style, Locale.getDefault()));
857   }
858
859
860   /**
861    * This method returns a string name of the time zone suitable
862    * for displaying to the user.  The string returned will be of the
863    * specified type in the specified locale. 
864    *
865    * @param dst Whether or not daylight savings time is in effect.
866    * @param style <code>LONG</code> for a long name, <code>SHORT</code> for
867    * a short abbreviation.
868    * @param locale The locale for this timezone name.
869    *
870    * @return The name of the time zone.
871    */
872   public String getDisplayName(boolean dst, int style, Locale locale)
873   {
874     DateFormatSymbols dfs;
875     try
876       {
877         dfs = new DateFormatSymbols(locale);
878
879         // The format of the value returned is defined by us.
880         String[][]zoneinfo = dfs.getZoneStrings();
881         for (int i = 0; i < zoneinfo.length; i++)
882           {
883             if (zoneinfo[i][0].equals(getID()))
884               {
885                 if (!dst)
886                   {
887                     if (style == SHORT)
888                       return (zoneinfo[i][2]);
889                     else
890                       return (zoneinfo[i][1]);
891                   }
892                 else
893                   {
894                     if (style == SHORT)
895                       return (zoneinfo[i][4]);
896                     else
897                       return (zoneinfo[i][3]);
898                   }
899               }
900           }
901       }
902     catch (MissingResourceException e)
903       {
904       }
905
906     return getDefaultDisplayName(dst);
907   }
908
909   private String getDefaultDisplayName(boolean dst)
910   {
911     int offset = getRawOffset();
912     if (dst && this instanceof SimpleTimeZone)
913       {
914         // ugly, but this is a design failure of the API:
915         // getDisplayName takes a dst parameter even though
916         // TimeZone knows nothing about daylight saving offsets.
917         offset += ((SimpleTimeZone) this).getDSTSavings();
918       }
919
920     StringBuffer sb = new StringBuffer(9);
921     sb.append("GMT");
922     sb.append(offset >= 0 ? '+' : '-');
923
924     offset = Math.abs(offset) / (1000 * 60);
925     int hours = offset / 60;
926     int minutes = offset % 60;
927
928     sb.append((char) ('0' + hours / 10)).append((char) ('0' + hours % 10));
929     sb.append(':');
930     sb.append((char) ('0' + minutes / 10)).append((char) ('0' + minutes % 10));
931     return sb.toString();
932   }
933
934   /** 
935    * Returns true, if this time zone uses Daylight Savings Time.
936    */
937   public abstract boolean useDaylightTime();
938
939   /**
940    * Returns true, if the given date is in Daylight Savings Time in this
941    * time zone.
942    * @param date the given Date.
943    */
944   public abstract boolean inDaylightTime(Date date);
945
946   /**
947    * Gets the TimeZone for the given ID.
948    * @param ID the time zone identifier.
949    * @return The time zone for the identifier or GMT, if no such time
950    * zone exists.
951    */
952   // FIXME: XXX: JCL indicates this and other methods are synchronized.
953   public static TimeZone getTimeZone(String ID)
954   {
955     // First check timezones hash
956     TimeZone tz = (TimeZone) timezones.get(ID);
957     if (tz != null)
958       {
959         if (tz.getID().equals(ID))
960           return tz;
961
962         // We always return a timezone with the requested ID.
963         // This is the same behaviour as with JDK1.2.
964         tz = (TimeZone) tz.clone();
965         tz.setID(ID);
966         // We also save the alias, so that we return the same
967         // object again if getTimeZone is called with the same
968         // alias.
969         timezones.put(ID, tz);
970         return tz;
971       }
972
973     // See if the ID is really a GMT offset form.
974     // Note that GMT is in the table so we know it is different.
975     if (ID.startsWith("GMT"))
976       {
977         int pos = 3;
978         int offset_direction = 1;
979
980         if (ID.charAt(pos) == '-')
981           {
982             offset_direction = -1;
983             pos++;
984           }
985         else if (ID.charAt(pos) == '+')
986           {
987             pos++;
988           }
989
990         try
991           {
992             int hour, minute;
993
994             String offset_str = ID.substring(pos);
995             int idx = offset_str.indexOf(":");
996             if (idx != -1)
997               {
998                 hour = Integer.parseInt(offset_str.substring(0, idx));
999                 minute = Integer.parseInt(offset_str.substring(idx + 1));
1000               }
1001             else
1002               {
1003                 int offset_length = offset_str.length();
1004                 if (offset_length <= 2)
1005                   {
1006                     // Only hour
1007                     hour = Integer.parseInt(offset_str);
1008                     minute = 0;
1009                   }
1010                 else
1011                   {
1012                     // hour and minute, not separated by colon
1013                     hour = Integer.parseInt
1014                       (offset_str.substring(0, offset_length - 2));
1015                     minute = Integer.parseInt
1016                       (offset_str.substring(offset_length - 2));
1017                   }
1018               }
1019
1020             return new SimpleTimeZone((hour * (60 * 60 * 1000) +
1021                                        minute * (60 * 1000))
1022                                       * offset_direction, ID);
1023           }
1024         catch (NumberFormatException e)
1025           {
1026           }
1027       }
1028
1029     // Finally, return GMT per spec
1030     return getTimeZone("GMT");
1031   }
1032
1033   /**
1034    * Gets the available IDs according to the given time zone
1035    * offset.  
1036    * @param rawOffset the given time zone GMT offset.
1037    * @return An array of IDs, where the time zone has the specified GMT
1038    * offset. For example <code>{"Phoenix", "Denver"}</code>, since both have
1039    * GMT-07:00, but differ in daylight savings behaviour.
1040    */
1041   public static String[] getAvailableIDs(int rawOffset)
1042   {
1043     int count = 0;
1044     Iterator iter = timezones.entrySet().iterator();
1045     while (iter.hasNext())
1046       {
1047         // Don't iterate the values, since we want to count 
1048         // doubled values (aliases)
1049         Map.Entry entry = (Map.Entry) iter.next();
1050         if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1051           count++;
1052       }
1053
1054     String[] ids = new String[count];
1055     count = 0;
1056     iter = timezones.entrySet().iterator();
1057     while (iter.hasNext())
1058       {
1059         Map.Entry entry = (Map.Entry) iter.next();
1060         if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1061           ids[count++] = (String) entry.getKey();
1062       }
1063     return ids;
1064   }
1065
1066   /**
1067    * Gets all available IDs.
1068    * @return An array of all supported IDs.
1069    */
1070   public static String[] getAvailableIDs()
1071   {
1072     return (String[])
1073       timezones.keySet().toArray(new String[timezones.size()]);
1074   }
1075
1076   /**
1077    * Returns the time zone under which the host is running.  This
1078    * can be changed with setDefault.
1079    * @return the time zone for this host.
1080    * @see #setDefault
1081    */
1082   public static TimeZone getDefault()
1083   {
1084     return defaultZone;
1085   }
1086
1087   public static void setDefault(TimeZone zone)
1088   {
1089     defaultZone = zone;
1090   }
1091
1092   /**
1093    * Test if the other time zone uses the same rule and only
1094    * possibly differs in ID.  This implementation for this particular
1095    * class will return true if the raw offsets are identical.  Subclasses
1096    * should override this method if they use daylight savings.
1097    * @return true if this zone has the same raw offset
1098    */
1099   public boolean hasSameRules(TimeZone other)
1100   {
1101     return other.getRawOffset() == getRawOffset();
1102   }
1103
1104   /**
1105    * Returns a clone of this object.  I can't imagine, why this is
1106    * useful for a time zone.
1107    */
1108   public Object clone()
1109   {
1110     try
1111       {
1112         return super.clone();
1113       }
1114     catch (CloneNotSupportedException ex)
1115       {
1116         return null;
1117       }
1118   }
1119 }