OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [util/] [TimeZone.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* java.util.TimeZone
2
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
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.
11
 
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.
16
 
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.
21
 
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.
26
 
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. */
38
 
39
 
40
package java.util;
41
 
42
import gnu.classpath.SystemProperties;
43
import gnu.java.lang.CPStringBuilder;
44
import gnu.java.util.ZoneInfo;
45
 
46
import java.io.File;
47
import java.security.AccessController;
48
import java.security.PrivilegedAction;
49
import java.text.DateFormatSymbols;
50
 
51
/**
52
 * This class represents a time zone offset and handles daylight savings.
53
 *
54
 * You can get the default time zone with <code>getDefault</code>.
55
 * This represents the time zone where program is running.
56
 *
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".
60
 *
61
 * With the <code>getAvailableIDs</code> method, you can get all the
62
 * supported time zone identifiers.
63
 *
64
 * @see Calendar
65
 * @see SimpleTimeZone
66
 * @author Jochen Hoenicke
67
 */
68
public abstract class TimeZone implements java.io.Serializable, Cloneable
69
{
70
 
71
  /**
72
   * Constant used to indicate that a short timezone abbreviation should
73
   * be returned, such as "EST"
74
   */
75
  public static final int SHORT = 0;
76
 
77
  /**
78
   * Constant used to indicate that a long timezone name should be
79
   * returned, such as "Eastern Standard Time".
80
   */
81
  public static final int LONG = 1;
82
 
83
  /**
84
   * The time zone identifier, e.g. PST.
85
   */
86
  private String ID;
87
 
88
  /**
89
   * The default time zone, as returned by getDefault.
90
   */
91
  private static TimeZone defaultZone0;
92
 
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.
99
   */
100
  private static synchronized TimeZone defaultZone()
101
  {
102
    /* Look up default timezone */
103
    if (defaultZone0 == null)
104
      {
105
        defaultZone0 = (TimeZone) AccessController.doPrivileged
106
          (new PrivilegedAction()
107
            {
108
              public Object run()
109
              {
110
                TimeZone zone = null;
111
 
112
                // Prefer System property user.timezone.
113
                String tzid = System.getProperty("user.timezone");
114
                if (tzid != null && !tzid.equals(""))
115
                  zone = getDefaultTimeZone(tzid);
116
 
117
                // Try platfom specific way.
118
                if (zone == null)
119
                  zone = VMTimeZone.getDefaultTimeZoneId();
120
 
121
                // Fall back on GMT.
122
                if (zone == null)
123
                  zone = getTimeZone ("GMT");
124
 
125
                return zone;
126
              }
127
            });
128
      }
129
 
130
    return defaultZone0;
131
  }
132
 
133
  private static final long serialVersionUID = 3581463369166924961L;
134
 
135
  /**
136
   * Flag whether zoneinfo data should be used,
137
   * otherwise builtin timezone data will be provided.
138
   */
139
  private static String zoneinfo_dir;
140
 
141
  /**
142
   * Cached copy of getAvailableIDs().
143
   */
144
  private static String[] availableIDs = null;
145
 
146
  /**
147
   * JDK 1.1.x compatibility aliases.
148
   */
149
  private static HashMap aliases0;
150
 
151
  /**
152
   * HashMap for timezones by ID.
153
   */
154
  private static HashMap timezones0;
155
  /* initialize this static field lazily to overhead if
156
   * it is not needed:
157
   */
158
  // Package-private to avoid a trampoline.
159
  static HashMap timezones()
160
  {
161
    if (timezones0 == null)
162
      {
163
        HashMap timezones = new HashMap();
164
        timezones0 = timezones;
165
 
166
        zoneinfo_dir = SystemProperties.getProperty("gnu.java.util.zoneinfo.dir");
167
        if (zoneinfo_dir != null && !new File(zoneinfo_dir).isDirectory())
168
          zoneinfo_dir = null;
169
 
170
        if (zoneinfo_dir != null)
171
          {
172
            aliases0 = new HashMap();
173
 
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;
206
          }
207
 
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);
902
      }
903
    return timezones0;
904
  }
905
 
906
  /**
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".
949
   */
950
  static TimeZone getDefaultTimeZone(String sysTimeZoneId)
951
  {
952
    String stdName = null;
953
    int stdOffs;
954
    int dstOffs;
955
    try
956
      {
957
        int idLength = sysTimeZoneId.length();
958
 
959
        int index = 0;
960
        int prevIndex;
961
        char c;
962
 
963
        // get std
964
        do
965
          c = sysTimeZoneId.charAt(index);
966
        while (c != '+' && c != '-' && c != ',' && c != ':'
967
               && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
968
 
969
        if (index >= idLength)
970
          return getTimeZoneInternal(sysTimeZoneId);
971
 
972
        stdName = sysTimeZoneId.substring(0, index);
973
        prevIndex = index;
974
 
975
        // get the std offset
976
        do
977
          c = sysTimeZoneId.charAt(index++);
978
        while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
979
               && index < idLength);
980
        if (index < idLength)
981
          index--;
982
 
983
        { // convert the dst string to a millis number
984
            String offset = sysTimeZoneId.substring(prevIndex, index);
985
            prevIndex = index;
986
 
987
            if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
988
              stdOffs = parseTime(offset.substring(1));
989
            else
990
              stdOffs = parseTime(offset);
991
 
992
            if (offset.charAt(0) == '-')
993
              stdOffs = -stdOffs;
994
 
995
            // TZ timezone offsets are positive when WEST of the meridian.
996
            stdOffs = -stdOffs;
997
        }
998
 
999
        // Done yet? (Format: std offset)
1000
        if (index >= idLength)
1001
          {
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;
1007
 
1008
            // Custom then.
1009
            return new SimpleTimeZone(stdOffs, stdName);
1010
          }
1011
 
1012
        // get dst
1013
        do
1014
          c = sysTimeZoneId.charAt(index);
1015
        while (c != '+' && c != '-' && c != ',' && c != ':'
1016
               && ! Character.isDigit(c) && c != '\0' && ++index < idLength);
1017
 
1018
        // Done yet? (Format: std offset dst)
1019
        if (index >= idLength)
1020
          {
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;
1027
 
1028
            // Custom then.
1029
            return new SimpleTimeZone(stdOffs, stdName);
1030
          }
1031
 
1032
        // get the dst offset
1033
        prevIndex = index;
1034
        do
1035
          c = sysTimeZoneId.charAt(index++);
1036
        while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c))
1037
               && index < idLength);
