2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
42 /*import gnu.classpath.SystemProperties;
43 import gnu.java.lang.CPStringBuilder;
44 import gnu.java.util.ZoneInfo;
47 import java.security.AccessController;
48 import java.security.PrivilegedAction;
49 import java.text.DateFormatSymbols;*/
52 * This class represents a time zone offset and handles daylight savings.
54 * You can get the default time zone with <code>getDefault</code>.
55 * This represents the time zone where program is running.
57 * Another way to create a time zone is <code>getTimeZone</code>, where
58 * you can give an identifier as parameter. For instance, the identifier
59 * of the Central European Time zone is "CET".
61 * With the <code>getAvailableIDs</code> method, you can get all the
62 * supported time zone identifiers.
66 * @author Jochen Hoenicke
68 public abstract class TimeZone //implements java.io.Serializable, Cloneable
72 * Constant used to indicate that a short timezone abbreviation should
73 * be returned, such as "EST"
75 public static final int SHORT = 0;
78 * Constant used to indicate that a long timezone name should be
79 * returned, such as "Eastern Standard Time".
81 public static final int LONG = 1;
84 * The time zone identifier, e.g. PST.
89 * The default time zone, as returned by getDefault.
91 private static TimeZone defaultZone0;
94 * Tries to get the default TimeZone for this system if not already
95 * set. It will call <code>getDefaultTimeZone(String)</code> with
96 * the result of <code>System.getProperty("user.timezone")</code>.
97 * If that fails it calls <code>VMTimeZone.getDefaultTimeZoneId()</code>.
98 * If that also fails GMT is returned.
100 private static synchronized TimeZone defaultZone()
102 /* Look up default timezone */
103 if (defaultZone0 == null)
105 /*defaultZone0 = (TimeZone) AccessController.doPrivileged
106 (new PrivilegedAction()
110 TimeZone zone = null;
112 // Prefer System property user.timezone.
113 String tzid = System.getProperty("user.timezone");
114 if (tzid != null && !tzid.equals(""))
115 zone = getDefaultTimeZone(tzid);
117 // Try platfom specific way.
119 zone = VMTimeZone.getDefaultTimeZoneId();
123 zone = getTimeZone ("GMT");
133 private static final long serialVersionUID = 3581463369166924961L;
136 * Flag whether zoneinfo data should be used,
137 * otherwise builtin timezone data will be provided.
139 private static String zoneinfo_dir;
142 * Cached copy of getAvailableIDs().
144 private static String[] availableIDs = null;
147 * JDK 1.1.x compatibility aliases.
149 private static HashMap aliases0;
152 * HashMap for timezones by ID.
154 private static HashMap timezones0;
155 /* initialize this static field lazily to overhead if
158 // Package-private to avoid a trampoline.
159 static HashMap timezones()
161 if (timezones0 == null)
163 HashMap timezones = new HashMap();
164 timezones0 = timezones;
166 /*zoneinfo_dir = SystemProperties.getProperty("gnu.java.util.zoneinfo.dir");
167 if (zoneinfo_dir != null && !new File(zoneinfo_dir).isDirectory())
168 zoneinfo_dir = null;*/
170 if (zoneinfo_dir != null)
172 aliases0 = new HashMap();
174 // These deprecated aliases for JDK 1.1.x compatibility
175 // should take precedence over data files read from
176 // /usr/share/zoneinfo.
177 aliases0.put("ACT", "Australia/Darwin");
178 aliases0.put("AET", "Australia/Sydney");
179 aliases0.put("AGT", "America/Argentina/Buenos_Aires");
180 aliases0.put("ART", "Africa/Cairo");
181 aliases0.put("AST", "America/Juneau");
182 aliases0.put("BST", "Asia/Colombo");
183 aliases0.put("CAT", "Africa/Gaborone");
184 aliases0.put("CNT", "America/St_Johns");
185 aliases0.put("CST", "CST6CDT");
186 aliases0.put("CTT", "Asia/Brunei");
187 aliases0.put("EAT", "Indian/Comoro");
188 aliases0.put("ECT", "CET");
189 aliases0.put("EST", "EST5EDT");
190 aliases0.put("EST5", "EST5EDT");
191 aliases0.put("IET", "EST5EDT");
192 aliases0.put("IST", "Asia/Calcutta");
193 aliases0.put("JST", "Asia/Seoul");
194 aliases0.put("MIT", "Pacific/Niue");
195 aliases0.put("MST", "MST7MDT");
196 aliases0.put("MST7", "MST7MDT");
197 aliases0.put("NET", "Indian/Mauritius");
198 aliases0.put("NST", "Pacific/Auckland");
199 aliases0.put("PLT", "Indian/Kerguelen");
200 aliases0.put("PNT", "MST7MDT");
201 aliases0.put("PRT", "America/Anguilla");
202 aliases0.put("PST", "PST8PDT");
203 aliases0.put("SST", "Pacific/Ponape");
204 aliases0.put("VST", "Asia/Bangkok");
209 // Automatically generated by scripts/timezones.pl
210 // XXX - Should we read this data from a file?
211 tz = new SimpleTimeZone(-11000 * 3600, "MIT");
212 timezones0.put("MIT", tz);
213 timezones0.put("Pacific/Apia", tz);
214 timezones0.put("Pacific/Midway", tz);
215 timezones0.put("Pacific/Niue", tz);
216 timezones0.put("Pacific/Pago_Pago", tz);
217 tz = new SimpleTimeZone
218 (-10000 * 3600, "America/Adak",
219 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
220 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
221 timezones0.put("America/Adak", tz);
222 tz = new SimpleTimeZone(-10000 * 3600, "HST");
223 timezones0.put("HST", tz);
224 timezones0.put("Pacific/Fakaofo", tz);
225 timezones0.put("Pacific/Honolulu", tz);
226 timezones0.put("Pacific/Johnston", tz);
227 timezones0.put("Pacific/Rarotonga", tz);
228 timezones0.put("Pacific/Tahiti", tz);
229 tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas");
230 timezones0.put("Pacific/Marquesas", tz);
231 tz = new SimpleTimeZone
232 (-9000 * 3600, "AST",
233 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
234 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
235 timezones0.put("AST", tz);
236 timezones0.put("America/Anchorage", tz);
237 timezones0.put("America/Juneau", tz);
238 timezones0.put("America/Nome", tz);
239 timezones0.put("America/Yakutat", tz);
240 tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier");
241 timezones0.put("Pacific/Gambier", tz);
242 tz = new SimpleTimeZone
243 (-8000 * 3600, "America/Tijuana",
244 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
245 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
246 timezones0.put("America/Tijuana", tz);
247 tz = new SimpleTimeZone
248 (-8000 * 3600, "PST",
249 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
250 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
251 timezones0.put("PST", tz);
252 timezones0.put("PST8PDT", tz);
253 timezones0.put("America/Dawson", tz);
254 timezones0.put("America/Los_Angeles", tz);
255 timezones0.put("America/Vancouver", tz);
256 timezones0.put("America/Whitehorse", tz);
257 timezones0.put("US/Pacific-New", tz);
258 tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn");
259 timezones0.put("Pacific/Pitcairn", tz);
260 tz = new SimpleTimeZone
261 (-7000 * 3600, "America/Chihuahua",
262 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
263 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
264 timezones0.put("America/Chihuahua", tz);
265 timezones0.put("America/Mazatlan", tz);
266 tz = new SimpleTimeZone(-7000 * 3600, "MST7");
267 timezones0.put("MST7", tz);
268 timezones0.put("PNT", tz);
269 timezones0.put("America/Dawson_Creek", tz);
270 timezones0.put("America/Hermosillo", tz);
271 timezones0.put("America/Phoenix", tz);
272 tz = new SimpleTimeZone
273 (-7000 * 3600, "MST",
274 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
275 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
276 timezones0.put("MST", tz);
277 timezones0.put("MST7MDT", tz);
278 timezones0.put("America/Boise", tz);
279 timezones0.put("America/Cambridge_Bay", tz);
280 timezones0.put("America/Denver", tz);
281 timezones0.put("America/Edmonton", tz);
282 timezones0.put("America/Inuvik", tz);
283 timezones0.put("America/Shiprock", tz);
284 timezones0.put("America/Yellowknife", tz);
285 tz = new SimpleTimeZone
286 (-6000 * 3600, "America/Cancun",
287 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600,
288 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
289 timezones0.put("America/Cancun", tz);
290 timezones0.put("America/Merida", tz);
291 timezones0.put("America/Mexico_City", tz);
292 timezones0.put("America/Monterrey", tz);
293 tz = new SimpleTimeZone(-6000 * 3600, "America/Belize");
294 timezones0.put("America/Belize", tz);
295 timezones0.put("America/Costa_Rica", tz);
296 timezones0.put("America/El_Salvador", tz);
297 timezones0.put("America/Guatemala", tz);
298 timezones0.put("America/Managua", tz);
299 timezones0.put("America/Regina", tz);
300 timezones0.put("America/Swift_Current", tz);
301 timezones0.put("America/Tegucigalpa", tz);
302 timezones0.put("Pacific/Galapagos", tz);
303 tz = new SimpleTimeZone
304 (-6000 * 3600, "CST",
305 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
306 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
307 timezones0.put("CST", tz);
308 timezones0.put("CST6CDT", tz);
309 timezones0.put("America/Chicago", tz);
310 timezones0.put("America/Indiana/Knox", tz);
311 timezones0.put("America/Indiana/Petersburg", tz);
312 timezones0.put("America/Indiana/Vincennes", tz);
313 timezones0.put("America/Menominee", tz);
314 timezones0.put("America/North_Dakota/Center", tz);
315 timezones0.put("America/North_Dakota/New_Salem", tz);
316 timezones0.put("America/Rainy_River", tz);
317 timezones0.put("America/Rankin_Inlet", tz);
318 timezones0.put("America/Winnipeg", tz);
319 tz = new SimpleTimeZone
320 (-6000 * 3600, "Pacific/Easter",
321 Calendar.OCTOBER, 2, Calendar.SATURDAY, 22000 * 3600,
322 Calendar.MARCH, 2, Calendar.SATURDAY, 22000 * 3600);
323 timezones0.put("Pacific/Easter", tz);
324 tz = new SimpleTimeZone(-5000 * 3600, "EST5");
325 timezones0.put("EST5", tz);
326 timezones0.put("IET", tz);
327 timezones0.put("America/Atikokan", tz);
328 timezones0.put("America/Bogota", tz);
329 timezones0.put("America/Cayman", tz);
330 timezones0.put("America/Eirunepe", tz);
331 timezones0.put("America/Guayaquil", tz);
332 timezones0.put("America/Jamaica", tz);
333 timezones0.put("America/Lima", tz);
334 timezones0.put("America/Panama", tz);
335 timezones0.put("America/Rio_Branco", tz);
336 tz = new SimpleTimeZone
337 (-5000 * 3600, "America/Havana",
338 Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600,
339 Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
340 timezones0.put("America/Havana", tz);
341 tz = new SimpleTimeZone
342 (-5000 * 3600, "America/Grand_Turk",
343 Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600,
344 Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
345 timezones0.put("America/Grand_Turk", tz);
346 timezones0.put("America/Port-au-Prince", tz);
347 tz = new SimpleTimeZone
348 (-5000 * 3600, "EST",
349 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
350 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
351 timezones0.put("EST", tz);
352 timezones0.put("EST5EDT", tz);
353 timezones0.put("America/Detroit", tz);
354 timezones0.put("America/Indiana/Indianapolis", tz);
355 timezones0.put("America/Indiana/Marengo", tz);
356 timezones0.put("America/Indiana/Vevay", tz);
357 timezones0.put("America/Iqaluit", tz);
358 timezones0.put("America/Kentucky/Louisville", tz);
359 timezones0.put("America/Kentucky/Monticello", tz);
360 timezones0.put("America/Montreal", tz);
361 timezones0.put("America/Nassau", tz);
362 timezones0.put("America/New_York", tz);
363 timezones0.put("America/Nipigon", tz);
364 timezones0.put("America/Pangnirtung", tz);
365 timezones0.put("America/Thunder_Bay", tz);
366 timezones0.put("America/Toronto", tz);
367 tz = new SimpleTimeZone
368 (-4000 * 3600, "America/Asuncion",
369 Calendar.OCTOBER, 3, Calendar.SUNDAY, 0 * 3600,
370 Calendar.MARCH, 2, Calendar.SUNDAY, 0 * 3600);
371 timezones0.put("America/Asuncion", tz);
372 tz = new SimpleTimeZone(-4000 * 3600, "PRT");
373 timezones0.put("PRT", tz);
374 timezones0.put("America/Anguilla", tz);
375 timezones0.put("America/Antigua", tz);
376 timezones0.put("America/Aruba", tz);
377 timezones0.put("America/Barbados", tz);
378 timezones0.put("America/Blanc-Sablon", tz);
379 timezones0.put("America/Boa_Vista", tz);
380 timezones0.put("America/Caracas", tz);
381 timezones0.put("America/Curacao", tz);
382 timezones0.put("America/Dominica", tz);
383 timezones0.put("America/Grenada", tz);
384 timezones0.put("America/Guadeloupe", tz);
385 timezones0.put("America/Guyana", tz);
386 timezones0.put("America/La_Paz", tz);
387 timezones0.put("America/Manaus", tz);
388 timezones0.put("America/Martinique", tz);
389 timezones0.put("America/Montserrat", tz);
390 timezones0.put("America/Port_of_Spain", tz);
391 timezones0.put("America/Porto_Velho", tz);
392 timezones0.put("America/Puerto_Rico", tz);
393 timezones0.put("America/Santo_Domingo", tz);
394 timezones0.put("America/St_Kitts", tz);
395 timezones0.put("America/St_Lucia", tz);
396 timezones0.put("America/St_Thomas", tz);
397 timezones0.put("America/St_Vincent", tz);
398 timezones0.put("America/Tortola", tz);
399 tz = new SimpleTimeZone
400 (-4000 * 3600, "America/Campo_Grande",
401 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600,
402 Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600);
403 timezones0.put("America/Campo_Grande", tz);
404 timezones0.put("America/Cuiaba", tz);
405 tz = new SimpleTimeZone
406 (-4000 * 3600, "America/Goose_Bay",
407 Calendar.MARCH, 2, Calendar.SUNDAY, 60000,
408 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000);
409 timezones0.put("America/Goose_Bay", tz);
410 tz = new SimpleTimeZone
411 (-4000 * 3600, "America/Glace_Bay",
412 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
413 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
414 timezones0.put("America/Glace_Bay", tz);
415 timezones0.put("America/Halifax", tz);
416 timezones0.put("America/Moncton", tz);
417 timezones0.put("America/Thule", tz);
418 timezones0.put("Atlantic/Bermuda", tz);
419 tz = new SimpleTimeZone
420 (-4000 * 3600, "America/Santiago",
421 Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600,
422 Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600);
423 timezones0.put("America/Santiago", tz);
424 timezones0.put("Antarctica/Palmer", tz);
425 tz = new SimpleTimeZone
426 (-4000 * 3600, "Atlantic/Stanley",
427 Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600,
428 Calendar.APRIL, 3, Calendar.SUNDAY, 2000 * 3600);
429 timezones0.put("Atlantic/Stanley", tz);
430 tz = new SimpleTimeZone
431 (-3500 * 3600, "CNT",
432 Calendar.MARCH, 2, Calendar.SUNDAY, 60000,
433 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000);
434 timezones0.put("CNT", tz);
435 timezones0.put("America/St_Johns", tz);
436 tz = new SimpleTimeZone
437 (-3000 * 3600, "America/Godthab",
438 Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600,
439 Calendar.OCTOBER, 30, -Calendar.SATURDAY, 23000 * 3600);
440 timezones0.put("America/Godthab", tz);
441 tz = new SimpleTimeZone
442 (-3000 * 3600, "America/Miquelon",
443 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600,
444 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600);
445 timezones0.put("America/Miquelon", tz);
446 tz = new SimpleTimeZone
447 (-3000 * 3600, "America/Montevideo",
448 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
449 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600);
450 timezones0.put("America/Montevideo", tz);
451 tz = new SimpleTimeZone
452 (-3000 * 3600, "America/Sao_Paulo",
453 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600,
454 Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600);
455 timezones0.put("America/Sao_Paulo", tz);
456 tz = new SimpleTimeZone(-3000 * 3600, "AGT");
457 timezones0.put("AGT", tz);
458 timezones0.put("America/Araguaina", tz);
459 timezones0.put("America/Argentina/Buenos_Aires", tz);
460 timezones0.put("America/Argentina/Catamarca", tz);
461 timezones0.put("America/Argentina/Cordoba", tz);
462 timezones0.put("America/Argentina/Jujuy", tz);
463 timezones0.put("America/Argentina/La_Rioja", tz);
464 timezones0.put("America/Argentina/Mendoza", tz);
465 timezones0.put("America/Argentina/Rio_Gallegos", tz);
466 timezones0.put("America/Argentina/San_Juan", tz);
467 timezones0.put("America/Argentina/Tucuman", tz);
468 timezones0.put("America/Argentina/Ushuaia", tz);
469 timezones0.put("America/Bahia", tz);
470 timezones0.put("America/Belem", tz);
471 timezones0.put("America/Cayenne", tz);
472 timezones0.put("America/Fortaleza", tz);
473 timezones0.put("America/Maceio", tz);
474 timezones0.put("America/Paramaribo", tz);
475 timezones0.put("America/Recife", tz);
476 timezones0.put("Antarctica/Rothera", tz);
477 tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha");
478 timezones0.put("America/Noronha", tz);
479 timezones0.put("Atlantic/South_Georgia", tz);
480 tz = new SimpleTimeZone
481 (-1000 * 3600, "America/Scoresbysund",
482 Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
483 Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600);
484 timezones0.put("America/Scoresbysund", tz);
485 timezones0.put("Atlantic/Azores", tz);
486 tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde");
487 timezones0.put("Atlantic/Cape_Verde", tz);
488 tz = new SimpleTimeZone(0 * 3600, "GMT");
489 timezones0.put("GMT", tz);
490 timezones0.put("UTC", tz);
491 timezones0.put("Africa/Abidjan", tz);
492 timezones0.put("Africa/Accra", tz);
493 timezones0.put("Africa/Bamako", tz);
494 timezones0.put("Africa/Banjul", tz);
495 timezones0.put("Africa/Bissau", tz);
496 timezones0.put("Africa/Casablanca", tz);
497 timezones0.put("Africa/Conakry", tz);
498 timezones0.put("Africa/Dakar", tz);
499 timezones0.put("Africa/El_Aaiun", tz);
500 timezones0.put("Africa/Freetown", tz);
501 timezones0.put("Africa/Lome", tz);
502 timezones0.put("Africa/Monrovia", tz);
503 timezones0.put("Africa/Nouakchott", tz);
504 timezones0.put("Africa/Ouagadougou", tz);
505 timezones0.put("Africa/Sao_Tome", tz);
506 timezones0.put("America/Danmarkshavn", tz);
507 timezones0.put("Atlantic/Reykjavik", tz);
508 timezones0.put("Atlantic/St_Helena", tz);
509 tz = new SimpleTimeZone
511 Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600,
512 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600);
513 timezones0.put("WET", tz);
514 timezones0.put("Atlantic/Canary", tz);
515 timezones0.put("Atlantic/Faroe", tz);
516 timezones0.put("Atlantic/Madeira", tz);
517 timezones0.put("Europe/Dublin", tz);
518 timezones0.put("Europe/Guernsey", tz);
519 timezones0.put("Europe/Isle_of_Man", tz);
520 timezones0.put("Europe/Jersey", tz);
521 timezones0.put("Europe/Lisbon", tz);
522 timezones0.put("Europe/London", tz);
523 tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers");
524 timezones0.put("Africa/Algiers", tz);
525 timezones0.put("Africa/Bangui", tz);
526 timezones0.put("Africa/Brazzaville", tz);
527 timezones0.put("Africa/Douala", tz);
528 timezones0.put("Africa/Kinshasa", tz);
529 timezones0.put("Africa/Lagos", tz);
530 timezones0.put("Africa/Libreville", tz);
531 timezones0.put("Africa/Luanda", tz);
532 timezones0.put("Africa/Malabo", tz);
533 timezones0.put("Africa/Ndjamena", tz);
534 timezones0.put("Africa/Niamey", tz);
535 timezones0.put("Africa/Porto-Novo", tz);
536 tz = new SimpleTimeZone
537 (1000 * 3600, "Africa/Windhoek",
538 Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600,
539 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600);
540 timezones0.put("Africa/Windhoek", tz);
541 tz = new SimpleTimeZone
543 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
544 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
545 timezones0.put("CET", tz);
546 timezones0.put("ECT", tz);
547 timezones0.put("MET", tz);
548 timezones0.put("Africa/Ceuta", tz);
549 timezones0.put("Africa/Tunis", tz);
550 timezones0.put("Arctic/Longyearbyen", tz);
551 timezones0.put("Atlantic/Jan_Mayen", tz);
552 timezones0.put("Europe/Amsterdam", tz);
553 timezones0.put("Europe/Andorra", tz);
554 timezones0.put("Europe/Belgrade", tz);
555 timezones0.put("Europe/Berlin", tz);
556 timezones0.put("Europe/Bratislava", tz);
557 timezones0.put("Europe/Brussels", tz);
558 timezones0.put("Europe/Budapest", tz);
559 timezones0.put("Europe/Copenhagen", tz);
560 timezones0.put("Europe/Gibraltar", tz);
561 timezones0.put("Europe/Ljubljana", tz);
562 timezones0.put("Europe/Luxembourg", tz);
563 timezones0.put("Europe/Madrid", tz);
564 timezones0.put("Europe/Malta", tz);
565 timezones0.put("Europe/Monaco", tz);
566 timezones0.put("Europe/Oslo", tz);
567 timezones0.put("Europe/Paris", tz);
568 timezones0.put("Europe/Podgorica", tz);
569 timezones0.put("Europe/Prague", tz);
570 timezones0.put("Europe/Rome", tz);
571 timezones0.put("Europe/San_Marino", tz);
572 timezones0.put("Europe/Sarajevo", tz);
573 timezones0.put("Europe/Skopje", tz);
574 timezones0.put("Europe/Stockholm", tz);
575 timezones0.put("Europe/Tirane", tz);
576 timezones0.put("Europe/Vaduz", tz);
577 timezones0.put("Europe/Vatican", tz);
578 timezones0.put("Europe/Vienna", tz);
579 timezones0.put("Europe/Warsaw", tz);
580 timezones0.put("Europe/Zagreb", tz);
581 timezones0.put("Europe/Zurich", tz);
582 tz = new SimpleTimeZone
584 Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600,
585 Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 24000 * 3600);
586 timezones0.put("ART", tz);
587 timezones0.put("Africa/Cairo", tz);
588 tz = new SimpleTimeZone(2000 * 3600, "CAT");
589 timezones0.put("CAT", tz);
590 timezones0.put("Africa/Blantyre", tz);
591 timezones0.put("Africa/Bujumbura", tz);
592 timezones0.put("Africa/Gaborone", tz);
593 timezones0.put("Africa/Harare", tz);
594 timezones0.put("Africa/Johannesburg", tz);
595 timezones0.put("Africa/Kigali", tz);
596 timezones0.put("Africa/Lubumbashi", tz);
597 timezones0.put("Africa/Lusaka", tz);
598 timezones0.put("Africa/Maputo", tz);
599 timezones0.put("Africa/Maseru", tz);
600 timezones0.put("Africa/Mbabane", tz);
601 timezones0.put("Africa/Tripoli", tz);
602 timezones0.put("Asia/Jerusalem", tz);
603 tz = new SimpleTimeZone
604 (2000 * 3600, "Asia/Amman",
605 Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600,
606 Calendar.OCTOBER, -1, Calendar.FRIDAY, 1000 * 3600);
607 timezones0.put("Asia/Amman", tz);
608 tz = new SimpleTimeZone
609 (2000 * 3600, "Asia/Beirut",
610 Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600,
611 Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600);
612 timezones0.put("Asia/Beirut", tz);
613 tz = new SimpleTimeZone
614 (2000 * 3600, "Asia/Damascus",
615 Calendar.APRIL, 1, 0, 0 * 3600,
616 Calendar.OCTOBER, 1, 0, 0 * 3600);
617 timezones0.put("Asia/Damascus", tz);
618 tz = new SimpleTimeZone
619 (2000 * 3600, "Asia/Gaza",
620 Calendar.APRIL, 1, 0, 0 * 3600,
621 Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600);
622 timezones0.put("Asia/Gaza", tz);
623 tz = new SimpleTimeZone
625 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600,
626 Calendar.OCTOBER, -1, Calendar.SUNDAY, 4000 * 3600);
627 timezones0.put("EET", tz);
628 timezones0.put("Asia/Istanbul", tz);
629 timezones0.put("Asia/Nicosia", tz);
630 timezones0.put("Europe/Athens", tz);
631 timezones0.put("Europe/Bucharest", tz);
632 timezones0.put("Europe/Chisinau", tz);
633 timezones0.put("Europe/Helsinki", tz);
634 timezones0.put("Europe/Istanbul", tz);
635 timezones0.put("Europe/Kiev", tz);
636 timezones0.put("Europe/Mariehamn", tz);
637 timezones0.put("Europe/Nicosia", tz);
638 timezones0.put("Europe/Riga", tz);
639 timezones0.put("Europe/Simferopol", tz);
640 timezones0.put("Europe/Sofia", tz);
641 timezones0.put("Europe/Tallinn", tz);
642 timezones0.put("Europe/Uzhgorod", tz);
643 timezones0.put("Europe/Vilnius", tz);
644 timezones0.put("Europe/Zaporozhye", tz);
645 tz = new SimpleTimeZone
646 (2000 * 3600, "Europe/Kaliningrad",
647 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
648 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
649 timezones0.put("Europe/Kaliningrad", tz);
650 timezones0.put("Europe/Minsk", tz);
651 tz = new SimpleTimeZone
652 (3000 * 3600, "Asia/Baghdad",
653 Calendar.APRIL, 1, 0, 3000 * 3600,
654 Calendar.OCTOBER, 1, 0, 4000 * 3600);
655 timezones0.put("Asia/Baghdad", tz);
656 tz = new SimpleTimeZone
657 (3000 * 3600, "Europe/Moscow",
658 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
659 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
660 timezones0.put("Europe/Moscow", tz);
661 timezones0.put("Europe/Volgograd", tz);
662 tz = new SimpleTimeZone(3000 * 3600, "EAT");
663 timezones0.put("EAT", tz);
664 timezones0.put("Africa/Addis_Ababa", tz);
665 timezones0.put("Africa/Asmara", tz);
666 timezones0.put("Africa/Dar_es_Salaam", tz);
667 timezones0.put("Africa/Djibouti", tz);
668 timezones0.put("Africa/Kampala", tz);
669 timezones0.put("Africa/Khartoum", tz);
670 timezones0.put("Africa/Mogadishu", tz);
671 timezones0.put("Africa/Nairobi", tz);
672 timezones0.put("Antarctica/Syowa", tz);
673 timezones0.put("Asia/Aden", tz);
674 timezones0.put("Asia/Bahrain", tz);
675 timezones0.put("Asia/Kuwait", tz);
676 timezones0.put("Asia/Qatar", tz);
677 timezones0.put("Asia/Riyadh", tz);
678 timezones0.put("Indian/Antananarivo", tz);
679 timezones0.put("Indian/Comoro", tz);
680 timezones0.put("Indian/Mayotte", tz);
681 tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran");
682 timezones0.put("Asia/Tehran", tz);
683 tz = new SimpleTimeZone
684 (4000 * 3600, "Asia/Baku",
685 Calendar.MARCH, -1, Calendar.SUNDAY, 4000 * 3600,
686 Calendar.OCTOBER, -1, Calendar.SUNDAY, 5000 * 3600);
687 timezones0.put("Asia/Baku", tz);
688 tz = new SimpleTimeZone
689 (4000 * 3600, "Asia/Yerevan",
690 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
691 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
692 timezones0.put("Asia/Yerevan", tz);
693 timezones0.put("Europe/Samara", tz);
694 tz = new SimpleTimeZone(4000 * 3600, "NET");
695 timezones0.put("NET", tz);
696 timezones0.put("Asia/Dubai", tz);
697 timezones0.put("Asia/Muscat", tz);
698 timezones0.put("Asia/Tbilisi", tz);
699 timezones0.put("Indian/Mahe", tz);
700 timezones0.put("Indian/Mauritius", tz);
701 timezones0.put("Indian/Reunion", tz);
702 tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul");
703 timezones0.put("Asia/Kabul", tz);
704 tz = new SimpleTimeZone
705 (5000 * 3600, "Asia/Yekaterinburg",
706 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
707 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
708 timezones0.put("Asia/Yekaterinburg", tz);
709 tz = new SimpleTimeZone(5000 * 3600, "PLT");
710 timezones0.put("PLT", tz);
711 timezones0.put("Asia/Aqtau", tz);
712 timezones0.put("Asia/Aqtobe", tz);
713 timezones0.put("Asia/Ashgabat", tz);
714 timezones0.put("Asia/Dushanbe", tz);
715 timezones0.put("Asia/Karachi", tz);
716 timezones0.put("Asia/Oral", tz);
717 timezones0.put("Asia/Samarkand", tz);
718 timezones0.put("Asia/Tashkent", tz);
719 timezones0.put("Indian/Kerguelen", tz);
720 timezones0.put("Indian/Maldives", tz);
721 tz = new SimpleTimeZone(5500 * 3600, "BST");
722 timezones0.put("BST", tz);
723 timezones0.put("IST", tz);
724 timezones0.put("Asia/Calcutta", tz);
725 timezones0.put("Asia/Colombo", tz);
726 tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu");
727 timezones0.put("Asia/Katmandu", tz);
728 tz = new SimpleTimeZone(6000 * 3600, "Antarctica/Mawson");
729 timezones0.put("Antarctica/Mawson", tz);
730 timezones0.put("Antarctica/Vostok", tz);
731 timezones0.put("Asia/Almaty", tz);
732 timezones0.put("Asia/Bishkek", tz);
733 timezones0.put("Asia/Dhaka", tz);
734 timezones0.put("Asia/Qyzylorda", tz);
735 timezones0.put("Asia/Thimphu", tz);
736 timezones0.put("Indian/Chagos", tz);
737 tz = new SimpleTimeZone
738 (6000 * 3600, "Asia/Novosibirsk",
739 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
740 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
741 timezones0.put("Asia/Novosibirsk", tz);
742 timezones0.put("Asia/Omsk", tz);
743 tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon");
744 timezones0.put("Asia/Rangoon", tz);
745 timezones0.put("Indian/Cocos", tz);
746 tz = new SimpleTimeZone(7000 * 3600, "VST");
747 timezones0.put("VST", tz);
748 timezones0.put("Antarctica/Davis", tz);
749 timezones0.put("Asia/Bangkok", tz);
750 timezones0.put("Asia/Jakarta", tz);
751 timezones0.put("Asia/Phnom_Penh", tz);
752 timezones0.put("Asia/Pontianak", tz);
753 timezones0.put("Asia/Saigon", tz);
754 timezones0.put("Asia/Vientiane", tz);
755 timezones0.put("Indian/Christmas", tz);
756 tz = new SimpleTimeZone
757 (7000 * 3600, "Asia/Hovd",
758 Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600,
759 Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600);
760 timezones0.put("Asia/Hovd", tz);
761 tz = new SimpleTimeZone
762 (7000 * 3600, "Asia/Krasnoyarsk",
763 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
764 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
765 timezones0.put("Asia/Krasnoyarsk", tz);
766 tz = new SimpleTimeZone(8000 * 3600, "CTT");
767 timezones0.put("CTT", tz);
768 timezones0.put("Antarctica/Casey", tz);
769 timezones0.put("Asia/Brunei", tz);
770 timezones0.put("Asia/Chongqing", tz);
771 timezones0.put("Asia/Harbin", tz);
772 timezones0.put("Asia/Hong_Kong", tz);
773 timezones0.put("Asia/Kashgar", tz);
774 timezones0.put("Asia/Kuala_Lumpur", tz);
775 timezones0.put("Asia/Kuching", tz);
776 timezones0.put("Asia/Macau", tz);
777 timezones0.put("Asia/Makassar", tz);
778 timezones0.put("Asia/Manila", tz);
779 timezones0.put("Asia/Shanghai", tz);
780 timezones0.put("Asia/Singapore", tz);
781 timezones0.put("Asia/Taipei", tz);
782 timezones0.put("Asia/Urumqi", tz);
783 timezones0.put("Australia/Perth", tz);
784 tz = new SimpleTimeZone
785 (8000 * 3600, "Asia/Irkutsk",
786 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
787 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
788 timezones0.put("Asia/Irkutsk", tz);
789 tz = new SimpleTimeZone
790 (8000 * 3600, "Asia/Ulaanbaatar",
791 Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600,
792 Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600);
793 timezones0.put("Asia/Ulaanbaatar", tz);
794 tz = new SimpleTimeZone(8750 * 3600, "Australia/Eucla");
795 timezones0.put("Australia/Eucla", tz);
796 tz = new SimpleTimeZone
797 (9000 * 3600, "Asia/Choibalsan",
798 Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600,
799 Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600);
800 timezones0.put("Asia/Choibalsan", tz);
801 tz = new SimpleTimeZone(9000 * 3600, "JST");
802 timezones0.put("JST", tz);
803 timezones0.put("Asia/Dili", tz);
804 timezones0.put("Asia/Jayapura", tz);
805 timezones0.put("Asia/Pyongyang", tz);
806 timezones0.put("Asia/Seoul", tz);
807 timezones0.put("Asia/Tokyo", tz);
808 timezones0.put("Pacific/Palau", tz);
809 tz = new SimpleTimeZone
810 (9000 * 3600, "Asia/Yakutsk",
811 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
812 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
813 timezones0.put("Asia/Yakutsk", tz);
814 tz = new SimpleTimeZone
815 (9500 * 3600, "Australia/Adelaide",
816 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
817 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600);
818 timezones0.put("Australia/Adelaide", tz);
819 timezones0.put("Australia/Broken_Hill", tz);
820 tz = new SimpleTimeZone(9500 * 3600, "ACT");
821 timezones0.put("ACT", tz);
822 timezones0.put("Australia/Darwin", tz);
823 tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville");
824 timezones0.put("Antarctica/DumontDUrville", tz);
825 timezones0.put("Australia/Brisbane", tz);
826 timezones0.put("Australia/Lindeman", tz);
827 timezones0.put("Pacific/Guam", tz);
828 timezones0.put("Pacific/Port_Moresby", tz);
829 timezones0.put("Pacific/Saipan", tz);
830 timezones0.put("Pacific/Truk", tz);
831 tz = new SimpleTimeZone
832 (10000 * 3600, "Asia/Sakhalin",
833 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
834 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
835 timezones0.put("Asia/Sakhalin", tz);
836 timezones0.put("Asia/Vladivostok", tz);
837 tz = new SimpleTimeZone
838 (10000 * 3600, "Australia/Currie",
839 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
840 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600);
841 timezones0.put("Australia/Currie", tz);
842 timezones0.put("Australia/Hobart", tz);
843 tz = new SimpleTimeZone
844 (10000 * 3600, "AET",
845 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
846 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600);
847 timezones0.put("AET", tz);
848 timezones0.put("Australia/Melbourne", tz);
849 timezones0.put("Australia/Sydney", tz);
850 tz = new SimpleTimeZone
851 (10500 * 3600, "Australia/Lord_Howe",
852 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600,
853 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600);
854 timezones0.put("Australia/Lord_Howe", tz);
855 tz = new SimpleTimeZone
856 (11000 * 3600, "Asia/Magadan",
857 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
858 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
859 timezones0.put("Asia/Magadan", tz);
860 tz = new SimpleTimeZone(11000 * 3600, "SST");
861 timezones0.put("SST", tz);
862 timezones0.put("Pacific/Efate", tz);
863 timezones0.put("Pacific/Guadalcanal", tz);
864 timezones0.put("Pacific/Kosrae", tz);
865 timezones0.put("Pacific/Noumea", tz);
866 timezones0.put("Pacific/Ponape", tz);
867 tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk");
868 timezones0.put("Pacific/Norfolk", tz);
869 tz = new SimpleTimeZone
870 (12000 * 3600, "NST",
871 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600,
872 Calendar.MARCH, 3, Calendar.SUNDAY, 3000 * 3600);
873 timezones0.put("NST", tz);
874 timezones0.put("Antarctica/McMurdo", tz);
875 timezones0.put("Antarctica/South_Pole", tz);
876 timezones0.put("Pacific/Auckland", tz);
877 tz = new SimpleTimeZone
878 (12000 * 3600, "Asia/Anadyr",
879 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600,
880 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600);
881 timezones0.put("Asia/Anadyr", tz);
882 timezones0.put("Asia/Kamchatka", tz);
883 tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji");
884 timezones0.put("Pacific/Fiji", tz);
885 timezones0.put("Pacific/Funafuti", tz);
886 timezones0.put("Pacific/Kwajalein", tz);
887 timezones0.put("Pacific/Majuro", tz);
888 timezones0.put("Pacific/Nauru", tz);
889 timezones0.put("Pacific/Tarawa", tz);
890 timezones0.put("Pacific/Wake", tz);
891 timezones0.put("Pacific/Wallis", tz);
892 tz = new SimpleTimeZone
893 (12750 * 3600, "Pacific/Chatham",
894 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600,
895 Calendar.MARCH, 3, Calendar.SUNDAY, 3750 * 3600);
896 timezones0.put("Pacific/Chatham", tz);
897 tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury");
898 timezones0.put("Pacific/Enderbury", tz);
899 timezones0.put("Pacific/Tongatapu", tz);
900 tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati");
901 timezones0.put("Pacific/Kiritimati", tz);
907 * Maps a time zone name (with optional GMT offset and daylight time
908 * zone name) to one of the known time zones. This method called
909 * with the result of <code>System.getProperty("user.timezone")</code>
910 * or <code>getDefaultTimeZoneId()</code>. Note that giving one of
911 * the standard tz data names from ftp://elsie.nci.nih.gov/pub/ is
913 * The time zone name can be given as follows:
914 * <code>(standard zone name)[(GMT offset)[(DST zone name)[DST offset]]]
917 * If only a (standard zone name) is given (no numbers in the
918 * String) then it gets mapped directly to the TimeZone with that
919 * name, if that fails null is returned.
921 * Alternately, a POSIX-style TZ string can be given, defining the time zone:
922 * <code>std offset dst offset,date/time,date/time</code>
923 * See the glibc manual, or the man page for <code>tzset</code> for details
926 * A GMT offset is the offset to add to the local time to get GMT.
927 * If a (GMT offset) is included (either in seconds or hours) then
928 * an attempt is made to find a TimeZone name matching both the name
929 * and the offset (that doesn't observe daylight time, if the
930 * timezone observes daylight time then you must include a daylight
931 * time zone name after the offset), if that fails then a TimeZone
932 * with the given GMT offset is returned (whether or not the
933 * TimeZone observes daylight time is ignored), if that also fails
934 * the GMT TimeZone is returned.
936 * If the String ends with (GMT offset)(daylight time zone name)
937 * then an attempt is made to find a TimeZone with the given name and
938 * GMT offset that also observes (the daylight time zone name is not
939 * currently used in any other way), if that fails a TimeZone with
940 * the given GMT offset that observes daylight time is returned, if
941 * that also fails the GMT TimeZone is returned.
943 * Examples: In Chicago, the time zone id could be "CST6CDT", but
944 * the preferred name would be "America/Chicago". In Indianapolis
945 * (which does not have Daylight Savings Time) the string could be
946 * "EST5", but the preferred name would be "America/Indianapolis".
947 * The standard time zone name for The Netherlands is "Europe/Amsterdam",
948 * but can also be given as "CET-1CEST".
950 static TimeZone getDefaultTimeZone(String sysTimeZoneId)
952 String stdName = null;
957 int idLength = sysTimeZoneId.length();
965 c = sysTimeZoneId.charAt(index);
966 while (c != '+' && c != '-' && c != ',' && c != ':'
967 && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
969 if (index >= idLength)
970 return getTimeZoneInternal(sysTimeZoneId);
972 stdName = sysTimeZoneId.substring(0, index);
975 // get the std offset
977 c = sysTimeZoneId.charAt(index++);
978 while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
979 && index < idLength);
980 if (index < idLength)
983 { // convert the dst string to a millis number
984 String offset = sysTimeZoneId.substring(prevIndex, index);
987 if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
988 stdOffs = parseTime(offset.substring(1));
990 stdOffs = parseTime(offset);
992 if (offset.charAt(0) == '-')
995 // TZ timezone offsets are positive when WEST of the meridian.
999 // Done yet? (Format: std offset)
1000 if (index >= idLength)
1002 // Do we have an existing timezone with that name and offset?
1003 TimeZone tz = getTimeZoneInternal(stdName);
1005 if (tz.getRawOffset() == stdOffs)
1009 return new SimpleTimeZone(stdOffs, stdName);
1014 c = sysTimeZoneId.charAt(index);
1015 while (c != '+' && c != '-' && c != ',' && c != ':'
1016 && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
1018 // Done yet? (Format: std offset dst)
1019 if (index >= idLength)
1021 // Do we have an existing timezone with that name and offset
1023 TimeZone tz = getTimeZoneInternal(stdName);
1025 if (tz.getRawOffset() == stdOffs && tz.useDaylightTime())
1029 return new SimpleTimeZone(stdOffs, stdName);
1032 // get the dst offset
1035 c = sysTimeZoneId.charAt(index++);
1036 while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
1037 && index < idLength);
1038 if (index < idLength)
1041 if (index == prevIndex && (c == ',' || c == ';'))
1043 // Missing dst offset defaults to one hour ahead of standard
1045 dstOffs = stdOffs + 60 * 60 * 1000;
1048 { // convert the dst string to a millis number
1049 String offset = sysTimeZoneId.substring(prevIndex, index);
1052 if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
1053 dstOffs = parseTime(offset.substring(1));
1055 dstOffs = parseTime(offset);
1057 if (offset.charAt(0) == '-')
1060 // TZ timezone offsets are positive when WEST of the meridian.
1064 // Done yet? (Format: std offset dst offset)
1065 // FIXME: We don't support DST without a rule given. Should we?
1066 if (index >= idLength)
1068 // Time Zone existing with same name, dst and offsets?
1069 TimeZone tz = getTimeZoneInternal(stdName);
1071 if (tz.getRawOffset() == stdOffs && tz.useDaylightTime()
1072 && tz.getDSTSavings() == (dstOffs - stdOffs))
1075 return new SimpleTimeZone(stdOffs, stdName);
1079 if (sysTimeZoneId.charAt(index) == ','
1080 || sysTimeZoneId.charAt(index) == ';')
1084 while (sysTimeZoneId.charAt(index) != ','
1085 && sysTimeZoneId.charAt(index) != ';')
1087 String startTime = sysTimeZoneId.substring(offs, index);
1089 String endTime = sysTimeZoneId.substring(index);
1091 index = startTime.indexOf('/');
1098 startDate = startTime.substring(0, index);
1099 startMillis = parseTime(startTime.substring(index + 1));
1103 startDate = startTime;
1104 // if time isn't given, default to 2:00:00 AM.
1105 startMillis = 2 * 60 * 60 * 1000;
1107 index = endTime.indexOf('/');
1110 endDate = endTime.substring(0, index);
1111 endMillis = parseTime(endTime.substring(index + 1));
1116 // if time isn't given, default to 2:00:00 AM.
1117 endMillis = 2 * 60 * 60 * 1000;
1120 int[] start = getDateParams(startDate);
1121 int[] end = getDateParams(endDate);
1122 return new SimpleTimeZone(stdOffs, stdName, start[0], start[1],
1123 start[2], startMillis, end[0], end[1],
1124 end[2], endMillis, (dstOffs - stdOffs));
1128 // FIXME: Produce a warning here?
1129 catch (/*IndexOutOfBounds*/Exception _)
1132 /*catch (NumberFormatException _)
1140 * Parses and returns the params for a POSIX TZ date field,
1141 * in the format int[]{ month, day, dayOfWeek }, following the
1142 * SimpleTimeZone constructor rules.
1144 private static int[] getDateParams(String date)
1146 int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
1149 if (date.charAt(0) == 'M' || date.charAt(0) == 'm')
1153 // Month, week of month, day of week
1154 month = Integer.parseInt(date.substring(1, date.indexOf('.')));
1155 int week = Integer.parseInt(date.substring(date.indexOf('.') + 1,
1156 date.lastIndexOf('.')));
1157 int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.')
1160 day = -1; // last day of month is -1 in java, 5 in TZ
1162 // first day of week starting on or after.
1163 day = (week - 1) * 7 + 1;
1165 dayOfWeek++; // Java day of week is one-based, Sunday is first day.
1166 month--; // Java month is zero-based.
1167 return new int[] { month, day, dayOfWeek };
1170 // julian day, either zero-based 0<=n<=365 (incl feb 29)
1171 // or one-based 1<=n<=365 (no feb 29)
1172 int julianDay; // Julian day,
1174 if (date.charAt(0) != 'J' || date.charAt(0) != 'j')
1176 julianDay = Integer.parseInt(date.substring(1));
1177 julianDay++; // make 1-based
1178 // Adjust day count to include feb 29.
1179 dayCount = new int[]
1181 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
1185 // 1-based julian day
1186 julianDay = Integer.parseInt(date);
1190 if (dayCount[i] < julianDay)
1194 julianDay -= dayCount[i];
1196 return new int[] { month, julianDay, 0 };
1200 * Parses a time field hh[:mm[:ss]], returning the result
1201 * in milliseconds. No leading sign.
1203 private static int parseTime(String time)
1208 while (i < time.length())
1209 if (time.charAt(i) == ':')
1213 millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i));
1214 if (i >= time.length())
1218 while (i < time.length())
1219 if (time.charAt(i) == ':')
1223 millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i));
1224 if (i >= time.length())
1227 millis += 1000 * Integer.parseInt(time.substring(++i));
1232 * Gets the time zone offset, for current date, modified in case of
1233 * daylight savings. This is the offset to add to UTC to get the local
1235 * @param era the era of the given date
1236 * @param year the year of the given date
1237 * @param month the month of the given date, 0 for January.
1238 * @param day the day of month
1239 * @param dayOfWeek the day of week
1240 * @param milliseconds the millis in the day (in local standard time)
1241 * @return the time zone offset in milliseconds.
1243 public abstract int getOffset(int era, int year, int month,
1244 int day, int dayOfWeek, int milliseconds);
1247 * Get the time zone offset for the specified date, modified in case of
1248 * daylight savings. This is the offset to add to UTC to get the local
1250 * @param date the date represented in millisecends
1251 * since January 1, 1970 00:00:00 GMT.
1254 public int getOffset(long date)
1256 return (inDaylightTime(new Date(date))
1257 ? getRawOffset() + getDSTSavings()
1262 * Gets the time zone offset, ignoring daylight savings. This is
1263 * the offset to add to UTC to get the local time.
1264 * @return the time zone offset in milliseconds.
1266 public abstract int getRawOffset();
1269 * Sets the time zone offset, ignoring daylight savings. This is
1270 * the offset to add to UTC to get the local time.
1271 * @param offsetMillis the time zone offset to GMT.
1273 public abstract void setRawOffset(int offsetMillis);
1276 * Gets the identifier of this time zone. For instance, PST for
1277 * Pacific Standard Time.
1278 * @returns the ID of this time zone.
1280 public String getID()
1286 * Sets the identifier of this time zone. For instance, PST for
1287 * Pacific Standard Time.
1288 * @param id the new time zone ID.
1289 * @throws NullPointerException if <code>id</code> is <code>null</code>
1291 public void setID(String id)
1294 throw new Exception/*NullPointerException*/("NullPointerException");
1300 * This method returns a string name of the time zone suitable
1301 * for displaying to the user. The string returned will be the long
1302 * description of the timezone in the current locale. The name
1303 * displayed will assume daylight savings time is not in effect.
1305 * @return The name of the time zone.
1307 public final String getDisplayName()
1309 return (getDisplayName(false, LONG, Locale.getDefault()));
1313 * This method returns a string name of the time zone suitable
1314 * for displaying to the user. The string returned will be the long
1315 * description of the timezone in the specified locale. The name
1316 * displayed will assume daylight savings time is not in effect.
1318 * @param locale The locale for this timezone name.
1320 * @return The name of the time zone.
1322 public final String getDisplayName(Locale locale)
1324 return (getDisplayName(false, LONG, locale));
1328 * This method returns a string name of the time zone suitable
1329 * for displaying to the user. The string returned will be of the
1330 * specified type in the current locale.
1332 * @param dst Whether or not daylight savings time is in effect.
1333 * @param style <code>LONG</code> for a long name, <code>SHORT</code> for
1334 * a short abbreviation.
1336 * @return The name of the time zone.
1338 public final String getDisplayName(boolean dst, int style)
1340 return (getDisplayName(dst, style, Locale.getDefault()));
1345 * This method returns a string name of the time zone suitable
1346 * for displaying to the user. The string returned will be of the
1347 * specified type in the specified locale.
1349 * @param dst Whether or not daylight savings time is in effect.
1350 * @param style <code>LONG</code> for a long name, <code>SHORT</code> for
1351 * a short abbreviation.
1352 * @param locale The locale for this timezone name.
1354 * @return The name of the time zone.
1356 /*public String getDisplayName(boolean dst, int style, Locale locale)
1358 DateFormatSymbols dfs;
1361 dfs = new DateFormatSymbols(locale);
1363 // The format of the value returned is defined by us.
1364 String[][]zoneinfo = dfs.getZoneStrings();
1365 for (int i = 0; i < zoneinfo.length; i++)
1367 if (zoneinfo[i][0].equals(getID()))
1372 return (zoneinfo[i][2]);
1374 return (zoneinfo[i][1]);
1379 return (zoneinfo[i][4]);
1381 return (zoneinfo[i][3]);
1386 catch (MissingResourceException e)
1390 return getDefaultDisplayName(dst);
1393 /*private String getDefaultDisplayName(boolean dst)
1395 int offset = getRawOffset();
1396 if (dst && this instanceof SimpleTimeZone)
1398 // ugly, but this is a design failure of the API:
1399 // getDisplayName takes a dst parameter even though
1400 // TimeZone knows nothing about daylight saving offsets.
1401 offset += ((SimpleTimeZone) this).getDSTSavings();
1404 CPStringBuilder sb = new CPStringBuilder(9);
1407 offset = offset / (1000 * 60);
1408 int hours = Math.abs(offset) / 60;
1409 int minutes = Math.abs(offset) % 60;
1411 if (minutes != 0 || hours != 0)
1413 sb.append(offset >= 0 ? '+' : '-');
1414 sb.append((char) ('0' + hours / 10));
1415 sb.append((char) ('0' + hours % 10));
1417 sb.append((char) ('0' + minutes / 10));
1418 sb.append((char) ('0' + minutes % 10));
1421 return sb.toString();
1425 * Returns true, if this time zone uses Daylight Savings Time.
1427 public abstract boolean useDaylightTime();
1430 * Returns true, if the given date is in Daylight Savings Time in this
1432 * @param date the given Date.
1434 public abstract boolean inDaylightTime(Date date);
1437 * Gets the daylight savings offset. This is a positive offset in
1438 * milliseconds with respect to standard time. Typically this
1439 * is one hour, but for some time zones this may be half an our.
1440 * <p>The default implementation returns 3600000 milliseconds
1441 * (one hour) if the time zone uses daylight savings time
1442 * (as specified by {@link #useDaylightTime()}), otherwise
1444 * @return the daylight savings offset in milliseconds.
1447 public int getDSTSavings ()
1449 return useDaylightTime () ? 3600000 : 0;
1453 * Gets the TimeZone for the given ID.
1454 * @param ID the time zone identifier.
1455 * @return The time zone for the identifier or GMT, if no such time
1458 private static TimeZone getTimeZoneInternal(String ID)
1460 // First check timezones hash
1462 TimeZone tznew = null;
1463 for (int pass = 0; pass < 2; pass++)
1465 synchronized (TimeZone.class)
1467 tz = (TimeZone) timezones().get(ID);
1470 if (!tz.getID().equals(ID))
1472 // We always return a timezone with the requested ID.
1473 // This is the same behaviour as with JDK1.2.
1474 tz = (TimeZone) tz.clone();
1476 // We also save the alias, so that we return the same
1477 // object again if getTimeZone is called with the same
1479 timezones().put(ID, tz);
1483 else if (tznew != null)
1485 timezones().put(ID, tznew);
1490 if (pass == 1 || zoneinfo_dir == null)
1493 // aliases0 is never changing after first timezones(), so should
1494 // be safe without synchronization.
1495 String zonename = (String) aliases0.get(ID);
1496 if (zonename == null)
1499 // Read the file outside of the critical section, it is expensive.
1500 tznew = ZoneInfo.readTZFile (ID, zoneinfo_dir
1501 + File.separatorChar + zonename);
1510 * Gets the TimeZone for the given ID.
1511 * @param ID the time zone identifier.
1512 * @return The time zone for the identifier or GMT, if no such time
1515 public static TimeZone getTimeZone(String ID)
1517 // Check for custom IDs first
1518 if (ID.startsWith("GMT") && ID.length() > 3)
1521 int offset_direction = 1;
1523 if (ID.charAt(pos) == '-')
1525 offset_direction = -1;
1528 else if (ID.charAt(pos) == '+')
1537 String offset_str = ID.substring(pos);
1538 int idx = offset_str.indexOf(":");
1541 hour = Integer.parseInt(offset_str.substring(0, idx));
1542 minute = Integer.parseInt(offset_str.substring(idx + 1));
1546 int offset_length = offset_str.length();
1547 if (offset_length <= 2)
1550 hour = Integer.parseInt(offset_str);
1555 // hour and minute, not separated by colon
1556 hour = Integer.parseInt
1557 (offset_str.substring(0, offset_length - 2));
1558 minute = Integer.parseInt
1559 (offset_str.substring(offset_length - 2));
1563 // Custom IDs have to be normalized
1564 /*CPStringBuilder sb = new CPStringBuilder(9);
1567 sb.append(offset_direction >= 0 ? '+' : '-');
1568 sb.append((char) ('0' + hour / 10));
1569 sb.append((char) ('0' + hour % 10));
1571 sb.append((char) ('0' + minute / 10));
1572 sb.append((char) ('0' + minute % 10));*/
1573 ID = "GMT" + (offset_direction >= 0 ? "+" : "-") + (char) ('0' + hour / 10)
1574 + (char) ('0' + hour % 10) + ":" + (char) ('0' + minute / 10) + (char) ('0' + minute % 10);//sb.toString();
1576 return new SimpleTimeZone((hour * (60 * 60 * 1000)
1577 + minute * (60 * 1000))
1578 * offset_direction, ID);
1580 catch (/*NumberFormat*/Exception e)
1585 TimeZone tz = getTimeZoneInternal(ID);
1589 return new SimpleTimeZone(0, "GMT");
1593 * Gets the available IDs according to the given time zone
1595 * @param rawOffset the given time zone GMT offset.
1596 * @return An array of IDs, where the time zone has the specified GMT
1597 * offset. For example <code>{"Phoenix", "Denver"}</code>, since both have
1598 * GMT-07:00, but differ in daylight savings behaviour.
1600 public static String[] getAvailableIDs(int rawOffset)
1602 synchronized (TimeZone.class)
1604 HashMap h = timezones();
1606 if (zoneinfo_dir == null)
1608 Iterator iter = h.entrySet().iterator();
1609 while (iter.hasNext())
1611 // Don't iterate the values, since we want to count
1612 // doubled values (aliases)
1613 Map.Entry entry = (Map.Entry) iter.next();
1614 if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1618 String[] ids = new String[count];
1620 iter = h.entrySet().iterator();
1621 while (iter.hasNext())
1623 Map.Entry entry = (Map.Entry) iter.next();
1624 if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1625 ids[count++] = (String) entry.getKey();
1631 String[] s = getAvailableIDs();
1633 for (int i = 0; i < s.length; i++)
1635 TimeZone t = getTimeZoneInternal(s[i]);
1636 if (t == null || t.getRawOffset() != rawOffset)
1641 String[] ids = new String[count];
1643 for (int i = 0; i < s.length; i++)
1645 ids[count++] = s[i];
1650 private static int getAvailableIDs(File d, String prefix, ArrayList list)
1652 String[] files = d.list();
1653 int count = files.length;
1654 boolean top = prefix.length() == 0;
1656 for (int i = 0; i < files.length; i++)
1659 && (files[i].equals("posix")
1660 || files[i].equals("right")
1661 || files[i].endsWith(".tab")
1662 || aliases0.get(files[i]) != null))
1669 File f = new File(d, files[i]);
1670 if (f.isDirectory())
1672 count += getAvailableIDs(f, prefix + files[i]
1673 + File.separatorChar, list) - 1;
1677 files[i] = prefix + files[i];
1683 * Gets all available IDs.
1684 * @return An array of all supported IDs.
1686 /*public static String[] getAvailableIDs()
1688 synchronized (TimeZone.class)
1690 HashMap h = timezones();
1691 if (zoneinfo_dir == null)
1692 return (String[]) h.keySet().toArray(new String[h.size()]);
1694 if (availableIDs != null)
1696 String[] ids = new String[availableIDs.length];
1697 for (int i = 0; i < availableIDs.length; i++)
1698 ids[i] = availableIDs[i];
1702 File d = new File(zoneinfo_dir);
1703 ArrayList list = new ArrayList(30);
1704 int count = getAvailableIDs(d, "", list) + aliases0.size();
1705 availableIDs = new String[count];
1706 String[] ids = new String[count];
1709 for (int i = 0; i < list.size(); i++)
1711 String[] s = (String[]) list.get(i);
1712 for (int j = 0; j < s.length; j++)
1715 availableIDs[count] = s[j];
1716 ids[count++] = s[j];
1720 Iterator iter = aliases0.entrySet().iterator();
1721 while (iter.hasNext())
1723 Map.Entry entry = (Map.Entry) iter.next();
1724 availableIDs[count] = (String) entry.getKey();
1725 ids[count++] = (String) entry.getKey();
1733 * Returns the time zone under which the host is running. This
1734 * can be changed with setDefault.
1736 * @return A clone of the current default time zone for this host.
1739 public static TimeZone getDefault()
1741 return (TimeZone) defaultZone().clone();
1744 public static void setDefault(TimeZone zone)
1746 // Hmmmm. No Security checks?
1747 defaultZone0 = zone;
1751 * Test if the other time zone uses the same rule and only
1752 * possibly differs in ID. This implementation for this particular
1753 * class will return true if the raw offsets are identical. Subclasses
1754 * should override this method if they use daylight savings.
1755 * @return true if this zone has the same raw offset
1757 public boolean hasSameRules(TimeZone other)
1759 return other.getRawOffset() == getRawOffset();
1763 * Returns a clone of this object. I can't imagine, why this is
1764 * useful for a time zone.
1766 public Object clone()
1770 return super.clone();
1772 catch (/*CloneNotSupported*/Exception ex)