001 /* java.util.TimeZone 002 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 003 Free Software Foundation, Inc. 004 005 This file is part of GNU Classpath. 006 007 GNU Classpath is free software; you can redistribute it and/or modify 008 it under the terms of the GNU General Public License as published by 009 the Free Software Foundation; either version 2, or (at your option) 010 any later version. 011 012 GNU Classpath is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of 014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 General Public License for more details. 016 017 You should have received a copy of the GNU General Public License 018 along with GNU Classpath; see the file COPYING. If not, write to the 019 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 020 02110-1301 USA. 021 022 Linking this library statically or dynamically with other modules is 023 making a combined work based on this library. Thus, the terms and 024 conditions of the GNU General Public License cover the whole 025 combination. 026 027 As a special exception, the copyright holders of this library give you 028 permission to link this library with independent modules to produce an 029 executable, regardless of the license terms of these independent 030 modules, and to copy and distribute the resulting executable under 031 terms of your choice, provided that you also meet, for each linked 032 independent module, the terms and conditions of the license of that 033 module. An independent module is a module which is not derived from 034 or based on this library. If you modify this library, you may extend 035 this exception to your version of the library, but you are not 036 obligated to do so. If you do not wish to do so, delete this 037 exception statement from your version. */ 038 039 040 package java.util; 041 042 import gnu.classpath.SystemProperties; 043 import gnu.java.util.ZoneInfo; 044 import java.io.File; 045 import java.security.AccessController; 046 import java.security.PrivilegedAction; 047 import java.text.DateFormatSymbols; 048 049 /** 050 * This class represents a time zone offset and handles daylight savings. 051 * 052 * You can get the default time zone with <code>getDefault</code>. 053 * This represents the time zone where program is running. 054 * 055 * Another way to create a time zone is <code>getTimeZone</code>, where 056 * you can give an identifier as parameter. For instance, the identifier 057 * of the Central European Time zone is "CET". 058 * 059 * With the <code>getAvailableIDs</code> method, you can get all the 060 * supported time zone identifiers. 061 * 062 * @see Calendar 063 * @see SimpleTimeZone 064 * @author Jochen Hoenicke 065 */ 066 public abstract class TimeZone implements java.io.Serializable, Cloneable 067 { 068 069 /** 070 * Constant used to indicate that a short timezone abbreviation should 071 * be returned, such as "EST" 072 */ 073 public static final int SHORT = 0; 074 075 /** 076 * Constant used to indicate that a long timezone name should be 077 * returned, such as "Eastern Standard Time". 078 */ 079 public static final int LONG = 1; 080 081 /** 082 * The time zone identifier, e.g. PST. 083 */ 084 private String ID; 085 086 /** 087 * The default time zone, as returned by getDefault. 088 */ 089 private static TimeZone defaultZone0; 090 091 /** 092 * Tries to get the default TimeZone for this system if not already 093 * set. It will call <code>getDefaultTimeZone(String)</code> with 094 * the result of <code>System.getProperty("user.timezone")</code>. 095 * If that fails it calls <code>VMTimeZone.getDefaultTimeZoneId()</code>. 096 * If that also fails GMT is returned. 097 */ 098 private static synchronized TimeZone defaultZone() 099 { 100 /* Look up default timezone */ 101 if (defaultZone0 == null) 102 { 103 defaultZone0 = (TimeZone) AccessController.doPrivileged 104 (new PrivilegedAction() 105 { 106 public Object run() 107 { 108 TimeZone zone = null; 109 110 // Prefer System property user.timezone. 111 String tzid = System.getProperty("user.timezone"); 112 if (tzid != null && !tzid.equals("")) 113 zone = getDefaultTimeZone(tzid); 114 115 // Try platfom specific way. 116 if (zone == null) 117 zone = VMTimeZone.getDefaultTimeZoneId(); 118 119 // Fall back on GMT. 120 if (zone == null) 121 zone = getTimeZone ("GMT"); 122 123 return zone; 124 } 125 }); 126 } 127 128 return defaultZone0; 129 } 130 131 private static final long serialVersionUID = 3581463369166924961L; 132 133 /** 134 * Flag whether zoneinfo data should be used, 135 * otherwise builtin timezone data will be provided. 136 */ 137 private static String zoneinfo_dir; 138 139 /** 140 * Cached copy of getAvailableIDs(). 141 */ 142 private static String[] availableIDs = null; 143 144 /** 145 * JDK 1.1.x compatibility aliases. 146 */ 147 private static HashMap aliases0; 148 149 /** 150 * HashMap for timezones by ID. 151 */ 152 private static HashMap timezones0; 153 /* initialize this static field lazily to overhead if 154 * it is not needed: 155 */ 156 // Package-private to avoid a trampoline. 157 static HashMap timezones() 158 { 159 if (timezones0 == null) 160 { 161 HashMap timezones = new HashMap(); 162 timezones0 = timezones; 163 164 zoneinfo_dir = SystemProperties.getProperty("gnu.java.util.zoneinfo.dir"); 165 if (zoneinfo_dir != null && !new File(zoneinfo_dir).isDirectory()) 166 zoneinfo_dir = null; 167 168 if (zoneinfo_dir != null) 169 { 170 aliases0 = new HashMap(); 171 172 // These deprecated aliases for JDK 1.1.x compatibility 173 // should take precedence over data files read from 174 // /usr/share/zoneinfo. 175 aliases0.put("ACT", "Australia/Darwin"); 176 aliases0.put("AET", "Australia/Sydney"); 177 aliases0.put("AGT", "America/Argentina/Buenos_Aires"); 178 aliases0.put("ART", "Africa/Cairo"); 179 aliases0.put("AST", "America/Juneau"); 180 aliases0.put("BST", "Asia/Colombo"); 181 aliases0.put("CAT", "Africa/Gaborone"); 182 aliases0.put("CNT", "America/St_Johns"); 183 aliases0.put("CST", "CST6CDT"); 184 aliases0.put("CTT", "Asia/Brunei"); 185 aliases0.put("EAT", "Indian/Comoro"); 186 aliases0.put("ECT", "CET"); 187 aliases0.put("EST", "EST5EDT"); 188 aliases0.put("EST5", "EST5EDT"); 189 aliases0.put("IET", "EST5EDT"); 190 aliases0.put("IST", "Asia/Calcutta"); 191 aliases0.put("JST", "Asia/Seoul"); 192 aliases0.put("MIT", "Pacific/Niue"); 193 aliases0.put("MST", "MST7MDT"); 194 aliases0.put("MST7", "MST7MDT"); 195 aliases0.put("NET", "Indian/Mauritius"); 196 aliases0.put("NST", "Pacific/Auckland"); 197 aliases0.put("PLT", "Indian/Kerguelen"); 198 aliases0.put("PNT", "MST7MDT"); 199 aliases0.put("PRT", "America/Anguilla"); 200 aliases0.put("PST", "PST8PDT"); 201 aliases0.put("SST", "Pacific/Ponape"); 202 aliases0.put("VST", "Asia/Bangkok"); 203 return timezones; 204 } 205 206 TimeZone tz; 207 // Automatically generated by scripts/timezones.pl 208 // XXX - Should we read this data from a file? 209 tz = new SimpleTimeZone(-11000 * 3600, "MIT"); 210 timezones0.put("MIT", tz); 211 timezones0.put("Pacific/Apia", tz); 212 timezones0.put("Pacific/Midway", tz); 213 timezones0.put("Pacific/Niue", tz); 214 timezones0.put("Pacific/Pago_Pago", tz); 215 tz = new SimpleTimeZone 216 (-10000 * 3600, "America/Adak", 217 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 218 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 219 timezones0.put("America/Adak", tz); 220 tz = new SimpleTimeZone(-10000 * 3600, "HST"); 221 timezones0.put("HST", tz); 222 timezones0.put("Pacific/Fakaofo", tz); 223 timezones0.put("Pacific/Honolulu", tz); 224 timezones0.put("Pacific/Johnston", tz); 225 timezones0.put("Pacific/Rarotonga", tz); 226 timezones0.put("Pacific/Tahiti", tz); 227 tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas"); 228 timezones0.put("Pacific/Marquesas", tz); 229 tz = new SimpleTimeZone 230 (-9000 * 3600, "AST", 231 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 232 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 233 timezones0.put("AST", tz); 234 timezones0.put("America/Anchorage", tz); 235 timezones0.put("America/Juneau", tz); 236 timezones0.put("America/Nome", tz); 237 timezones0.put("America/Yakutat", tz); 238 tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier"); 239 timezones0.put("Pacific/Gambier", tz); 240 tz = new SimpleTimeZone 241 (-8000 * 3600, "America/Tijuana", 242 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, 243 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); 244 timezones0.put("America/Tijuana", tz); 245 tz = new SimpleTimeZone 246 (-8000 * 3600, "PST", 247 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 248 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 249 timezones0.put("PST", tz); 250 timezones0.put("PST8PDT", tz); 251 timezones0.put("America/Dawson", tz); 252 timezones0.put("America/Los_Angeles", tz); 253 timezones0.put("America/Vancouver", tz); 254 timezones0.put("America/Whitehorse", tz); 255 timezones0.put("US/Pacific-New", tz); 256 tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn"); 257 timezones0.put("Pacific/Pitcairn", tz); 258 tz = new SimpleTimeZone 259 (-7000 * 3600, "America/Chihuahua", 260 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, 261 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); 262 timezones0.put("America/Chihuahua", tz); 263 timezones0.put("America/Mazatlan", tz); 264 tz = new SimpleTimeZone(-7000 * 3600, "MST7"); 265 timezones0.put("MST7", tz); 266 timezones0.put("PNT", tz); 267 timezones0.put("America/Dawson_Creek", tz); 268 timezones0.put("America/Hermosillo", tz); 269 timezones0.put("America/Phoenix", tz); 270 tz = new SimpleTimeZone 271 (-7000 * 3600, "MST", 272 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 273 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 274 timezones0.put("MST", tz); 275 timezones0.put("MST7MDT", tz); 276 timezones0.put("America/Boise", tz); 277 timezones0.put("America/Cambridge_Bay", tz); 278 timezones0.put("America/Denver", tz); 279 timezones0.put("America/Edmonton", tz); 280 timezones0.put("America/Inuvik", tz); 281 timezones0.put("America/Shiprock", tz); 282 timezones0.put("America/Yellowknife", tz); 283 tz = new SimpleTimeZone 284 (-6000 * 3600, "America/Cancun", 285 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, 286 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); 287 timezones0.put("America/Cancun", tz); 288 timezones0.put("America/Merida", tz); 289 timezones0.put("America/Mexico_City", tz); 290 timezones0.put("America/Monterrey", tz); 291 tz = new SimpleTimeZone(-6000 * 3600, "America/Belize"); 292 timezones0.put("America/Belize", tz); 293 timezones0.put("America/Costa_Rica", tz); 294 timezones0.put("America/El_Salvador", tz); 295 timezones0.put("America/Guatemala", tz); 296 timezones0.put("America/Managua", tz); 297 timezones0.put("America/Regina", tz); 298 timezones0.put("America/Swift_Current", tz); 299 timezones0.put("America/Tegucigalpa", tz); 300 timezones0.put("Pacific/Galapagos", tz); 301 tz = new SimpleTimeZone 302 (-6000 * 3600, "CST", 303 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 304 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 305 timezones0.put("CST", tz); 306 timezones0.put("CST6CDT", tz); 307 timezones0.put("America/Chicago", tz); 308 timezones0.put("America/Indiana/Knox", tz); 309 timezones0.put("America/Indiana/Petersburg", tz); 310 timezones0.put("America/Indiana/Vincennes", tz); 311 timezones0.put("America/Menominee", tz); 312 timezones0.put("America/North_Dakota/Center", tz); 313 timezones0.put("America/North_Dakota/New_Salem", tz); 314 timezones0.put("America/Rainy_River", tz); 315 timezones0.put("America/Rankin_Inlet", tz); 316 timezones0.put("America/Winnipeg", tz); 317 tz = new SimpleTimeZone 318 (-6000 * 3600, "Pacific/Easter", 319 Calendar.OCTOBER, 2, Calendar.SATURDAY, 22000 * 3600, 320 Calendar.MARCH, 2, Calendar.SATURDAY, 22000 * 3600); 321 timezones0.put("Pacific/Easter", tz); 322 tz = new SimpleTimeZone(-5000 * 3600, "EST5"); 323 timezones0.put("EST5", tz); 324 timezones0.put("IET", tz); 325 timezones0.put("America/Atikokan", tz); 326 timezones0.put("America/Bogota", tz); 327 timezones0.put("America/Cayman", tz); 328 timezones0.put("America/Eirunepe", tz); 329 timezones0.put("America/Guayaquil", tz); 330 timezones0.put("America/Jamaica", tz); 331 timezones0.put("America/Lima", tz); 332 timezones0.put("America/Panama", tz); 333 timezones0.put("America/Rio_Branco", tz); 334 tz = new SimpleTimeZone 335 (-5000 * 3600, "America/Havana", 336 Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, 337 Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); 338 timezones0.put("America/Havana", tz); 339 tz = new SimpleTimeZone 340 (-5000 * 3600, "America/Grand_Turk", 341 Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, 342 Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); 343 timezones0.put("America/Grand_Turk", tz); 344 timezones0.put("America/Port-au-Prince", tz); 345 tz = new SimpleTimeZone 346 (-5000 * 3600, "EST", 347 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 348 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 349 timezones0.put("EST", tz); 350 timezones0.put("EST5EDT", tz); 351 timezones0.put("America/Detroit", tz); 352 timezones0.put("America/Indiana/Indianapolis", tz); 353 timezones0.put("America/Indiana/Marengo", tz); 354 timezones0.put("America/Indiana/Vevay", tz); 355 timezones0.put("America/Iqaluit", tz); 356 timezones0.put("America/Kentucky/Louisville", tz); 357 timezones0.put("America/Kentucky/Monticello", tz); 358 timezones0.put("America/Montreal", tz); 359 timezones0.put("America/Nassau", tz); 360 timezones0.put("America/New_York", tz); 361 timezones0.put("America/Nipigon", tz); 362 timezones0.put("America/Pangnirtung", tz); 363 timezones0.put("America/Thunder_Bay", tz); 364 timezones0.put("America/Toronto", tz); 365 tz = new SimpleTimeZone 366 (-4000 * 3600, "America/Asuncion", 367 Calendar.OCTOBER, 3, Calendar.SUNDAY, 0 * 3600, 368 Calendar.MARCH, 2, Calendar.SUNDAY, 0 * 3600); 369 timezones0.put("America/Asuncion", tz); 370 tz = new SimpleTimeZone(-4000 * 3600, "PRT"); 371 timezones0.put("PRT", tz); 372 timezones0.put("America/Anguilla", tz); 373 timezones0.put("America/Antigua", tz); 374 timezones0.put("America/Aruba", tz); 375 timezones0.put("America/Barbados", tz); 376 timezones0.put("America/Blanc-Sablon", tz); 377 timezones0.put("America/Boa_Vista", tz); 378 timezones0.put("America/Caracas", tz); 379 timezones0.put("America/Curacao", tz); 380 timezones0.put("America/Dominica", tz); 381 timezones0.put("America/Grenada", tz); 382 timezones0.put("America/Guadeloupe", tz); 383 timezones0.put("America/Guyana", tz); 384 timezones0.put("America/La_Paz", tz); 385 timezones0.put("America/Manaus", tz); 386 timezones0.put("America/Martinique", tz); 387 timezones0.put("America/Montserrat", tz); 388 timezones0.put("America/Port_of_Spain", tz); 389 timezones0.put("America/Porto_Velho", tz); 390 timezones0.put("America/Puerto_Rico", tz); 391 timezones0.put("America/Santo_Domingo", tz); 392 timezones0.put("America/St_Kitts", tz); 393 timezones0.put("America/St_Lucia", tz); 394 timezones0.put("America/St_Thomas", tz); 395 timezones0.put("America/St_Vincent", tz); 396 timezones0.put("America/Tortola", tz); 397 tz = new SimpleTimeZone 398 (-4000 * 3600, "America/Campo_Grande", 399 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600, 400 Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); 401 timezones0.put("America/Campo_Grande", tz); 402 timezones0.put("America/Cuiaba", tz); 403 tz = new SimpleTimeZone 404 (-4000 * 3600, "America/Goose_Bay", 405 Calendar.MARCH, 2, Calendar.SUNDAY, 60000, 406 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000); 407 timezones0.put("America/Goose_Bay", tz); 408 tz = new SimpleTimeZone 409 (-4000 * 3600, "America/Glace_Bay", 410 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 411 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 412 timezones0.put("America/Glace_Bay", tz); 413 timezones0.put("America/Halifax", tz); 414 timezones0.put("America/Moncton", tz); 415 timezones0.put("America/Thule", tz); 416 timezones0.put("Atlantic/Bermuda", tz); 417 tz = new SimpleTimeZone 418 (-4000 * 3600, "America/Santiago", 419 Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600, 420 Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600); 421 timezones0.put("America/Santiago", tz); 422 timezones0.put("Antarctica/Palmer", tz); 423 tz = new SimpleTimeZone 424 (-4000 * 3600, "Atlantic/Stanley", 425 Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600, 426 Calendar.APRIL, 3, Calendar.SUNDAY, 2000 * 3600); 427 timezones0.put("Atlantic/Stanley", tz); 428 tz = new SimpleTimeZone 429 (-3500 * 3600, "CNT", 430 Calendar.MARCH, 2, Calendar.SUNDAY, 60000, 431 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000); 432 timezones0.put("CNT", tz); 433 timezones0.put("America/St_Johns", tz); 434 tz = new SimpleTimeZone 435 (-3000 * 3600, "America/Godthab", 436 Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600, 437 Calendar.OCTOBER, 30, -Calendar.SATURDAY, 23000 * 3600); 438 timezones0.put("America/Godthab", tz); 439 tz = new SimpleTimeZone 440 (-3000 * 3600, "America/Miquelon", 441 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, 442 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); 443 timezones0.put("America/Miquelon", tz); 444 tz = new SimpleTimeZone 445 (-3000 * 3600, "America/Montevideo", 446 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, 447 Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600); 448 timezones0.put("America/Montevideo", tz); 449 tz = new SimpleTimeZone 450 (-3000 * 3600, "America/Sao_Paulo", 451 Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600, 452 Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); 453 timezones0.put("America/Sao_Paulo", tz); 454 tz = new SimpleTimeZone(-3000 * 3600, "AGT"); 455 timezones0.put("AGT", tz); 456 timezones0.put("America/Araguaina", tz); 457 timezones0.put("America/Argentina/Buenos_Aires", tz); 458 timezones0.put("America/Argentina/Catamarca", tz); 459 timezones0.put("America/Argentina/Cordoba", tz); 460 timezones0.put("America/Argentina/Jujuy", tz); 461 timezones0.put("America/Argentina/La_Rioja", tz); 462 timezones0.put("America/Argentina/Mendoza", tz); 463 timezones0.put("America/Argentina/Rio_Gallegos", tz); 464 timezones0.put("America/Argentina/San_Juan", tz); 465 timezones0.put("America/Argentina/Tucuman", tz); 466 timezones0.put("America/Argentina/Ushuaia", tz); 467 timezones0.put("America/Bahia", tz); 468 timezones0.put("America/Belem", tz); 469 timezones0.put("America/Cayenne", tz); 470 timezones0.put("America/Fortaleza", tz); 471 timezones0.put("America/Maceio", tz); 472 timezones0.put("America/Paramaribo", tz); 473 timezones0.put("America/Recife", tz); 474 timezones0.put("Antarctica/Rothera", tz); 475 tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha"); 476 timezones0.put("America/Noronha", tz); 477 timezones0.put("Atlantic/South_Georgia", tz); 478 tz = new SimpleTimeZone 479 (-1000 * 3600, "America/Scoresbysund", 480 Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, 481 Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); 482 timezones0.put("America/Scoresbysund", tz); 483 timezones0.put("Atlantic/Azores", tz); 484 tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde"); 485 timezones0.put("Atlantic/Cape_Verde", tz); 486 tz = new SimpleTimeZone(0 * 3600, "GMT"); 487 timezones0.put("GMT", tz); 488 timezones0.put("UTC", tz); 489 timezones0.put("Africa/Abidjan", tz); 490 timezones0.put("Africa/Accra", tz); 491 timezones0.put("Africa/Bamako", tz); 492 timezones0.put("Africa/Banjul", tz); 493 timezones0.put("Africa/Bissau", tz); 494 timezones0.put("Africa/Casablanca", tz); 495 timezones0.put("Africa/Conakry", tz); 496 timezones0.put("Africa/Dakar", tz); 497 timezones0.put("Africa/El_Aaiun", tz); 498 timezones0.put("Africa/Freetown", tz); 499 timezones0.put("Africa/Lome", tz); 500 timezones0.put("Africa/Monrovia", tz); 501 timezones0.put("Africa/Nouakchott", tz); 502 timezones0.put("Africa/Ouagadougou", tz); 503 timezones0.put("Africa/Sao_Tome", tz); 504 timezones0.put("America/Danmarkshavn", tz); 505 timezones0.put("Atlantic/Reykjavik", tz); 506 timezones0.put("Atlantic/St_Helena", tz); 507 tz = new SimpleTimeZone 508 (0 * 3600, "WET", 509 Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, 510 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); 511 timezones0.put("WET", tz); 512 timezones0.put("Atlantic/Canary", tz); 513 timezones0.put("Atlantic/Faroe", tz); 514 timezones0.put("Atlantic/Madeira", tz); 515 timezones0.put("Europe/Dublin", tz); 516 timezones0.put("Europe/Guernsey", tz); 517 timezones0.put("Europe/Isle_of_Man", tz); 518 timezones0.put("Europe/Jersey", tz); 519 timezones0.put("Europe/Lisbon", tz); 520 timezones0.put("Europe/London", tz); 521 tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers"); 522 timezones0.put("Africa/Algiers", tz); 523 timezones0.put("Africa/Bangui", tz); 524 timezones0.put("Africa/Brazzaville", tz); 525 timezones0.put("Africa/Douala", tz); 526 timezones0.put("Africa/Kinshasa", tz); 527 timezones0.put("Africa/Lagos", tz); 528 timezones0.put("Africa/Libreville", tz); 529 timezones0.put("Africa/Luanda", tz); 530 timezones0.put("Africa/Malabo", tz); 531 timezones0.put("Africa/Ndjamena", tz); 532 timezones0.put("Africa/Niamey", tz); 533 timezones0.put("Africa/Porto-Novo", tz); 534 tz = new SimpleTimeZone 535 (1000 * 3600, "Africa/Windhoek", 536 Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600, 537 Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600); 538 timezones0.put("Africa/Windhoek", tz); 539 tz = new SimpleTimeZone 540 (1000 * 3600, "CET", 541 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 542 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 543 timezones0.put("CET", tz); 544 timezones0.put("ECT", tz); 545 timezones0.put("MET", tz); 546 timezones0.put("Africa/Ceuta", tz); 547 timezones0.put("Africa/Tunis", tz); 548 timezones0.put("Arctic/Longyearbyen", tz); 549 timezones0.put("Atlantic/Jan_Mayen", tz); 550 timezones0.put("Europe/Amsterdam", tz); 551 timezones0.put("Europe/Andorra", tz); 552 timezones0.put("Europe/Belgrade", tz); 553 timezones0.put("Europe/Berlin", tz); 554 timezones0.put("Europe/Bratislava", tz); 555 timezones0.put("Europe/Brussels", tz); 556 timezones0.put("Europe/Budapest", tz); 557 timezones0.put("Europe/Copenhagen", tz); 558 timezones0.put("Europe/Gibraltar", tz); 559 timezones0.put("Europe/Ljubljana", tz); 560 timezones0.put("Europe/Luxembourg", tz); 561 timezones0.put("Europe/Madrid", tz); 562 timezones0.put("Europe/Malta", tz); 563 timezones0.put("Europe/Monaco", tz); 564 timezones0.put("Europe/Oslo", tz); 565 timezones0.put("Europe/Paris", tz); 566 timezones0.put("Europe/Podgorica", tz); 567 timezones0.put("Europe/Prague", tz); 568 timezones0.put("Europe/Rome", tz); 569 timezones0.put("Europe/San_Marino", tz); 570 timezones0.put("Europe/Sarajevo", tz); 571 timezones0.put("Europe/Skopje", tz); 572 timezones0.put("Europe/Stockholm", tz); 573 timezones0.put("Europe/Tirane", tz); 574 timezones0.put("Europe/Vaduz", tz); 575 timezones0.put("Europe/Vatican", tz); 576 timezones0.put("Europe/Vienna", tz); 577 timezones0.put("Europe/Warsaw", tz); 578 timezones0.put("Europe/Zagreb", tz); 579 timezones0.put("Europe/Zurich", tz); 580 tz = new SimpleTimeZone 581 (2000 * 3600, "ART", 582 Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600, 583 Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 24000 * 3600); 584 timezones0.put("ART", tz); 585 timezones0.put("Africa/Cairo", tz); 586 tz = new SimpleTimeZone(2000 * 3600, "CAT"); 587 timezones0.put("CAT", tz); 588 timezones0.put("Africa/Blantyre", tz); 589 timezones0.put("Africa/Bujumbura", tz); 590 timezones0.put("Africa/Gaborone", tz); 591 timezones0.put("Africa/Harare", tz); 592 timezones0.put("Africa/Johannesburg", tz); 593 timezones0.put("Africa/Kigali", tz); 594 timezones0.put("Africa/Lubumbashi", tz); 595 timezones0.put("Africa/Lusaka", tz); 596 timezones0.put("Africa/Maputo", tz); 597 timezones0.put("Africa/Maseru", tz); 598 timezones0.put("Africa/Mbabane", tz); 599 timezones0.put("Africa/Tripoli", tz); 600 timezones0.put("Asia/Jerusalem", tz); 601 tz = new SimpleTimeZone 602 (2000 * 3600, "Asia/Amman", 603 Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600, 604 Calendar.OCTOBER, -1, Calendar.FRIDAY, 1000 * 3600); 605 timezones0.put("Asia/Amman", tz); 606 tz = new SimpleTimeZone 607 (2000 * 3600, "Asia/Beirut", 608 Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, 609 Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); 610 timezones0.put("Asia/Beirut", tz); 611 tz = new SimpleTimeZone 612 (2000 * 3600, "Asia/Damascus", 613 Calendar.APRIL, 1, 0, 0 * 3600, 614 Calendar.OCTOBER, 1, 0, 0 * 3600); 615 timezones0.put("Asia/Damascus", tz); 616 tz = new SimpleTimeZone 617 (2000 * 3600, "Asia/Gaza", 618 Calendar.APRIL, 1, 0, 0 * 3600, 619 Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600); 620 timezones0.put("Asia/Gaza", tz); 621 tz = new SimpleTimeZone 622 (2000 * 3600, "EET", 623 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600, 624 Calendar.OCTOBER, -1, Calendar.SUNDAY, 4000 * 3600); 625 timezones0.put("EET", tz); 626 timezones0.put("Asia/Istanbul", tz); 627 timezones0.put("Asia/Nicosia", tz); 628 timezones0.put("Europe/Athens", tz); 629 timezones0.put("Europe/Bucharest", tz); 630 timezones0.put("Europe/Chisinau", tz); 631 timezones0.put("Europe/Helsinki", tz); 632 timezones0.put("Europe/Istanbul", tz); 633 timezones0.put("Europe/Kiev", tz); 634 timezones0.put("Europe/Mariehamn", tz); 635 timezones0.put("Europe/Nicosia", tz); 636 timezones0.put("Europe/Riga", tz); 637 timezones0.put("Europe/Simferopol", tz); 638 timezones0.put("Europe/Sofia", tz); 639 timezones0.put("Europe/Tallinn", tz); 640 timezones0.put("Europe/Uzhgorod", tz); 641 timezones0.put("Europe/Vilnius", tz); 642 timezones0.put("Europe/Zaporozhye", tz); 643 tz = new SimpleTimeZone 644 (2000 * 3600, "Europe/Kaliningrad", 645 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 646 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 647 timezones0.put("Europe/Kaliningrad", tz); 648 timezones0.put("Europe/Minsk", tz); 649 tz = new SimpleTimeZone 650 (3000 * 3600, "Asia/Baghdad", 651 Calendar.APRIL, 1, 0, 3000 * 3600, 652 Calendar.OCTOBER, 1, 0, 4000 * 3600); 653 timezones0.put("Asia/Baghdad", tz); 654 tz = new SimpleTimeZone 655 (3000 * 3600, "Europe/Moscow", 656 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 657 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 658 timezones0.put("Europe/Moscow", tz); 659 timezones0.put("Europe/Volgograd", tz); 660 tz = new SimpleTimeZone(3000 * 3600, "EAT"); 661 timezones0.put("EAT", tz); 662 timezones0.put("Africa/Addis_Ababa", tz); 663 timezones0.put("Africa/Asmara", tz); 664 timezones0.put("Africa/Dar_es_Salaam", tz); 665 timezones0.put("Africa/Djibouti", tz); 666 timezones0.put("Africa/Kampala", tz); 667 timezones0.put("Africa/Khartoum", tz); 668 timezones0.put("Africa/Mogadishu", tz); 669 timezones0.put("Africa/Nairobi", tz); 670 timezones0.put("Antarctica/Syowa", tz); 671 timezones0.put("Asia/Aden", tz); 672 timezones0.put("Asia/Bahrain", tz); 673 timezones0.put("Asia/Kuwait", tz); 674 timezones0.put("Asia/Qatar", tz); 675 timezones0.put("Asia/Riyadh", tz); 676 timezones0.put("Indian/Antananarivo", tz); 677 timezones0.put("Indian/Comoro", tz); 678 timezones0.put("Indian/Mayotte", tz); 679 tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran"); 680 timezones0.put("Asia/Tehran", tz); 681 tz = new SimpleTimeZone 682 (4000 * 3600, "Asia/Baku", 683 Calendar.MARCH, -1, Calendar.SUNDAY, 4000 * 3600, 684 Calendar.OCTOBER, -1, Calendar.SUNDAY, 5000 * 3600); 685 timezones0.put("Asia/Baku", tz); 686 tz = new SimpleTimeZone 687 (4000 * 3600, "Asia/Yerevan", 688 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 689 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 690 timezones0.put("Asia/Yerevan", tz); 691 timezones0.put("Europe/Samara", tz); 692 tz = new SimpleTimeZone(4000 * 3600, "NET"); 693 timezones0.put("NET", tz); 694 timezones0.put("Asia/Dubai", tz); 695 timezones0.put("Asia/Muscat", tz); 696 timezones0.put("Asia/Tbilisi", tz); 697 timezones0.put("Indian/Mahe", tz); 698 timezones0.put("Indian/Mauritius", tz); 699 timezones0.put("Indian/Reunion", tz); 700 tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul"); 701 timezones0.put("Asia/Kabul", tz); 702 tz = new SimpleTimeZone 703 (5000 * 3600, "Asia/Yekaterinburg", 704 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 705 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 706 timezones0.put("Asia/Yekaterinburg", tz); 707 tz = new SimpleTimeZone(5000 * 3600, "PLT"); 708 timezones0.put("PLT", tz); 709 timezones0.put("Asia/Aqtau", tz); 710 timezones0.put("Asia/Aqtobe", tz); 711 timezones0.put("Asia/Ashgabat", tz); 712 timezones0.put("Asia/Dushanbe", tz); 713 timezones0.put("Asia/Karachi", tz); 714 timezones0.put("Asia/Oral", tz); 715 timezones0.put("Asia/Samarkand", tz); 716 timezones0.put("Asia/Tashkent", tz); 717 timezones0.put("Indian/Kerguelen", tz); 718 timezones0.put("Indian/Maldives", tz); 719 tz = new SimpleTimeZone(5500 * 3600, "BST"); 720 timezones0.put("BST", tz); 721 timezones0.put("IST", tz); 722 timezones0.put("Asia/Calcutta", tz); 723 timezones0.put("Asia/Colombo", tz); 724 tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu"); 725 timezones0.put("Asia/Katmandu", tz); 726 tz = new SimpleTimeZone(6000 * 3600, "Antarctica/Mawson"); 727 timezones0.put("Antarctica/Mawson", tz); 728 timezones0.put("Antarctica/Vostok", tz); 729 timezones0.put("Asia/Almaty", tz); 730 timezones0.put("Asia/Bishkek", tz); 731 timezones0.put("Asia/Dhaka", tz); 732 timezones0.put("Asia/Qyzylorda", tz); 733 timezones0.put("Asia/Thimphu", tz); 734 timezones0.put("Indian/Chagos", tz); 735 tz = new SimpleTimeZone 736 (6000 * 3600, "Asia/Novosibirsk", 737 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 738 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 739 timezones0.put("Asia/Novosibirsk", tz); 740 timezones0.put("Asia/Omsk", tz); 741 tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon"); 742 timezones0.put("Asia/Rangoon", tz); 743 timezones0.put("Indian/Cocos", tz); 744 tz = new SimpleTimeZone(7000 * 3600, "VST"); 745 timezones0.put("VST", tz); 746 timezones0.put("Antarctica/Davis", tz); 747 timezones0.put("Asia/Bangkok", tz); 748 timezones0.put("Asia/Jakarta", tz); 749 timezones0.put("Asia/Phnom_Penh", tz); 750 timezones0.put("Asia/Pontianak", tz); 751 timezones0.put("Asia/Saigon", tz); 752 timezones0.put("Asia/Vientiane", tz); 753 timezones0.put("Indian/Christmas", tz); 754 tz = new SimpleTimeZone 755 (7000 * 3600, "Asia/Hovd", 756 Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, 757 Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); 758 timezones0.put("Asia/Hovd", tz); 759 tz = new SimpleTimeZone 760 (7000 * 3600, "Asia/Krasnoyarsk", 761 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 762 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 763 timezones0.put("Asia/Krasnoyarsk", tz); 764 tz = new SimpleTimeZone(8000 * 3600, "CTT"); 765 timezones0.put("CTT", tz); 766 timezones0.put("Antarctica/Casey", tz); 767 timezones0.put("Asia/Brunei", tz); 768 timezones0.put("Asia/Chongqing", tz); 769 timezones0.put("Asia/Harbin", tz); 770 timezones0.put("Asia/Hong_Kong", tz); 771 timezones0.put("Asia/Kashgar", tz); 772 timezones0.put("Asia/Kuala_Lumpur", tz); 773 timezones0.put("Asia/Kuching", tz); 774 timezones0.put("Asia/Macau", tz); 775 timezones0.put("Asia/Makassar", tz); 776 timezones0.put("Asia/Manila", tz); 777 timezones0.put("Asia/Shanghai", tz); 778 timezones0.put("Asia/Singapore", tz); 779 timezones0.put("Asia/Taipei", tz); 780 timezones0.put("Asia/Urumqi", tz); 781 timezones0.put("Australia/Perth", tz); 782 tz = new SimpleTimeZone 783 (8000 * 3600, "Asia/Irkutsk", 784 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 785 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 786 timezones0.put("Asia/Irkutsk", tz); 787 tz = new SimpleTimeZone 788 (8000 * 3600, "Asia/Ulaanbaatar", 789 Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, 790 Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); 791 timezones0.put("Asia/Ulaanbaatar", tz); 792 tz = new SimpleTimeZone(8750 * 3600, "Australia/Eucla"); 793 timezones0.put("Australia/Eucla", tz); 794 tz = new SimpleTimeZone 795 (9000 * 3600, "Asia/Choibalsan", 796 Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, 797 Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); 798 timezones0.put("Asia/Choibalsan", tz); 799 tz = new SimpleTimeZone(9000 * 3600, "JST"); 800 timezones0.put("JST", tz); 801 timezones0.put("Asia/Dili", tz); 802 timezones0.put("Asia/Jayapura", tz); 803 timezones0.put("Asia/Pyongyang", tz); 804 timezones0.put("Asia/Seoul", tz); 805 timezones0.put("Asia/Tokyo", tz); 806 timezones0.put("Pacific/Palau", tz); 807 tz = new SimpleTimeZone 808 (9000 * 3600, "Asia/Yakutsk", 809 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 810 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 811 timezones0.put("Asia/Yakutsk", tz); 812 tz = new SimpleTimeZone 813 (9500 * 3600, "Australia/Adelaide", 814 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, 815 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); 816 timezones0.put("Australia/Adelaide", tz); 817 timezones0.put("Australia/Broken_Hill", tz); 818 tz = new SimpleTimeZone(9500 * 3600, "ACT"); 819 timezones0.put("ACT", tz); 820 timezones0.put("Australia/Darwin", tz); 821 tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville"); 822 timezones0.put("Antarctica/DumontDUrville", tz); 823 timezones0.put("Australia/Brisbane", tz); 824 timezones0.put("Australia/Lindeman", tz); 825 timezones0.put("Pacific/Guam", tz); 826 timezones0.put("Pacific/Port_Moresby", tz); 827 timezones0.put("Pacific/Saipan", tz); 828 timezones0.put("Pacific/Truk", tz); 829 tz = new SimpleTimeZone 830 (10000 * 3600, "Asia/Sakhalin", 831 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 832 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 833 timezones0.put("Asia/Sakhalin", tz); 834 timezones0.put("Asia/Vladivostok", tz); 835 tz = new SimpleTimeZone 836 (10000 * 3600, "Australia/Currie", 837 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, 838 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); 839 timezones0.put("Australia/Currie", tz); 840 timezones0.put("Australia/Hobart", tz); 841 tz = new SimpleTimeZone 842 (10000 * 3600, "AET", 843 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, 844 Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); 845 timezones0.put("AET", tz); 846 timezones0.put("Australia/Melbourne", tz); 847 timezones0.put("Australia/Sydney", tz); 848 tz = new SimpleTimeZone 849 (10500 * 3600, "Australia/Lord_Howe", 850 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, 851 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600); 852 timezones0.put("Australia/Lord_Howe", tz); 853 tz = new SimpleTimeZone 854 (11000 * 3600, "Asia/Magadan", 855 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 856 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 857 timezones0.put("Asia/Magadan", tz); 858 tz = new SimpleTimeZone(11000 * 3600, "SST"); 859 timezones0.put("SST", tz); 860 timezones0.put("Pacific/Efate", tz); 861 timezones0.put("Pacific/Guadalcanal", tz); 862 timezones0.put("Pacific/Kosrae", tz); 863 timezones0.put("Pacific/Noumea", tz); 864 timezones0.put("Pacific/Ponape", tz); 865 tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk"); 866 timezones0.put("Pacific/Norfolk", tz); 867 tz = new SimpleTimeZone 868 (12000 * 3600, "NST", 869 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, 870 Calendar.MARCH, 3, Calendar.SUNDAY, 3000 * 3600); 871 timezones0.put("NST", tz); 872 timezones0.put("Antarctica/McMurdo", tz); 873 timezones0.put("Antarctica/South_Pole", tz); 874 timezones0.put("Pacific/Auckland", tz); 875 tz = new SimpleTimeZone 876 (12000 * 3600, "Asia/Anadyr", 877 Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 878 Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); 879 timezones0.put("Asia/Anadyr", tz); 880 timezones0.put("Asia/Kamchatka", tz); 881 tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji"); 882 timezones0.put("Pacific/Fiji", tz); 883 timezones0.put("Pacific/Funafuti", tz); 884 timezones0.put("Pacific/Kwajalein", tz); 885 timezones0.put("Pacific/Majuro", tz); 886 timezones0.put("Pacific/Nauru", tz); 887 timezones0.put("Pacific/Tarawa", tz); 888 timezones0.put("Pacific/Wake", tz); 889 timezones0.put("Pacific/Wallis", tz); 890 tz = new SimpleTimeZone 891 (12750 * 3600, "Pacific/Chatham", 892 Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600, 893 Calendar.MARCH, 3, Calendar.SUNDAY, 3750 * 3600); 894 timezones0.put("Pacific/Chatham", tz); 895 tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury"); 896 timezones0.put("Pacific/Enderbury", tz); 897 timezones0.put("Pacific/Tongatapu", tz); 898 tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati"); 899 timezones0.put("Pacific/Kiritimati", tz); 900 } 901 return timezones0; 902 } 903 904 /** 905 * Maps a time zone name (with optional GMT offset and daylight time 906 * zone name) to one of the known time zones. This method called 907 * with the result of <code>System.getProperty("user.timezone")</code> 908 * or <code>getDefaultTimeZoneId()</code>. Note that giving one of 909 * the standard tz data names from ftp://elsie.nci.nih.gov/pub/ is 910 * preferred. 911 * The time zone name can be given as follows: 912 * <code>(standard zone name)[(GMT offset)[(DST zone name)[DST offset]]] 913 * </code> 914 * <p> 915 * If only a (standard zone name) is given (no numbers in the 916 * String) then it gets mapped directly to the TimeZone with that 917 * name, if that fails null is returned. 918 * <p> 919 * Alternately, a POSIX-style TZ string can be given, defining the time zone: 920 * <code>std offset dst offset,date/time,date/time</code> 921 * See the glibc manual, or the man page for <code>tzset</code> for details 922 * of this format. 923 * <p> 924 * A GMT offset is the offset to add to the local time to get GMT. 925 * If a (GMT offset) is included (either in seconds or hours) then 926 * an attempt is made to find a TimeZone name matching both the name 927 * and the offset (that doesn't observe daylight time, if the 928 * timezone observes daylight time then you must include a daylight 929 * time zone name after the offset), if that fails then a TimeZone 930 * with the given GMT offset is returned (whether or not the 931 * TimeZone observes daylight time is ignored), if that also fails 932 * the GMT TimeZone is returned. 933 * <p> 934 * If the String ends with (GMT offset)(daylight time zone name) 935 * then an attempt is made to find a TimeZone with the given name and 936 * GMT offset that also observes (the daylight time zone name is not 937 * currently used in any other way), if that fails a TimeZone with 938 * the given GMT offset that observes daylight time is returned, if 939 * that also fails the GMT TimeZone is returned. 940 * <p> 941 * Examples: In Chicago, the time zone id could be "CST6CDT", but 942 * the preferred name would be "America/Chicago". In Indianapolis 943 * (which does not have Daylight Savings Time) the string could be 944 * "EST5", but the preferred name would be "America/Indianapolis". 945 * The standard time zone name for The Netherlands is "Europe/Amsterdam", 946 * but can also be given as "CET-1CEST". 947 */ 948 static TimeZone getDefaultTimeZone(String sysTimeZoneId) 949 { 950 String stdName = null; 951 int stdOffs; 952 int dstOffs; 953 try 954 { 955 int idLength = sysTimeZoneId.length(); 956 957 int index = 0; 958 int prevIndex; 959 char c; 960 961 // get std 962 do 963 c = sysTimeZoneId.charAt(index); 964 while (c != '+' && c != '-' && c != ',' && c != ':' 965 && ! Character.isDigit(c) && c != '\0' && ++index < idLength); 966 967 if (index >= idLength) 968 return getTimeZoneInternal(sysTimeZoneId); 969 970 stdName = sysTimeZoneId.substring(0, index); 971 prevIndex = index; 972 973 // get the std offset 974 do 975 c = sysTimeZoneId.charAt(index++); 976 while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) 977 && index < idLength); 978 if (index < idLength) 979 index--; 980 981 { // convert the dst string to a millis number 982 String offset = sysTimeZoneId.substring(prevIndex, index); 983 prevIndex = index; 984 985 if (offset.charAt(0) == '+' || offset.charAt(0) == '-') 986 stdOffs = parseTime(offset.substring(1)); 987 else 988 stdOffs = parseTime(offset); 989 990 if (offset.charAt(0) == '-') 991 stdOffs = -stdOffs; 992 993 // TZ timezone offsets are positive when WEST of the meridian. 994 stdOffs = -stdOffs; 995 } 996 997 // Done yet? (Format: std offset) 998 if (index >= idLength) 999 { 1000 // Do we have an existing timezone with that name and offset? 1001 TimeZone tz = getTimeZoneInternal(stdName); 1002 if (tz != null) 1003 if (tz.getRawOffset() == stdOffs) 1004 return tz; 1005 1006 // Custom then. 1007 return new SimpleTimeZone(stdOffs, stdName); 1008 } 1009 1010 // get dst 1011 do 1012 c = sysTimeZoneId.charAt(index); 1013 while (c != '+' && c != '-' && c != ',' && c != ':' 1014 && ! Character.isDigit(c) && c != '\0' && ++index < idLength); 1015 1016 // Done yet? (Format: std offset dst) 1017 if (index >= idLength) 1018 { 1019 // Do we have an existing timezone with that name and offset 1020 // which has DST? 1021 TimeZone tz = getTimeZoneInternal(stdName); 1022 if (tz != null) 1023 if (tz.getRawOffset() == stdOffs && tz.useDaylightTime()) 1024 return tz; 1025 1026 // Custom then. 1027 return new SimpleTimeZone(stdOffs, stdName); 1028 } 1029 1030 // get the dst offset 1031 prevIndex = index; 1032 do 1033 c = sysTimeZoneId.charAt(index++); 1034 while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) 1035 && index < idLength); 1036 if (index < idLength) 1037 index--; 1038 1039 if (index == prevIndex && (c == ',' || c == ';')) 1040 { 1041 // Missing dst offset defaults to one hour ahead of standard 1042 // time. 1043 dstOffs = stdOffs + 60 * 60 * 1000; 1044 } 1045 else 1046 { // convert the dst string to a millis number 1047 String offset = sysTimeZoneId.substring(prevIndex, index); 1048 prevIndex = index; 1049 1050 if (offset.charAt(0) == '+' || offset.charAt(0) == '-') 1051 dstOffs = parseTime(offset.substring(1)); 1052 else 1053 dstOffs = parseTime(offset); 1054 1055 if (offset.charAt(0) == '-') 1056 dstOffs = -dstOffs; 1057 1058 // TZ timezone offsets are positive when WEST of the meridian. 1059 dstOffs = -dstOffs; 1060 } 1061 1062 // Done yet? (Format: std offset dst offset) 1063 // FIXME: We don't support DST without a rule given. Should we? 1064 if (index >= idLength) 1065 { 1066 // Time Zone existing with same name, dst and offsets? 1067 TimeZone tz = getTimeZoneInternal(stdName); 1068 if (tz != null) 1069 if (tz.getRawOffset() == stdOffs && tz.useDaylightTime() 1070 && tz.getDSTSavings() == (dstOffs - stdOffs)) 1071 return tz; 1072 1073 return new SimpleTimeZone(stdOffs, stdName); 1074 } 1075 1076 // get the DST rule 1077 if (sysTimeZoneId.charAt(index) == ',' 1078 || sysTimeZoneId.charAt(index) == ';') 1079 { 1080 index++; 1081 int offs = index; 1082 while (sysTimeZoneId.charAt(index) != ',' 1083 && sysTimeZoneId.charAt(index) != ';') 1084 index++; 1085 String startTime = sysTimeZoneId.substring(offs, index); 1086 index++; 1087 String endTime = sysTimeZoneId.substring(index); 1088 1089 index = startTime.indexOf('/'); 1090 int startMillis; 1091 int endMillis; 1092 String startDate; 1093 String endDate; 1094 if (index != -1) 1095 { 1096 startDate = startTime.substring(0, index); 1097 startMillis = parseTime(startTime.substring(index + 1)); 1098 } 1099 else 1100 { 1101 startDate = startTime; 1102 // if time isn't given, default to 2:00:00 AM. 1103 startMillis = 2 * 60 * 60 * 1000; 1104 } 1105 index = endTime.indexOf('/'); 1106 if (index != -1) 1107 { 1108 endDate = endTime.substring(0, index); 1109 endMillis = parseTime(endTime.substring(index + 1)); 1110 } 1111 else 1112 { 1113 endDate = endTime; 1114 // if time isn't given, default to 2:00:00 AM. 1115 endMillis = 2 * 60 * 60 * 1000; 1116 } 1117 1118 int[] start = getDateParams(startDate); 1119 int[] end = getDateParams(endDate); 1120 return new SimpleTimeZone(stdOffs, stdName, start[0], start[1], 1121 start[2], startMillis, end[0], end[1], 1122 end[2], endMillis, (dstOffs - stdOffs)); 1123 } 1124 } 1125 1126 // FIXME: Produce a warning here? 1127 catch (IndexOutOfBoundsException _) 1128 { 1129 } 1130 catch (NumberFormatException _) 1131 { 1132 } 1133 1134 return null; 1135 } 1136 1137 /** 1138 * Parses and returns the params for a POSIX TZ date field, 1139 * in the format int[]{ month, day, dayOfWeek }, following the 1140 * SimpleTimeZone constructor rules. 1141 */ 1142 private static int[] getDateParams(String date) 1143 { 1144 int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; 1145 int month; 1146 1147 if (date.charAt(0) == 'M' || date.charAt(0) == 'm') 1148 { 1149 int day; 1150 1151 // Month, week of month, day of week 1152 1153 // "Mm.w.d". d is between 0 (Sunday) and 6. Week w is 1154 // between 1 and 5; Week 1 is the first week in which day d 1155 // occurs and Week 5 specifies the last d day in the month. 1156 // Month m is between 1 and 12. 1157 1158 month = Integer.parseInt(date.substring(1, date.indexOf('.'))); 1159 int week = Integer.parseInt(date.substring(date.indexOf('.') + 1, 1160 date.lastIndexOf('.'))); 1161 int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.') 1162 + 1)); 1163 dayOfWeek++; // Java day of week is one-based, Sunday is first day. 1164 1165 if (week == 5) 1166 day = -1; // last day of month is -1 in java, 5 in TZ 1167 else 1168 { 1169 // First day of week starting on or after. For example, 1170 // to specify the second Sunday of April, set month to 1171 // APRIL, day-of-month to 8, and day-of-week to -SUNDAY. 1172 day = (week - 1) * 7 + 1; 1173 dayOfWeek = -dayOfWeek; 1174 } 1175 1176 month--; // Java month is zero-based. 1177 return new int[] { month, day, dayOfWeek }; 1178 } 1179 1180 // julian day, either zero-based 0<=n<=365 (incl feb 29) 1181 // or one-based 1<=n<=365 (no feb 29) 1182 int julianDay; // Julian day, 1183 1184 if (date.charAt(0) != 'J' || date.charAt(0) != 'j') 1185 { 1186 julianDay = Integer.parseInt(date.substring(1)); 1187 julianDay++; // make 1-based 1188 // Adjust day count to include feb 29. 1189 dayCount = new int[] 1190 { 1191 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 1192 }; 1193 } 1194 else 1195 // 1-based julian day 1196 julianDay = Integer.parseInt(date); 1197 1198 int i = 11; 1199 while (i > 0) 1200 if (dayCount[i] < julianDay) 1201 break; 1202 else 1203 i--; 1204 julianDay -= dayCount[i]; 1205 month = i; 1206 return new int[] { month, julianDay, 0 }; 1207 } 1208 1209 /** 1210 * Parses a time field hh[:mm[:ss]], returning the result 1211 * in milliseconds. No leading sign. 1212 */ 1213 private static int parseTime(String time) 1214 { 1215 int millis = 0; 1216 int i = 0; 1217 1218 while (i < time.length()) 1219 if (time.charAt(i) == ':') 1220 break; 1221 else 1222 i++; 1223 millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i)); 1224 if (i >= time.length()) 1225 return millis; 1226 1227 int iprev = ++i; 1228 while (i < time.length()) 1229 if (time.charAt(i) == ':') 1230 break; 1231 else 1232 i++; 1233 millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i)); 1234 if (i >= time.length()) 1235 return millis; 1236 1237 millis += 1000 * Integer.parseInt(time.substring(++i)); 1238 return millis; 1239 } 1240 1241 /** 1242 * Gets the time zone offset, for current date, modified in case of 1243 * daylight savings. This is the offset to add to UTC to get the local 1244 * time. 1245 * @param era the era of the given date 1246 * @param year the year of the given date 1247 * @param month the month of the given date, 0 for January. 1248 * @param day the day of month 1249 * @param dayOfWeek the day of week 1250 * @param milliseconds the millis in the day (in local standard time) 1251 * @return the time zone offset in milliseconds. 1252 */ 1253 public abstract int getOffset(int era, int year, int month, 1254 int day, int dayOfWeek, int milliseconds); 1255 1256 /** 1257 * Get the time zone offset for the specified date, modified in case of 1258 * daylight savings. This is the offset to add to UTC to get the local 1259 * time. 1260 * @param date the date represented in millisecends 1261 * since January 1, 1970 00:00:00 GMT. 1262 * @since 1.4 1263 */ 1264 public int getOffset(long date) 1265 { 1266 return (inDaylightTime(new Date(date)) 1267 ? getRawOffset() + getDSTSavings() 1268 : getRawOffset()); 1269 } 1270 1271 /** 1272 * Gets the time zone offset, ignoring daylight savings. This is 1273 * the offset to add to UTC to get the local time. 1274 * @return the time zone offset in milliseconds. 1275 */ 1276 public abstract int getRawOffset(); 1277 1278 /** 1279 * Sets the time zone offset, ignoring daylight savings. This is 1280 * the offset to add to UTC to get the local time. 1281 * @param offsetMillis the time zone offset to GMT. 1282 */ 1283 public abstract void setRawOffset(int offsetMillis); 1284 1285 /** 1286 * Gets the identifier of this time zone. For instance, PST for 1287 * Pacific Standard Time. 1288 * @returns the ID of this time zone. 1289 */ 1290 public String getID() 1291 { 1292 return ID; 1293 } 1294 1295 /** 1296 * Sets the identifier of this time zone. For instance, PST for 1297 * Pacific Standard Time. 1298 * @param id the new time zone ID. 1299 * @throws NullPointerException if <code>id</code> is <code>null</code> 1300 */ 1301 public void setID(String id) 1302 { 1303 if (id == null) 1304 throw new NullPointerException(); 1305 1306 this.ID = id; 1307 } 1308 1309 /** 1310 * This method returns a string name of the time zone suitable 1311 * for displaying to the user. The string returned will be the long 1312 * description of the timezone in the current locale. The name 1313 * displayed will assume daylight savings time is not in effect. 1314 * 1315 * @return The name of the time zone. 1316 */ 1317 public final String getDisplayName() 1318 { 1319 return (getDisplayName(false, LONG, Locale.getDefault())); 1320 } 1321 1322 /** 1323 * This method returns a string name of the time zone suitable 1324 * for displaying to the user. The string returned will be the long 1325 * description of the timezone in the specified locale. The name 1326 * displayed will assume daylight savings time is not in effect. 1327 * 1328 * @param locale The locale for this timezone name. 1329 * 1330 * @return The name of the time zone. 1331 */ 1332 public final String getDisplayName(Locale locale) 1333 { 1334 return (getDisplayName(false, LONG, locale)); 1335 } 1336 1337 /** 1338 * This method returns a string name of the time zone suitable 1339 * for displaying to the user. The string returned will be of the 1340 * specified type in the current locale. 1341 * 1342 * @param dst Whether or not daylight savings time is in effect. 1343 * @param style <code>LONG</code> for a long name, <code>SHORT</code> for 1344 * a short abbreviation. 1345 * 1346 * @return The name of the time zone. 1347 */ 1348 public final String getDisplayName(boolean dst, int style) 1349 { 1350 return (getDisplayName(dst, style, Locale.getDefault())); 1351 } 1352 1353 1354 /** 1355 * This method returns a string name of the time zone suitable 1356 * for displaying to the user. The string returned will be of the 1357 * specified type in the specified locale. 1358 * 1359 * @param dst Whether or not daylight savings time is in effect. 1360 * @param style <code>LONG</code> for a long name, <code>SHORT</code> for 1361 * a short abbreviation. 1362 * @param locale The locale for this timezone name. 1363 * 1364 * @return The name of the time zone. 1365 */ 1366 public String getDisplayName(boolean dst, int style, Locale locale) 1367 { 1368 DateFormatSymbols dfs; 1369 try 1370 { 1371 dfs = new DateFormatSymbols(locale); 1372 1373 // The format of the value returned is defined by us. 1374 String[][]zoneinfo = dfs.getZoneStrings(); 1375 for (int i = 0; i < zoneinfo.length; i++) 1376 { 1377 if (zoneinfo[i][0].equals(getID())) 1378 { 1379 if (!dst) 1380 { 1381 if (style == SHORT) 1382 return (zoneinfo[i][2]); 1383 else 1384 return (zoneinfo[i][1]); 1385 } 1386 else 1387 { 1388 if (style == SHORT) 1389 return (zoneinfo[i][4]); 1390 else 1391 return (zoneinfo[i][3]); 1392 } 1393 } 1394 } 1395 } 1396 catch (MissingResourceException e) 1397 { 1398 } 1399 1400 return getDefaultDisplayName(dst); 1401 } 1402 1403 private String getDefaultDisplayName(boolean dst) 1404 { 1405 int offset = getRawOffset() + (dst ? getDSTSavings() : 0); 1406 1407 StringBuffer sb = new StringBuffer(9); 1408 sb.append("GMT"); 1409 1410 offset = offset / (1000 * 60); 1411 int hours = Math.abs(offset) / 60; 1412 int minutes = Math.abs(offset) % 60; 1413 1414 if (minutes != 0 || hours != 0) 1415 { 1416 sb.append(offset >= 0 ? '+' : '-'); 1417 sb.append((char) ('0' + hours / 10)); 1418 sb.append((char) ('0' + hours % 10)); 1419 sb.append(':'); 1420 sb.append((char) ('0' + minutes / 10)); 1421 sb.append((char) ('0' + minutes % 10)); 1422 } 1423 1424 return sb.toString(); 1425 } 1426 1427 /** 1428 * Returns true, if this time zone uses Daylight Savings Time. 1429 */ 1430 public abstract boolean useDaylightTime(); 1431 1432 /** 1433 * Returns true, if the given date is in Daylight Savings Time in this 1434 * time zone. 1435 * @param date the given Date. 1436 */ 1437 public abstract boolean inDaylightTime(Date date); 1438 1439 /** 1440 * Gets the daylight savings offset. This is a positive offset in 1441 * milliseconds with respect to standard time. Typically this 1442 * is one hour, but for some time zones this may be half an our. 1443 * <p>The default implementation returns 3600000 milliseconds 1444 * (one hour) if the time zone uses daylight savings time 1445 * (as specified by {@link #useDaylightTime()}), otherwise 1446 * it returns 0. 1447 * @return the daylight savings offset in milliseconds. 1448 * @since 1.4 1449 */ 1450 public int getDSTSavings () 1451 { 1452 return useDaylightTime () ? 3600000 : 0; 1453 } 1454 1455 /** 1456 * Gets the TimeZone for the given ID. 1457 * @param ID the time zone identifier. 1458 * @return The time zone for the identifier or GMT, if no such time 1459 * zone exists. 1460 */ 1461 private static TimeZone getTimeZoneInternal(String ID) 1462 { 1463 // First check timezones hash 1464 TimeZone tz = null; 1465 TimeZone tznew = null; 1466 for (int pass = 0; pass < 2; pass++) 1467 { 1468 synchronized (TimeZone.class) 1469 { 1470 tz = (TimeZone) timezones().get(ID); 1471 if (tz != null) 1472 { 1473 if (!tz.getID().equals(ID)) 1474 { 1475 // We always return a timezone with the requested ID. 1476 // This is the same behaviour as with JDK1.2. 1477 tz = (TimeZone) tz.clone(); 1478 tz.setID(ID); 1479 // We also save the alias, so that we return the same 1480 // object again if getTimeZone is called with the same 1481 // alias. 1482 timezones().put(ID, tz); 1483 } 1484 return tz; 1485 } 1486 else if (tznew != null) 1487 { 1488 timezones().put(ID, tznew); 1489 return tznew; 1490 } 1491 } 1492 1493 if (pass == 1 || zoneinfo_dir == null) 1494 return null; 1495 1496 // aliases0 is never changing after first timezones(), so should 1497 // be safe without synchronization. 1498 String zonename = (String) aliases0.get(ID); 1499 if (zonename == null) 1500 zonename = ID; 1501 1502 // Read the file outside of the critical section, it is expensive. 1503 tznew = ZoneInfo.readTZFile (ID, zoneinfo_dir 1504 + File.separatorChar + zonename); 1505 if (tznew == null) 1506 return null; 1507 } 1508 1509 return null; 1510 } 1511 1512 /** 1513 * Gets the TimeZone for the given ID. 1514 * @param ID the time zone identifier. 1515 * @return The time zone for the identifier or GMT, if no such time 1516 * zone exists. 1517 */ 1518 public static TimeZone getTimeZone(String ID) 1519 { 1520 // Check for custom IDs first 1521 if (ID.startsWith("GMT") && ID.length() > 3) 1522 { 1523 int pos = 3; 1524 int offset_direction = 1; 1525 1526 if (ID.charAt(pos) == '-') 1527 { 1528 offset_direction = -1; 1529 pos++; 1530 } 1531 else if (ID.charAt(pos) == '+') 1532 { 1533 pos++; 1534 } 1535 1536 try 1537 { 1538 int hour, minute; 1539 1540 String offset_str = ID.substring(pos); 1541 int idx = offset_str.indexOf(":"); 1542 if (idx != -1) 1543 { 1544 hour = Integer.parseInt(offset_str.substring(0, idx)); 1545 minute = Integer.parseInt(offset_str.substring(idx + 1)); 1546 } 1547 else 1548 { 1549 int offset_length = offset_str.length(); 1550 if (offset_length <= 2) 1551 { 1552 // Only hour 1553 hour = Integer.parseInt(offset_str); 1554 minute = 0; 1555 } 1556 else 1557 { 1558 // hour and minute, not separated by colon 1559 hour = Integer.parseInt 1560 (offset_str.substring(0, offset_length - 2)); 1561 minute = Integer.parseInt 1562 (offset_str.substring(offset_length - 2)); 1563 } 1564 } 1565 1566 // Custom IDs have to be normalized 1567 StringBuffer sb = new StringBuffer(9); 1568 sb.append("GMT"); 1569 1570 sb.append(offset_direction >= 0 ? '+' : '-'); 1571 sb.append((char) ('0' + hour / 10)); 1572 sb.append((char) ('0' + hour % 10)); 1573 sb.append(':'); 1574 sb.append((char) ('0' + minute / 10)); 1575 sb.append((char) ('0' + minute % 10)); 1576 ID = sb.toString(); 1577 1578 return new SimpleTimeZone((hour * (60 * 60 * 1000) 1579 + minute * (60 * 1000)) 1580 * offset_direction, ID); 1581 } 1582 catch (NumberFormatException e) 1583 { 1584 } 1585 } 1586 1587 TimeZone tz = getTimeZoneInternal(ID); 1588 if (tz != null) 1589 return tz; 1590 1591 return new SimpleTimeZone(0, "GMT"); 1592 } 1593 1594 /** 1595 * Gets the available IDs according to the given time zone 1596 * offset. 1597 * @param rawOffset the given time zone GMT offset. 1598 * @return An array of IDs, where the time zone has the specified GMT 1599 * offset. For example <code>{"Phoenix", "Denver"}</code>, since both have 1600 * GMT-07:00, but differ in daylight savings behaviour. 1601 */ 1602 public static String[] getAvailableIDs(int rawOffset) 1603 { 1604 synchronized (TimeZone.class) 1605 { 1606 HashMap h = timezones(); 1607 int count = 0; 1608 if (zoneinfo_dir == null) 1609 { 1610 Iterator iter = h.entrySet().iterator(); 1611 while (iter.hasNext()) 1612 { 1613 // Don't iterate the values, since we want to count 1614 // doubled values (aliases) 1615 Map.Entry entry = (Map.Entry) iter.next(); 1616 if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) 1617 count++; 1618 } 1619 1620 String[] ids = new String[count]; 1621 count = 0; 1622 iter = h.entrySet().iterator(); 1623 while (iter.hasNext()) 1624 { 1625 Map.Entry entry = (Map.Entry) iter.next(); 1626 if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) 1627 ids[count++] = (String) entry.getKey(); 1628 } 1629 return ids; 1630 } 1631 } 1632 1633 String[] s = getAvailableIDs(); 1634 int count = 0; 1635 for (int i = 0; i < s.length; i++) 1636 { 1637 TimeZone t = getTimeZoneInternal(s[i]); 1638 if (t == null || t.getRawOffset() != rawOffset) 1639 s[i] = null; 1640 else 1641 count++; 1642 } 1643 String[] ids = new String[count]; 1644 count = 0; 1645 for (int i = 0; i < s.length; i++) 1646 if (s[i] != null) 1647 ids[count++] = s[i]; 1648 1649 return ids; 1650 } 1651 1652 private static int getAvailableIDs(File d, String prefix, ArrayList list) 1653 { 1654 String[] files = d.list(); 1655 int count = files.length; 1656 boolean top = prefix.length() == 0; 1657 list.add (files); 1658 for (int i = 0; i < files.length; i++) 1659 { 1660 if (top 1661 && (files[i].equals("posix") 1662 || files[i].equals("right") 1663 || files[i].endsWith(".tab") 1664 || aliases0.get(files[i]) != null)) 1665 { 1666 files[i] = null; 1667 count--; 1668 continue; 1669 } 1670 1671 File f = new File(d, files[i]); 1672 if (f.isDirectory()) 1673 { 1674 count += getAvailableIDs(f, prefix + files[i] 1675 + File.separatorChar, list) - 1; 1676 files[i] = null; 1677 } 1678 else 1679 files[i] = prefix + files[i]; 1680 } 1681 return count; 1682 } 1683 1684 /** 1685 * Gets all available IDs. 1686 * @return An array of all supported IDs. 1687 */ 1688 public static String[] getAvailableIDs() 1689 { 1690 synchronized (TimeZone.class) 1691 { 1692 HashMap h = timezones(); 1693 if (zoneinfo_dir == null) 1694 return (String[]) h.keySet().toArray(new String[h.size()]); 1695 1696 if (availableIDs != null) 1697 { 1698 String[] ids = new String[availableIDs.length]; 1699 for (int i = 0; i < availableIDs.length; i++) 1700 ids[i] = availableIDs[i]; 1701 return ids; 1702 } 1703 1704 File d = new File(zoneinfo_dir); 1705 ArrayList list = new ArrayList(30); 1706 int count = getAvailableIDs(d, "", list) + aliases0.size(); 1707 availableIDs = new String[count]; 1708 String[] ids = new String[count]; 1709 1710 count = 0; 1711 for (int i = 0; i < list.size(); i++) 1712 { 1713 String[] s = (String[]) list.get(i); 1714 for (int j = 0; j < s.length; j++) 1715 if (s[j] != null) 1716 { 1717 availableIDs[count] = s[j]; 1718 ids[count++] = s[j]; 1719 } 1720 } 1721 1722 Iterator iter = aliases0.entrySet().iterator(); 1723 while (iter.hasNext()) 1724 { 1725 Map.Entry entry = (Map.Entry) iter.next(); 1726 availableIDs[count] = (String) entry.getKey(); 1727 ids[count++] = (String) entry.getKey(); 1728 } 1729 1730 return ids; 1731 } 1732 } 1733 1734 /** 1735 * Returns the time zone under which the host is running. This 1736 * can be changed with setDefault. 1737 * 1738 * @return A clone of the current default time zone for this host. 1739 * @see #setDefault 1740 */ 1741 public static TimeZone getDefault() 1742 { 1743 return (TimeZone) defaultZone().clone(); 1744 } 1745 1746 public static void setDefault(TimeZone zone) 1747 { 1748 // Hmmmm. No Security checks? 1749 defaultZone0 = zone; 1750 } 1751 1752 /** 1753 * Test if the other time zone uses the same rule and only 1754 * possibly differs in ID. This implementation for this particular 1755 * class will return true if the raw offsets are identical. Subclasses 1756 * should override this method if they use daylight savings. 1757 * @return true if this zone has the same raw offset 1758 */ 1759 public boolean hasSameRules(TimeZone other) 1760 { 1761 return other.getRawOffset() == getRawOffset(); 1762 } 1763 1764 /** 1765 * Returns a clone of this object. I can't imagine, why this is 1766 * useful for a time zone. 1767 */ 1768 public Object clone() 1769 { 1770 try 1771 { 1772 return super.clone(); 1773 } 1774 catch (CloneNotSupportedException ex) 1775 { 1776 return null; 1777 } 1778 } 1779 }