1038
        if (index < idLength)
1039
          index--;
1040
 
1041
        if (index == prevIndex && (c == ',' || c == ';'))
1042
          {
1043
            // Missing dst offset defaults to one hour ahead of standard
1044
            // time.
1045
            dstOffs = stdOffs + 60 * 60 * 1000;
1046
          }
1047
        else
1048
          { // convert the dst string to a millis number
1049
            String offset = sysTimeZoneId.substring(prevIndex, index);
1050
            prevIndex = index;
1051
 
1052
            if (offset.charAt(0) == '+' || offset.charAt(0) == '-')
1053
              dstOffs = parseTime(offset.substring(1));
1054
            else
1055
              dstOffs = parseTime(offset);
1056
 
1057
            if (offset.charAt(0) == '-')
1058
              dstOffs = -dstOffs;
1059
 
1060
            // TZ timezone offsets are positive when WEST of the meridian.
1061
            dstOffs = -dstOffs;
1062
          }
1063
 
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)
1067
          {
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;
1074
 
1075
            return new SimpleTimeZone(stdOffs, stdName);
1076
          }
1077
 
1078
        // get the DST rule
1079
        if (sysTimeZoneId.charAt(index) == ','
1080
            || sysTimeZoneId.charAt(index) == ';')
1081
          {
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);
1090
 
