2 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
40 import java.text.DateFormatSymbols;
43 * This class represents a time zone offset and handles daylight savings.
45 * You can get the default time zone with <code>getDefault</code>.
46 * This represents the time zone where program is running.
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".
52 * With the <code>getAvailableIDs</code> method, you can get all the
53 * supported time zone identifiers.
57 * @author Jochen Hoenicke
59 public abstract class TimeZone implements java.io.Serializable, Cloneable
63 * Constant used to indicate that a short timezone abbreviation should
64 * be returned, such as "EST"
66 public static final int SHORT = 0;
69 * Constant used to indicate that a long timezone name should be
70 * returned, such as "Eastern Standard Time".
72 public static final int LONG = 1;
75 * The time zone identifier, e.g. PST.
80 * The default time zone, as returned by getDefault.
82 private static TimeZone defaultZone;
84 private static final long serialVersionUID = 3581463369166924961L;
87 * Hashtable for timezones by ID.
89 private static final Hashtable timezones = new Hashtable();
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
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
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
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
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);
753 /* Look up default timezone */
756 // System.loadLibrary("javautil");
758 String tzid = System.getProperty("user.timezone");
763 defaultZone = getTimeZone(tzid);
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
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.
778 public abstract int getOffset(int era, int year, int month,
779 int day, int dayOfWeek, int milliseconds);
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.
786 public abstract int getRawOffset();
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.
793 public abstract void setRawOffset(int offsetMillis);
796 * Gets the identifier of this time zone. For instance, PST for
797 * Pacific Standard Time.
798 * @returns the ID of this time zone.
800 public String getID()
806 * Sets the identifier of this time zone. For instance, PST for
807 * Pacific Standard Time.
808 * @param id the new time zone ID.
810 public void setID(String id)
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.
821 * @return The name of the time zone.
823 public final String getDisplayName()
825 return (getDisplayName(false, LONG, Locale.getDefault()));
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.
834 * @param locale The locale for this timezone name.
836 * @return The name of the time zone.
838 public final String getDisplayName(Locale locale)
840 return (getDisplayName(false, LONG, locale));
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.
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.
852 * @return The name of the time zone.
854 public final String getDisplayName(boolean dst, int style)
856 return (getDisplayName(dst, style, Locale.getDefault()));
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.
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.
870 * @return The name of the time zone.
872 public String getDisplayName(boolean dst, int style, Locale locale)
874 DateFormatSymbols dfs;
877 dfs = new DateFormatSymbols(locale);
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++)
883 if (zoneinfo[i][0].equals(getID()))
888 return (zoneinfo[i][2]);
890 return (zoneinfo[i][1]);
895 return (zoneinfo[i][4]);
897 return (zoneinfo[i][3]);
902 catch (MissingResourceException e)
906 return getDefaultDisplayName(dst);
909 private String getDefaultDisplayName(boolean dst)
911 int offset = getRawOffset();
912 if (dst && this instanceof SimpleTimeZone)
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();
920 StringBuffer sb = new StringBuffer(9);
922 sb.append(offset >= 0 ? '+' : '-');
924 offset = Math.abs(offset) / (1000 * 60);
925 int hours = offset / 60;
926 int minutes = offset % 60;
928 sb.append((char) ('0' + hours / 10)).append((char) ('0' + hours % 10));
930 sb.append((char) ('0' + minutes / 10)).append((char) ('0' + minutes % 10));
931 return sb.toString();
935 * Returns true, if this time zone uses Daylight Savings Time.
937 public abstract boolean useDaylightTime();
940 * Returns true, if the given date is in Daylight Savings Time in this
942 * @param date the given Date.
944 public abstract boolean inDaylightTime(Date date);
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
952 // FIXME: XXX: JCL indicates this and other methods are synchronized.
953 public static TimeZone getTimeZone(String ID)
955 // First check timezones hash
956 TimeZone tz = (TimeZone) timezones.get(ID);
959 if (tz.getID().equals(ID))
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();
966 // We also save the alias, so that we return the same
967 // object again if getTimeZone is called with the same
969 timezones.put(ID, tz);
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"))
978 int offset_direction = 1;
980 if (ID.charAt(pos) == '-')
982 offset_direction = -1;
985 else if (ID.charAt(pos) == '+')
994 String offset_str = ID.substring(pos);
995 int idx = offset_str.indexOf(":");
998 hour = Integer.parseInt(offset_str.substring(0, idx));
999 minute = Integer.parseInt(offset_str.substring(idx + 1));
1003 int offset_length = offset_str.length();
1004 if (offset_length <= 2)
1007 hour = Integer.parseInt(offset_str);
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));
1020 return new SimpleTimeZone((hour * (60 * 60 * 1000) +
1021 minute * (60 * 1000))
1022 * offset_direction, ID);
1024 catch (NumberFormatException e)
1029 // Finally, return GMT per spec
1030 return getTimeZone("GMT");
1034 * Gets the available IDs according to the given time zone
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.
1041 public static String[] getAvailableIDs(int rawOffset)
1044 Iterator iter = timezones.entrySet().iterator();
1045 while (iter.hasNext())
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)
1054 String[] ids = new String[count];
1056 iter = timezones.entrySet().iterator();
1057 while (iter.hasNext())
1059 Map.Entry entry = (Map.Entry) iter.next();
1060 if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1061 ids[count++] = (String) entry.getKey();
1067 * Gets all available IDs.
1068 * @return An array of all supported IDs.
1070 public static String[] getAvailableIDs()
1073 timezones.keySet().toArray(new String[timezones.size()]);
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.
1082 public static TimeZone getDefault()
1087 public static void setDefault(TimeZone zone)
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
1099 public boolean hasSameRules(TimeZone other)
1101 return other.getRawOffset() == getRawOffset();
1105 * Returns a clone of this object. I can't imagine, why this is
1106 * useful for a time zone.
1108 public Object clone()
1112 return super.clone();
1114 catch (CloneNotSupportedException ex)