1 7 8 package com.ibm.icu.util; 9 10 import java.io.Serializable ; 11 import java.lang.ref.SoftReference ; 12 import java.util.Date ; 13 import java.util.Hashtable ; 14 import java.util.Locale ; 15 import java.util.MissingResourceException ; 16 17 import com.ibm.icu.impl.ICUResourceBundle; 18 import com.ibm.icu.impl.TimeZoneAdapter; 19 import com.ibm.icu.impl.ZoneMeta; 20 import com.ibm.icu.text.SimpleDateFormat; 21 22 74 abstract public class TimeZone implements Serializable , Cloneable { 75 private static final long serialVersionUID = -744942128318337471L; 77 78 83 public TimeZone() { 84 } 85 86 92 public static final int SHORT = 0; 93 94 100 public static final int LONG = 1; 101 102 106 private static final int SHORT_GENERIC = 2; 107 108 112 private static final int LONG_GENERIC = 3; 113 114 117 private static Hashtable cachedLocaleData = new Hashtable (3); 118 119 132 abstract public int getOffset(int era, int year, int month, int day, 133 int dayOfWeek, int milliseconds); 134 135 136 150 public int getOffset(long date) { 151 int[] result = new int[2]; 152 getOffset(date, false, result); 153 return result[0]+result[1]; 154 } 155 156 177 public void getOffset(long date, boolean local, int[] offsets) { 178 offsets[0] = getRawOffset(); 179 180 if (!local) { 182 date += offsets[0]; } 184 185 for (int pass=0; ; ++pass) { 189 int fields[] = new int[4]; 190 long day = floorDivide(date, MILLIS_PER_DAY, fields); 191 int millis = fields[0]; 192 193 computeGregorianFields(day, fields); 194 195 offsets[1] = getOffset(GregorianCalendar.AD, 196 fields[0], fields[1], fields[2], 197 fields[3], millis) - offsets[0]; 198 199 if (pass!=0 || local || offsets[1]==0) { 202 break; 203 } 204 date += offsets[1]; 205 if (floorDivide(date, MILLIS_PER_DAY) == day) { 206 break; 207 } 208 } 209 } 210 211 223 static long floorDivide(long numerator, long denominator) { 224 return (numerator >= 0) ? 227 numerator / denominator : 228 ((numerator + 1) / denominator) - 1; 229 } 230 231 247 static int floorDivide(long numerator, int denominator, int[] remainder) { 248 if (numerator >= 0) { 249 remainder[0] = (int)(numerator % denominator); 250 return (int)(numerator / denominator); 251 } 252 int quotient = (int)(((numerator + 1) / denominator) - 1); 253 remainder[0] = (int)(numerator - (quotient * denominator)); 254 return quotient; 255 } 256 257 263 static void computeGregorianFields(long day, int fields[]) { 264 int year, month, dayOfMonth, dayOfYear; 265 266 day += (2440588 - 1721426); 270 271 int[] rem = new int[1]; 276 int n400 = floorDivide(day, 146097, rem); int n100 = floorDivide(rem[0], 36524, rem); int n4 = floorDivide(rem[0], 1461, rem); int n1 = floorDivide(rem[0], 365, rem); 280 year = 400*n400 + 100*n100 + 4*n4 + n1; 281 dayOfYear = rem[0]; if (n100 == 4 || n1 == 4) { 283 dayOfYear = 365; } else { 285 ++year; 286 } 287 288 boolean isLeap = ((year&0x3) == 0) && (year%100 != 0 || year%400 == 0); 290 291 int correction = 0; 292 int march1 = isLeap ? 60 : 59; if (dayOfYear >= march1) correction = isLeap ? 1 : 2; 294 month = (12 * (dayOfYear + correction) + 6) / 367; dayOfMonth = dayOfYear - 296 GREGORIAN_MONTH_COUNT[month][isLeap?1:0] + 1; 298 int dayOfWeek = (int) ((day + Calendar.MONDAY) % 7); 300 if (dayOfWeek < Calendar.SUNDAY) { 301 dayOfWeek += 7; 302 } 303 304 fields[0] = year; 305 fields[1] = month; fields[2] = dayOfMonth; fields[3] = dayOfWeek; } 310 311 312 317 protected static final int MILLIS_PER_HOUR = 60*60*1000; 318 319 324 protected static final int MILLIS_PER_DAY = 24*MILLIS_PER_HOUR; 325 326 333 static final int[][] GREGORIAN_MONTH_COUNT = { 334 { 0, 0 }, { 31, 31 }, { 59, 60 }, { 90, 91 }, { 120, 121 }, { 151, 152 }, { 181, 182 }, { 212, 213 }, { 243, 244 }, { 273, 274 }, { 304, 305 }, { 334, 335 } }; 347 348 354 abstract public void setRawOffset(int offsetMillis); 355 356 362 abstract public int getRawOffset(); 363 364 369 public String getID() { 370 return ID; 371 } 372 373 379 public void setID(String ID) { 380 if (ID == null) { 381 throw new NullPointerException (); 382 } 383 this.ID = ID; 384 } 385 386 395 public final String getDisplayName() { 396 return _getDisplayName(false, LONG_GENERIC, ULocale.getDefault()); 397 } 398 399 410 public final String getDisplayName(Locale locale) { 411 return _getDisplayName(false, LONG_GENERIC, ULocale.forLocale(locale)); 412 } 413 414 426 public final String getDisplayName(ULocale locale) { 427 return _getDisplayName(false, LONG_GENERIC, locale); 428 } 429 430 441 public final String getDisplayName(boolean daylight, int style) { 442 return getDisplayName(daylight, style, ULocale.getDefault()); 443 } 444 445 459 public String getDisplayName(boolean daylight, int style, Locale locale) { 460 return getDisplayName(daylight, style, ULocale.forLocale(locale)); 461 } 462 463 478 public String getDisplayName(boolean daylight, int style, ULocale locale) { 479 if (style != SHORT && style != LONG) { 480 throw new IllegalArgumentException ("Illegal style: " + style); 481 } 482 return _getDisplayName(daylight, style, locale); 483 } 484 485 491 private String _getDisplayName(boolean daylight, int style, ULocale locale) { 492 502 503 SoftReference data = (SoftReference )cachedLocaleData.get(locale); 506 SimpleDateFormat format; 507 if (data == null || 508 (format = (SimpleDateFormat)data.get()) == null) { 509 format = new SimpleDateFormat(null, locale); 510 cachedLocaleData.put(locale, new SoftReference (format)); 511 } 512 SimpleTimeZone tz; 517 if (daylight && useDaylightTime()) { 518 int savings = getDSTSavings(); 519 tz = new SimpleTimeZone(getRawOffset(), getID(), 520 Calendar.JANUARY, 1, 0, 0, 521 Calendar.FEBRUARY, 1, 0, 0, 522 savings); 523 } else { 524 tz = new SimpleTimeZone(getRawOffset(), getID()); 525 } 526 String [] patterns = { "z", "zzzz", "v", "vvvv" }; 527 format.applyPattern(patterns[style]); 528 format.setTimeZone(tz); 529 return format.format(new Date (864000000L)); 532 } 533 534 549 public int getDSTSavings() { 550 if (useDaylightTime()) { 551 return 3600000; 552 } 553 return 0; 554 } 555 556 562 abstract public boolean useDaylightTime(); 563 564 572 abstract public boolean inDaylightTime(Date date); 573 574 586 public static synchronized TimeZone getTimeZone(String ID) { 587 595 if(ID==null){ 596 throw new NullPointerException (); 597 } 598 TimeZone result = ZoneMeta.getSystemTimeZone(ID); 599 600 if (result == null) { 601 result = ZoneMeta.getCustomTimeZone(ID); 602 } 603 if (result == null) { 604 result = ZoneMeta.getGMT(); 605 } 606 return result; 607 } 608 609 619 public static String [] getAvailableIDs(int rawOffset) { 620 return ZoneMeta.getAvailableIDs(rawOffset); 621 622 } 623 624 625 636 public static String [] getAvailableIDs(String country) { 637 return ZoneMeta.getAvailableIDs(country); 638 } 639 640 648 public static String [] getAvailableIDs() { 649 return ZoneMeta.getAvailableIDs(); 650 } 651 652 666 public static int countEquivalentIDs(String id) { 667 return ZoneMeta.countEquivalentIDs(id); 668 } 669 670 689 public static String getEquivalentID(String id, int index) { 690 return ZoneMeta.getEquivalentID(id, index); 691 } 692 693 700 public static synchronized TimeZone getDefault() { 701 if (defaultZone == null) { 702 java.util.TimeZone temp=java.util.TimeZone.getDefault(); 703 defaultZone = getTimeZone(temp.getID()); 704 } 705 return (TimeZone) defaultZone.clone(); 706 } 707 708 716 public static synchronized void setDefault(TimeZone tz) { 717 718 defaultZone = tz; 719 java.util.TimeZone jdkZone = null; 722 if (tz != null) { 723 jdkZone = TimeZoneAdapter.wrap(tz); 724 } 725 java.util.TimeZone.setDefault(jdkZone); 726 } 727 728 737 public boolean hasSameRules(TimeZone other) { 738 return other != null && 739 getRawOffset() == other.getRawOffset() && 740 useDaylightTime() == other.useDaylightTime(); 741 } 742 743 747 public Object clone() { 748 try { 749 TimeZone other = (TimeZone) super.clone(); 750 other.ID = ID; 751 return other; 752 } catch (CloneNotSupportedException e) { 753 throw new IllegalStateException (); 754 } 755 } 756 757 764 public boolean equals(Object obj){ 765 if (this == obj) return true; 766 if (obj == null || getClass() != obj.getClass()) return false; 767 return (ID.equals(((TimeZone)obj).ID)); 768 } 769 770 776 public int hashCode(){ 777 return ID.hashCode(); 778 } 779 780 782 790 private String ID; 791 792 795 private static TimeZone defaultZone = null; 796 797 } 798 799 | Popular Tags |