1091
            index = startTime.indexOf('/');
1092
            int startMillis;
1093
            int endMillis;
1094
            String startDate;
1095
            String endDate;
1096
            if (index != -1)
1097
              {
1098
                startDate = startTime.substring(0, index);
1099
                startMillis = parseTime(startTime.substring(index + 1));
1100
              }
1101
            else
1102
              {
1103
                startDate = startTime;
1104
                // if time isn't given, default to 2:00:00 AM.
1105
                startMillis = 2 * 60 * 60 * 1000;
1106
              }
1107
            index = endTime.indexOf('/');
1108
            if (index != -1)
1109
              {
1110
                endDate = endTime.substring(0, index);
1111
                endMillis = parseTime(endTime.substring(index + 1));
1112
              }
1113
            else
1114
              {
1115
                endDate = endTime;
1116
                // if time isn't given, default to 2:00:00 AM.
1117
                endMillis = 2 * 60 * 60 * 1000;
1118
              }
1119
 
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));
1125
          }
1126
      }
1127
 
1128
    // FIXME: Produce a warning here?
1129
    catch (IndexOutOfBoundsException _)
1130
      {
1131
      }
1132
    catch (NumberFormatException _)
1133
      {
1134
      }
1135
 
1136
    return null;
1137
  }
1138
 
1139
  /**
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.
1143
   */
1144
  private static int[] getDateParams(String date)
1145
  {
1146
    int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
1147
    int month;
1148
 
1149
    if (date.charAt(0) == 'M' || date.charAt(0) == 'm')
1150
      {
1151
        int day;
1152
 
1153
        // Month, week of month, day of week
1154
 
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.
1159
 
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.
1166
 
1167
        if (week == 5)
1168
          day = -1; // last day of month is -1 in java, 5 in TZ
1169
        else
1170
          {
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;
1176
          }
1177
 
1178
        month--; // Java month is zero-based.
1179
        return new int[] { month, day, dayOfWeek };
1180
      }
1181
 
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,
1185
 
1186
    if (date.charAt(0) != 'J' || date.charAt(0) != 'j')
1187
      {
1188
        julianDay = Integer.parseInt(date.substring(1));
1189
        julianDay++; // make 1-based
1190
        // Adjust day count to include feb 29.
1191
        dayCount = new int[]
1192
                   {
1193
                     0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
1194
                   };
1195
      }
1196
    else
1197
      // 1-based julian day
1198
      julianDay = Integer.parseInt(date);
1199
 
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 };
1209
  }
1210
 
1211
  /**
1212
   * Parses a time field hh[:mm[:ss]], returning the result
1213
   * in milliseconds. No leading sign.
1214
   */
1215
  private static int parseTime(String time)
1216
  {
1217
    int millis = 0;
1218
    int i = 0;
1219
 
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;
1228
 
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;
1238
 
1239
    millis += 1000 * Integer.parseInt(time.substring(++i));
1240
    return millis;
1241
  }
1242
 
1243
  /**
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.
1254
   */
1255
  public abstract int getOffset(int era, int year, int month,
1256
                                int day, int dayOfWeek, int milliseconds);
1257
 
1258
  /**
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
1265
   */
1266
  public int getOffset(long date)
1267
  {
1268
    return (inDaylightTime(new Date(date))
1269
            ? getRawOffset() + getDSTSavings()
1270
            : getRawOffset());
1271
  }
1272
 
1273
  /**
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.
1277
   */
1278
  public abstract int getRawOffset();
1279
 
1280
  /**
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.
1284
   */
1285
  public abstract void setRawOffset(int offsetMillis);
1286
 
1287
  /**
1288
   * Gets the identifier of this time zone. For instance, PST for
1289
   * Pacific Standard Time.
1290
   * @returns the ID of this time zone.
1291
   */
1292
  public String getID()
1293
  {
1294
    return ID;
1295
  }
1296
 
1297
  /**
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>
1302
   */
