Import GNU Classpath (20121202).
[official-gcc.git] / libjava / classpath / java / util / TimeZone.java
bloba8b2b51cf8c2a1c98590f79834339dba6e0b3d79
1 /* java.util.TimeZone
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2012
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)
10 any later version.
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
20 02110-1301 USA.
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
25 combination.
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. */
40 package java.util;
42 import gnu.classpath.SystemProperties;
43 import gnu.java.lang.CPStringBuilder;
44 import gnu.java.util.ZoneInfo;
46 import java.io.File;
47 import java.security.AccessController;
48 import java.security.PrivilegedAction;
49 import java.text.DateFormatSymbols;
51 /**
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.
64 * @see Calendar
65 * @see SimpleTimeZone
66 * @author Jochen Hoenicke
68 public abstract class TimeZone implements java.io.Serializable, Cloneable
71 /**
72 * Constant used to indicate that a short timezone abbreviation should
73 * be returned, such as "EST"
75 public static final int SHORT = 0;
77 /**
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;
83 /**
84 * The time zone identifier, e.g. PST.
86 private String ID;
88 /**
89 * The default time zone, as returned by getDefault.
91 private static TimeZone defaultZone0;
93 /**
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 = AccessController.doPrivileged
106 (new PrivilegedAction<TimeZone>()
108 public TimeZone run()
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.
118 if (zone == null)
119 zone = VMTimeZone.getDefaultTimeZoneId();
121 // Fall back on GMT.
122 if (zone == null)
123 zone = getTimeZone ("GMT");
125 return zone;
130 return defaultZone0;
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<String,String> aliases0;
152 * HashMap for timezones by ID.
154 private static HashMap<String,TimeZone> timezones0;
155 /* initialize this static field lazily to overhead if
156 * it is not needed:
158 // Package-private to avoid a trampoline.
159 static HashMap<String,TimeZone> timezones()
161 if (timezones0 == null)
163 HashMap<String,TimeZone> timezones = new HashMap<String,TimeZone>();
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<String,String>();
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");
205 return timezones;
208 TimeZone tz;
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
510 (0 * 3600, "WET",
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
542 (1000 * 3600, "CET",
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
583 (2000 * 3600, "ART",
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
624 (2000 * 3600, "EET",
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);
903 return timezones0;
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
912 * preferred.
913 * The time zone name can be given as follows:
914 * <code>(standard zone name)[(GMT offset)[(DST zone name)[DST offset]]]
915 * </code>
916 * <p>
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.
920 * <p>
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
924 * of this format.
925 * <p>
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.
935 * <p>
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.
942 * <p>
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;
953 int stdOffs;
954 int dstOffs;
957 int idLength = sysTimeZoneId.length();
959 int index = 0;
960 int prevIndex;
961 char c;
963 // get std
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);
973 prevIndex = 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)
981 index--;
983 { // convert the dst string to a millis number
984 String offset = sysTimeZoneId.substring(prevIndex, index);
985 prevIndex = index;
987 if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
988 stdOffs = parseTime(offset.substring(1));
989 else
990 stdOffs = parseTime(offset);
992 if (offset.charAt(0) == '-')
993 stdOffs = -stdOffs;
995 // TZ timezone offsets are positive when WEST of the meridian.
996 stdOffs = -stdOffs;
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);
1004 if (tz != null)
1005 if (tz.getRawOffset() == stdOffs)
1006 return tz;
1008 // Custom then.
1009 return new SimpleTimeZone(stdOffs, stdName);
1012 // get dst
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
1022 // which has DST?
1023 TimeZone tz = getTimeZoneInternal(stdName);
1024 if (tz != null)
1025 if (tz.getRawOffset() == stdOffs && tz.useDaylightTime())
1026 return tz;
1028 // Custom then.
1029 return new SimpleTimeZone(stdOffs, stdName);
1032 // get the dst offset
1033 prevIndex = index;
1035 c = sysTimeZoneId.charAt(index++);
1036 while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
1037 && index < idLength);
1038 if (index < idLength)
1039 index--;
1041 if (index == prevIndex && (c == ',' || c == ';'))
1043 // Missing dst offset defaults to one hour ahead of standard
1044 // time.
1045 dstOffs = stdOffs + 60 * 60 * 1000;
1047 else
1048 { // convert the dst string to a millis number
1049 String offset = sysTimeZoneId.substring(prevIndex, index);
1050 prevIndex = index;
1052 if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
1053 dstOffs = parseTime(offset.substring(1));
1054 else
1055 dstOffs = parseTime(offset);
1057 if (offset.charAt(0) == '-')
1058 dstOffs = -dstOffs;
1060 // TZ timezone offsets are positive when WEST of the meridian.
1061 dstOffs = -dstOffs;
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);
1070 if (tz != null)
1071 if (tz.getRawOffset() == stdOffs && tz.useDaylightTime()
1072 && tz.getDSTSavings() == (dstOffs - stdOffs))
1073 return tz;
1075 return new SimpleTimeZone(stdOffs, stdName);
1078 // get the DST rule
1079 if (sysTimeZoneId.charAt(index) == ','
1080 || sysTimeZoneId.charAt(index) == ';')
1082 index++;
1083 int offs = index;
1084 while (sysTimeZoneId.charAt(index) != ','
1085 && sysTimeZoneId.charAt(index) != ';')
1086 index++;
1087 String startTime = sysTimeZoneId.substring(offs, index);
1088 index++;
1089 String endTime = sysTimeZoneId.substring(index);
1091 index = startTime.indexOf('/');
1092 int startMillis;
1093 int endMillis;
1094 String startDate;
1095 String endDate;
1096 if (index != -1)
1098 startDate = startTime.substring(0, index);
1099 startMillis = parseTime(startTime.substring(index + 1));
1101 else
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('/');
1108 if (index != -1)
1110 endDate = endTime.substring(0, index);
1111 endMillis = parseTime(endTime.substring(index + 1));
1113 else
1115 endDate = endTime;
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 (IndexOutOfBoundsException _)
1132 catch (NumberFormatException _)
1136 return null;
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 };
1147 int month;
1149 if (date.charAt(0) == 'M' || date.charAt(0) == 'm')
1151 int day;
1153 // Month, week of month, day of week
1155 // "Mm.w.d". d is between 0 (Sunday) and 6. Week w is
1156 // between 1 and 5; Week 1 is the first week in which day d
1157 // occurs and Week 5 specifies the last d day in the month.
1158 // Month m is between 1 and 12.
1160 month = Integer.parseInt(date.substring(1, date.indexOf('.')));
1161 int week = Integer.parseInt(date.substring(date.indexOf('.') + 1,
1162 date.lastIndexOf('.')));
1163 int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.')
1164 + 1));
1165 dayOfWeek++; // Java day of week is one-based, Sunday is first day.
1167 if (week == 5)
1168 day = -1; // last day of month is -1 in java, 5 in TZ
1169 else
1171 // First day of week starting on or after. For example,
1172 // to specify the second Sunday of April, set month to
1173 // APRIL, day-of-month to 8, and day-of-week to -SUNDAY.
1174 day = (week - 1) * 7 + 1;
1175 dayOfWeek = -dayOfWeek;
1178 month--; // Java month is zero-based.
1179 return new int[] { month, day, dayOfWeek };
1182 // julian day, either zero-based 0<=n<=365 (incl feb 29)
1183 // or one-based 1<=n<=365 (no feb 29)
1184 int julianDay; // Julian day,
1186 if (date.charAt(0) != 'J' || date.charAt(0) != 'j')
1188 julianDay = Integer.parseInt(date.substring(1));
1189 julianDay++; // make 1-based
1190 // Adjust day count to include feb 29.
1191 dayCount = new int[]
1193 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
1196 else
1197 // 1-based julian day
1198 julianDay = Integer.parseInt(date);
1200 int i = 11;
1201 while (i > 0)
1202 if (dayCount[i] < julianDay)
1203 break;
1204 else
1205 i--;
1206 julianDay -= dayCount[i];
1207 month = i;
1208 return new int[] { month, julianDay, 0 };
1212 * Parses a time field hh[:mm[:ss]], returning the result
1213 * in milliseconds. No leading sign.
1215 private static int parseTime(String time)
1217 int millis = 0;
1218 int i = 0;
1220 while (i < time.length())
1221 if (time.charAt(i) == ':')
1222 break;
1223 else
1224 i++;
1225 millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i));
1226 if (i >= time.length())
1227 return millis;
1229 int iprev = ++i;
1230 while (i < time.length())
1231 if (time.charAt(i) == ':')
1232 break;
1233 else
1234 i++;
1235 millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i));
1236 if (i >= time.length())
1237 return millis;
1239 millis += 1000 * Integer.parseInt(time.substring(++i));
1240 return millis;
1244 * Gets the time zone offset, for current date, modified in case of
1245 * daylight savings. This is the offset to add to UTC to get the local
1246 * time.
1247 * @param era the era of the given date
1248 * @param year the year of the given date
1249 * @param month the month of the given date, 0 for January.
1250 * @param day the day of month
1251 * @param dayOfWeek the day of week
1252 * @param milliseconds the millis in the day (in local standard time)
1253 * @return the time zone offset in milliseconds.
1255 public abstract int getOffset(int era, int year, int month,
1256 int day, int dayOfWeek, int milliseconds);
1259 * Get the time zone offset for the specified date, modified in case of
1260 * daylight savings. This is the offset to add to UTC to get the local
1261 * time.
1262 * @param date the date represented in millisecends
1263 * since January 1, 1970 00:00:00 GMT.
1264 * @since 1.4
1266 public int getOffset(long date)
1268 return (inDaylightTime(new Date(date))
1269 ? getRawOffset() + getDSTSavings()
1270 : getRawOffset());
1274 * Gets the time zone offset, ignoring daylight savings. This is
1275 * the offset to add to UTC to get the local time.
1276 * @return the time zone offset in milliseconds.
1278 public abstract int getRawOffset();
1281 * Sets the time zone offset, ignoring daylight savings. This is
1282 * the offset to add to UTC to get the local time.
1283 * @param offsetMillis the time zone offset to GMT.
1285 public abstract void setRawOffset(int offsetMillis);
1288 * Gets the identifier of this time zone. For instance, PST for
1289 * Pacific Standard Time.
1290 * @returns the ID of this time zone.
1292 public String getID()
1294 return ID;
1298 * Sets the identifier of this time zone. For instance, PST for
1299 * Pacific Standard Time.
1300 * @param id the new time zone ID.
1301 * @throws NullPointerException if <code>id</code> is <code>null</code>
1303 public void setID(String id)
1305 if (id == null)
1306 throw new NullPointerException();
1308 this.ID = id;
1312 * This method returns a string name of the time zone suitable
1313 * for displaying to the user. The string returned will be the long
1314 * description of the timezone in the current locale. The name
1315 * displayed will assume daylight savings time is not in effect.
1317 * @return The name of the time zone.
1319 public final String getDisplayName()
1321 return (getDisplayName(false, LONG, Locale.getDefault()));
1325 * This method returns a string name of the time zone suitable
1326 * for displaying to the user. The string returned will be the long
1327 * description of the timezone in the specified locale. The name
1328 * displayed will assume daylight savings time is not in effect.
1330 * @param locale The locale for this timezone name.
1332 * @return The name of the time zone.
1334 public final String getDisplayName(Locale locale)
1336 return (getDisplayName(false, LONG, locale));
1340 * This method returns a string name of the time zone suitable
1341 * for displaying to the user. The string returned will be of the
1342 * specified type in the current locale.
1344 * @param dst Whether or not daylight savings time is in effect.
1345 * @param style <code>LONG</code> for a long name, <code>SHORT</code> for
1346 * a short abbreviation.
1348 * @return The name of the time zone.
1350 public final String getDisplayName(boolean dst, int style)
1352 return (getDisplayName(dst, style, Locale.getDefault()));
1357 * This method returns a string name of the time zone suitable
1358 * for displaying to the user. The string returned will be of the
1359 * specified type in the specified locale.
1361 * @param dst Whether or not daylight savings time is in effect.
1362 * @param style <code>LONG</code> for a long name, <code>SHORT</code> for
1363 * a short abbreviation.
1364 * @param locale The locale for this timezone name.
1366 * @return The name of the time zone.
1368 public String getDisplayName(boolean dst, int style, Locale locale)
1370 DateFormatSymbols dfs;
1373 dfs = new DateFormatSymbols(locale);
1375 // The format of the value returned is defined by us.
1376 String[][]zoneinfo = dfs.getZoneStrings();
1377 for (int i = 0; i < zoneinfo.length; i++)
1379 if (zoneinfo[i][0].equals(getID()))
1381 if (!dst)
1383 if (style == SHORT)
1384 return (zoneinfo[i][2]);
1385 else
1386 return (zoneinfo[i][1]);
1388 else
1390 if (style == SHORT)
1391 return (zoneinfo[i][4]);
1392 else
1393 return (zoneinfo[i][3]);
1398 catch (MissingResourceException e)
1402 return getDefaultDisplayName(dst);
1405 private String getDefaultDisplayName(boolean dst)
1407 int offset = getRawOffset() + (dst ? getDSTSavings() : 0);
1409 CPStringBuilder sb = new CPStringBuilder(9);
1410 sb.append("GMT");
1412 offset = offset / (1000 * 60);
1413 int hours = Math.abs(offset) / 60;
1414 int minutes = Math.abs(offset) % 60;
1416 if (minutes != 0 || hours != 0)
1418 sb.append(offset >= 0 ? '+' : '-');
1419 sb.append((char) ('0' + hours / 10));
1420 sb.append((char) ('0' + hours % 10));
1421 sb.append(':');
1422 sb.append((char) ('0' + minutes / 10));
1423 sb.append((char) ('0' + minutes % 10));
1426 return sb.toString();
1430 * Returns true, if this time zone uses Daylight Savings Time.
1432 public abstract boolean useDaylightTime();
1435 * Returns true, if the given date is in Daylight Savings Time in this
1436 * time zone.
1437 * @param date the given Date.
1439 public abstract boolean inDaylightTime(Date date);
1442 * Gets the daylight savings offset. This is a positive offset in
1443 * milliseconds with respect to standard time. Typically this
1444 * is one hour, but for some time zones this may be half an our.
1445 * <p>The default implementation returns 3600000 milliseconds
1446 * (one hour) if the time zone uses daylight savings time
1447 * (as specified by {@link #useDaylightTime()}), otherwise
1448 * it returns 0.
1449 * @return the daylight savings offset in milliseconds.
1450 * @since 1.4
1452 public int getDSTSavings ()
1454 return useDaylightTime () ? 3600000 : 0;
1458 * Gets the TimeZone for the given ID.
1459 * @param ID the time zone identifier.
1460 * @return The time zone for the identifier or GMT, if no such time
1461 * zone exists.
1463 private static TimeZone getTimeZoneInternal(String ID)
1465 // First check timezones hash
1466 TimeZone tz = null;
1467 TimeZone tznew = null;
1468 for (int pass = 0; pass < 2; pass++)
1470 synchronized (TimeZone.class)
1472 tz = timezones().get(ID);
1473 if (tz != null)
1475 if (!tz.getID().equals(ID))
1477 // We always return a timezone with the requested ID.
1478 // This is the same behaviour as with JDK1.2.
1479 tz = (TimeZone) tz.clone();
1480 tz.setID(ID);
1481 // We also save the alias, so that we return the same
1482 // object again if getTimeZone is called with the same
1483 // alias.
1484 timezones().put(ID, tz);
1486 return tz;
1488 else if (tznew != null)
1490 timezones().put(ID, tznew);
1491 return tznew;
1495 if (pass == 1 || zoneinfo_dir == null)
1496 return null;
1498 // aliases0 is never changing after first timezones(), so should
1499 // be safe without synchronization.
1500 String zonename = aliases0.get(ID);
1501 if (zonename == null)
1502 zonename = ID;
1504 // Read the file outside of the critical section, it is expensive.
1505 tznew = ZoneInfo.readTZFile (ID, zoneinfo_dir
1506 + File.separatorChar + zonename);
1507 if (tznew == null)
1508 return null;
1511 return null;
1515 * Gets the TimeZone for the given ID.
1516 * @param ID the time zone identifier.
1517 * @return The time zone for the identifier or GMT, if no such time
1518 * zone exists.
1520 public static TimeZone getTimeZone(String ID)
1522 // Check for custom IDs first
1523 if (ID.startsWith("GMT") && ID.length() > 3)
1525 int pos = 3;
1526 int offset_direction = 1;
1528 if (ID.charAt(pos) == '-')
1530 offset_direction = -1;
1531 pos++;
1533 else if (ID.charAt(pos) == '+')
1535 pos++;
1540 int hour, minute;
1542 String offset_str = ID.substring(pos);
1543 int idx = offset_str.indexOf(":");
1544 if (idx != -1)
1546 hour = Integer.parseInt(offset_str.substring(0, idx));
1547 minute = Integer.parseInt(offset_str.substring(idx + 1));
1549 else
1551 int offset_length = offset_str.length();
1552 if (offset_length <= 2)
1554 // Only hour
1555 hour = Integer.parseInt(offset_str);
1556 minute = 0;
1558 else
1560 // hour and minute, not separated by colon
1561 hour = Integer.parseInt
1562 (offset_str.substring(0, offset_length - 2));
1563 minute = Integer.parseInt
1564 (offset_str.substring(offset_length - 2));
1568 // Custom IDs have to be normalized
1569 CPStringBuilder sb = new CPStringBuilder(9);
1570 sb.append("GMT");
1572 sb.append(offset_direction >= 0 ? '+' : '-');
1573 sb.append((char) ('0' + hour / 10));
1574 sb.append((char) ('0' + hour % 10));
1575 sb.append(':');
1576 sb.append((char) ('0' + minute / 10));
1577 sb.append((char) ('0' + minute % 10));
1578 ID = sb.toString();
1580 return new SimpleTimeZone((hour * (60 * 60 * 1000)
1581 + minute * (60 * 1000))
1582 * offset_direction, ID);
1584 catch (NumberFormatException e)
1589 TimeZone tz = getTimeZoneInternal(ID);
1590 if (tz != null)
1591 return tz;
1593 return new SimpleTimeZone(0, "GMT");
1597 * Gets the available IDs according to the given time zone
1598 * offset.
1599 * @param rawOffset the given time zone GMT offset.
1600 * @return An array of IDs, where the time zone has the specified GMT
1601 * offset. For example <code>{"Phoenix", "Denver"}</code>, since both have
1602 * GMT-07:00, but differ in daylight savings behaviour.
1604 public static String[] getAvailableIDs(int rawOffset)
1606 synchronized (TimeZone.class)
1608 HashMap<String,TimeZone> h = timezones();
1609 int count = 0;
1610 if (zoneinfo_dir == null)
1612 Iterator<Map.Entry<String,TimeZone>> iter = h.entrySet().iterator();
1613 while (iter.hasNext())
1615 // Don't iterate the values, since we want to count
1616 // doubled values (aliases)
1617 Map.Entry<String,TimeZone> entry = iter.next();
1618 if (entry.getValue().getRawOffset() == rawOffset)
1619 count++;
1622 String[] ids = new String[count];
1623 count = 0;
1624 iter = h.entrySet().iterator();
1625 while (iter.hasNext())
1627 Map.Entry<String,TimeZone> entry = iter.next();
1628 if (entry.getValue().getRawOffset() == rawOffset)
1629 ids[count++] = (String) entry.getKey();
1631 return ids;
1635 String[] s = getAvailableIDs();
1636 int count = 0;
1637 for (int i = 0; i < s.length; i++)
1639 TimeZone t = getTimeZoneInternal(s[i]);
1640 if (t == null || t.getRawOffset() != rawOffset)
1641 s[i] = null;
1642 else
1643 count++;
1645 String[] ids = new String[count];
1646 count = 0;
1647 for (int i = 0; i < s.length; i++)
1648 if (s[i] != null)
1649 ids[count++] = s[i];
1651 return ids;
1654 private static int getAvailableIDs(File d, String prefix, ArrayList<String[]> list)
1656 String[] files = d.list();
1657 int count = files.length;
1658 boolean top = prefix.length() == 0;
1659 list.add (files);
1660 for (int i = 0; i < files.length; i++)
1662 if (top
1663 && (files[i].equals("posix")
1664 || files[i].equals("right")
1665 || files[i].endsWith(".tab")
1666 || aliases0.get(files[i]) != null))
1668 files[i] = null;
1669 count--;
1670 continue;
1673 File f = new File(d, files[i]);
1674 if (f.isDirectory())
1676 count += getAvailableIDs(f, prefix + files[i]
1677 + File.separatorChar, list) - 1;
1678 files[i] = null;
1680 else
1681 files[i] = prefix + files[i];
1683 return count;
1687 * Gets all available IDs.
1688 * @return An array of all supported IDs.
1690 public static String[] getAvailableIDs()
1692 synchronized (TimeZone.class)
1694 HashMap<String,TimeZone> h = timezones();
1695 if (zoneinfo_dir == null)
1696 return h.keySet().toArray(new String[h.size()]);
1698 if (availableIDs != null)
1700 String[] ids = new String[availableIDs.length];
1701 for (int i = 0; i < availableIDs.length; i++)
1702 ids[i] = availableIDs[i];
1703 return ids;
1706 File d = new File(zoneinfo_dir);
1707 ArrayList<String[]> list = new ArrayList<String[]>(30);
1708 int count = getAvailableIDs(d, "", list) + aliases0.size();
1709 availableIDs = new String[count];
1710 String[] ids = new String[count];
1712 count = 0;
1713 for (int i = 0; i < list.size(); i++)
1715 String[] s = list.get(i);
1716 for (int j = 0; j < s.length; j++)
1717 if (s[j] != null)
1719 availableIDs[count] = s[j];
1720 ids[count++] = s[j];
1724 Iterator<Map.Entry<String,String>> iter = aliases0.entrySet().iterator();
1725 while (iter.hasNext())
1727 Map.Entry<String,String> entry = iter.next();
1728 availableIDs[count] = entry.getKey();
1729 ids[count++] = entry.getKey();
1732 return ids;
1737 * Returns the time zone under which the host is running. This
1738 * can be changed with setDefault.
1740 * @return A clone of the current default time zone for this host.
1741 * @see #setDefault
1743 public static TimeZone getDefault()
1745 return (TimeZone) defaultZone().clone();
1748 public static void setDefault(TimeZone zone)
1750 // Hmmmm. No Security checks?
1751 defaultZone0 = zone;
1755 * Test if the other time zone uses the same rule and only
1756 * possibly differs in ID. This implementation for this particular
1757 * class will return true if the raw offsets are identical. Subclasses
1758 * should override this method if they use daylight savings.
1759 * @return true if this zone has the same raw offset
1761 public boolean hasSameRules(TimeZone other)
1763 return other.getRawOffset() == getRawOffset();
1767 * Returns a clone of this object. I can't imagine, why this is
1768 * useful for a time zone.
1770 public Object clone()
1774 return super.clone();
1776 catch (CloneNotSupportedException ex)
1778 return null;