1303
  public void setID(String id)
1304
  {
1305
    if (id == null)
1306
      throw new NullPointerException();
1307
 
1308
    this.ID = id;
1309
  }
1310
 
1311
  /**
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.
1316
   *
1317
   * @return The name of the time zone.
1318
   */
1319
  public final String getDisplayName()
1320
  {
1321
    return (getDisplayName(false, LONG, Locale.getDefault()));
1322
  }
1323
 
1324
  /**
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.
1329
   *
1330
   * @param locale The locale for this timezone name.
1331
   *
1332
   * @return The name of the time zone.
1333
   */
1334
  public final String getDisplayName(Locale locale)
1335
  {
1336
    return (getDisplayName(false, LONG, locale));
1337
  }
1338
 
1339
  /**
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.
1343
   *
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.
1347
   *
1348
   * @return The name of the time zone.
1349
   */
1350
  public final String getDisplayName(boolean dst, int style)
1351
  {
1352
    return (getDisplayName(dst, style, Locale.getDefault()));
1353
  }
1354
 
1355
 
1356
  /**
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.
1360
   *
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.
1365
   *
1366
   * @return The name of the time zone.
1367
   */
1368
  public String getDisplayName(boolean dst, int style, Locale locale)
1369
  {
1370
    DateFormatSymbols dfs;
1371
    try
1372
      {
1373
        dfs = new DateFormatSymbols(locale);
1374
 
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++)
1378
          {
1379
            if (zoneinfo[i][0].equals(getID()))
1380
              {
1381
                if (!dst)
1382
                  {
1383
                    if (style == SHORT)
1384
                      return (zoneinfo[i][2]);
1385
                    else
1386
                      return (zoneinfo[i][1]);
1387
                  }
1388
                else
1389
                  {
1390
                    if (style == SHORT)
1391
                      return (zoneinfo[i][4]);
1392
                    else
1393
                      return (zoneinfo[i][3]);
1394
                  }
1395
              }
1396
          }
1397
      }
1398
    catch (MissingResourceException e)
1399
      {
1400
      }
1401
 
1402
    return getDefaultDisplayName(dst);
1403
  }
1404
 
1405
  private String getDefaultDisplayName(boolean dst)
1406
  {
1407
    int offset = getRawOffset() + (dst ? getDSTSavings() : 0);
1408
 
1409
    CPStringBuilder sb = new CPStringBuilder(9);
1410
    sb.append("GMT");
1411
 
1412
    offset = offset / (1000 * 60);
1413
    int hours = Math.abs(offset) / 60;
1414
    int minutes = Math.abs(offset) % 60;
1415
 
1416
    if (minutes != 0 || hours != 0)
1417
      {
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));
1424
      }
1425
 
1426
    return sb.toString();
1427
  }
1428
 
1429
  /**
1430
   * Returns true, if this time zone uses Daylight Savings Time.
1431
   */
1432
  public abstract boolean useDaylightTime();
1433
 
1434
  /**
1435
   * Returns true, if the given date is in Daylight Savings Time in this
1436
   * time zone.
1437
   * @param date the given Date.
1438
   */
1439
  public abstract boolean inDaylightTime(Date date);
1440
 
1441
  /**
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
1451
   */
1452
  public int getDSTSavings ()
1453
  {
1454
    return useDaylightTime () ? 3600000 : 0;
1455
  }
1456
 
1457
  /**
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.
1462
   */
1463
  private static TimeZone getTimeZoneInternal(String ID)
1464
  {
1465
    // First check timezones hash
1466
    TimeZone tz = null;
1467
    TimeZone tznew = null;
1468
    for (int pass = 0; pass < 2; pass++)
1469
      {
1470
        synchronized (TimeZone.class)
1471
          {
1472
            tz = (TimeZone) timezones().get(ID);
1473
            if (tz != null)
1474
              {
1475
                if (!tz.getID().equals(ID))
1476
                  {
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);
1485
                  }
1486
                return tz;
1487
              }
1488
            else if (tznew != null)
1489
              {
1490
                timezones().put(ID, tznew);
1491
                return tznew;
1492
              }
1493
          }
1494
 
1495
        if (pass == 1 || zoneinfo_dir == null)
1496
          return null;
1497
 
1498
        // aliases0 is never changing after first timezones(), so should
1499
        // be safe without synchronization.
1500
        String zonename = (String) aliases0.get(ID);
1501
        if (zonename == null)
1502
          zonename = ID;
1503
 
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;
1509
      }
1510
 
1511
    return null;
1512
  }
1513
 
1514
  /**
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.
1519
   */
1520
  public static TimeZone getTimeZone(String ID)
1521
  {
1522
    // Check for custom IDs first
1523
    if (ID.startsWith("GMT") && ID.length() > 3)
1524
      {
1525
        int pos = 3;
1526
        int offset_direction = 1;
1527
 
1528
        if (ID.charAt(pos) == '-')
1529
          {
1530
            offset_direction = -1;
1531
            pos++;
1532
          }
1533
        else if (ID.charAt(pos) == '+')
1534
          {
1535
            pos++;
1536
          }
1537
 
1538
        try
1539
          {
1540
            int hour, minute;
1541
 
1542
            String offset_str = ID.substring(pos);
1543
            int idx = offset_str.indexOf(":");
1544
            if (idx != -1)
1545
              {
1546
                hour = Integer.parseInt(offset_str.substring(0, idx));
1547
                minute = Integer.parseInt(offset_str.substring(idx + 1));
1548
              }
1549
            else
1550
              {
1551
                int offset_length = offset_str.length();
1552
                if (offset_length <= 2)
1553
                  {
1554
                    // Only hour
1555
                    hour = Integer.parseInt(offset_str);
1556
                    minute = 0;
1557
                  }
1558
                else
1559
                  {
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));
1565
                  }
1566
              }
1567
 
1568
            // Custom IDs have to be normalized
1569
            CPStringBuilder sb = new CPStringBuilder(9);
1570
            sb.append("GMT");
1571
 
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();
1579
 
1580
            return new SimpleTimeZone((hour * (60 * 60 * 1000)
1581
                                       + minute * (60 * 1000))
1582
                                      * offset_direction, ID);
1583
          }
1584
        catch (NumberFormatException e)
1585
          {
1586
          }
1587
      }
1588
 
1589
    TimeZone tz = getTimeZoneInternal(ID);
1590
    if (tz != null)
1591
      return tz;
1592
 
1593
    return new SimpleTimeZone(0, "GMT");
1594
  }
1595
 
1596
  /**
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.
1603
   */
1604
  public static String[] getAvailableIDs(int rawOffset)
1605
  {
1606
    synchronized (TimeZone.class)
1607
      {
1608
        HashMap h = timezones();
1609
        int count = 0;
1610
        if (zoneinfo_dir == null)
1611
          {
1612
            Iterator iter = h.entrySet().iterator();
1613
            while (iter.hasNext())
1614
              {
1615
                // Don't iterate the values, since we want to count
1616
                // doubled values (aliases)
1617
                Map.Entry entry = (Map.Entry) iter.next();
1618
                if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1619
                  count++;
1620
              }
1621
 
1622
            String[] ids = new String[count];
1623
            count = 0;
1624
            iter = h.entrySet().iterator();
1625
            while (iter.hasNext())
1626
              {
1627
                Map.Entry entry = (Map.Entry) iter.next();
1628
                if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset)
1629
                  ids[count++] = (String) entry.getKey();
1630
              }
1631
            return ids;
1632
          }
1633
      }
1634
 
1635
    String[] s = getAvailableIDs();
1636
    int count = 0;
1637
    for (int i = 0; i < s.length; i++)
1638
      {
1639
        TimeZone t = getTimeZoneInternal(s[i]);
1640
        if (t == null || t.getRawOffset() != rawOffset)
1641
          s[i] = null;
1642
        else
1643
          count++;
1644
      }
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];
1650
 
1651
    return ids;
1652
  }
1653
 
1654
  private static int getAvailableIDs(File d, String prefix, ArrayList list)
1655
    {
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++)
1661
        {
1662
          if (top
1663
              && (files[i].equals("posix")
1664
                  || files[i].equals("right")
1665
                  || files[i].endsWith(".tab")
1666
                  || aliases0.get(files[i]) != null))
1667
            {
1668
              files[i] = null;
1669
              count--;
1670
              continue;
1671
            }
1672
 
1673
          File f = new File(d, files[i]);
1674
          if (f.isDirectory())
1675
            {
1676
              count += getAvailableIDs(f, prefix + files[i]
1677
                                       + File.separatorChar, list) - 1;
1678
              files[i] = null;
1679
            }
1680
          else
1681
            files[i] = prefix + files[i];
1682
        }
1683
      return count;
1684
    }
1685
 
1686
  /**
1687
   * Gets all available IDs.
1688
   * @return An array of all supported IDs.
1689
   */
1690
  public static String[] getAvailableIDs()
1691
  {
1692
    synchronized (TimeZone.class)
1693
      {
1694
        HashMap h = timezones();
1695
        if (zoneinfo_dir == null)
1696
          return (String[]) h.keySet().toArray(new String[h.size()]);
1697
 
1698
        if (availableIDs != null)
1699
          {
1700
            String[] ids = new String[availableIDs.length];
1701
            for (int i = 0; i < availableIDs.length; i++)
1702
              ids[i] = availableIDs[i];
1703
            return ids;
1704
          }
1705
 
1706
        File d = new File(zoneinfo_dir);
1707
        ArrayList list = new ArrayList(30);
1708
        int count = getAvailableIDs(d, "", list) + aliases0.size();
1709
        availableIDs = new String[count];
1710
        String[] ids = new String[count];
1711
 
1712
        count = 0;
1713
        for (int i = 0; i < list.size(); i++)
1714
          {
1715
            String[] s = (String[]) list.get(i);
1716
            for (int j = 0; j < s.length; j++)
1717
              if (s[j] != null)
1718
                {
1719
                  availableIDs[count] = s[j];
1720
                  ids[count++] = s[j];
1721
                }
1722
          }
1723
 
1724
        Iterator iter = aliases0.entrySet().iterator();
1725
        while (iter.hasNext())
1726
          {
1727
            Map.Entry entry = (Map.Entry) iter.next();
1728
            availableIDs[count] = (String) entry.getKey();
1729
            ids[count++] = (String) entry.getKey();
1730
          }
1731
 
1732
        return ids;
1733
      }
1734
  }
1735
 
1736
  /**
1737
   * Returns the time zone under which the host is running.  This
1738
   * can be changed with setDefault.
1739
   *
1740
   * @return A clone of the current default time zone for this host.
1741
   * @see #setDefault
1742
   */
1743
  public static TimeZone getDefault()
1744
  {
1745
    return (TimeZone) defaultZone().clone();
1746
  }
1747
 
1748
  public static void setDefault(TimeZone zone)
1749
  {
1750
    // Hmmmm. No Security checks?
1751
    defaultZone0 = zone;
1752
  }
1753
 
1754
  /**
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
1760
   */
1761
  public boolean hasSameRules(TimeZone other)
1762
  {
1763
    return other.getRawOffset() == getRawOffset();
1764
  }
1765
 
1766
  /**
1767
   * Returns a clone of this object.  I can't imagine, why this is
1768
   * useful for a time zone.
1769
   */
1770
  public Object clone()
1771
  {
1772
    try
1773
      {
1774
        return super.clone();
1775
      }
1776
    catch (CloneNotSupportedException ex)
1777
      {
1778
        return null;
1779
      }
1780
  }
1781
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.