1/* GENERATED SOURCE. DO NOT MODIFY. */ 2/* 3 ******************************************************************************* 4 * Copyright (C) 2007-2014, International Business Machines Corporation and * 5 * others. All Rights Reserved. * 6 ******************************************************************************* 7 */ 8package android.icu.util; 9 10import java.util.BitSet; 11import java.util.Date; 12import java.util.LinkedList; 13import java.util.List; 14 15import android.icu.impl.Grego; 16 17/** 18 * <strong>[icu]</strong> BasicTimeZone extends <code>TimeZone</code> with additional methods to access 19 * time zone transitions and rules. All ICU <code>TimeZone</code> concrete subclasses 20 * extend this class. APIs added to <code>java.util.TimeZone</code> by 21 * <code>BasicTimeZone</code> are annotated with <strong>'<font 22 * style="color:red">[icu]</font>'</strong>. 23 * 24 * @see android.icu.util.TimeZoneRule 25 * @see android.icu.util.TimeZoneTransition 26 * 27 * @hide Only a subset of ICU is exposed in Android 28 */ 29public abstract class BasicTimeZone extends TimeZone { 30 31 private static final long serialVersionUID = -3204278532246180932L; 32 33 private static final long MILLIS_PER_YEAR = 365*24*60*60*1000L; 34 35 /** 36 * <strong>[icu]</strong> Returns the first time zone transition after the base time. 37 * <p>Example code:{{@literal @}.jcite android.icu.samples.util.timezone.BasicTimeZoneExample:---getNextTransitionExample} 38 * 39 * @param base The base time. 40 * @param inclusive Whether the base time is inclusive or not. 41 * 42 * @return A <code>Date</code> holding the first time zone transition time 43 * after the given base time, or null if no time zone transitions 44 * are available after the base time. 45 */ 46 public abstract TimeZoneTransition getNextTransition(long base, boolean inclusive); 47 48 /** 49 * <strong>[icu]</strong> Returns the last time zone transition before the base time. 50 * <p>Example code:{{@literal @}.jcite android.icu.samples.util.timezone.BasicTimeZoneExample:---getPreviousTransitionExample} 51 * 52 * @param base The base time. 53 * @param inclusive Whether the base time is inclusive or not. 54 * 55 * @return A <code>Date</code> holding the last time zone transition time 56 * before the given base time, or null if no time zone transitions 57 * are available before the base time. 58 */ 59 public abstract TimeZoneTransition getPreviousTransition(long base, boolean inclusive); 60 61 /** 62 * <strong>[icu]</strong> Checks if the time zone has equivalent transitions in the time range. 63 * This method returns true when all of transition times, from/to standard 64 * offsets and DST savings used by this time zone match the other in the 65 * time range. 66 * <p>Example code:{{@literal @}.jcite android.icu.samples.util.timezone.BasicTimeZoneExample:---hasEquivalentTransitionsExample} 67 * 68 * @param tz The instance of <code>TimeZone</code> 69 * @param start The start time of the evaluated time range (inclusive) 70 * @param end The end time of the evaluated time range (inclusive) 71 * 72 * @return true if the other time zone has the equivalent transitions in the 73 * time range. When tz is not a <code>BasicTimeZone</code>, this method 74 * returns false. 75 */ 76 public boolean hasEquivalentTransitions(TimeZone tz, long start, long end) { 77 return hasEquivalentTransitions(tz, start, end, false); 78 } 79 80 /** 81 * <strong>[icu]</strong> Checks if the time zone has equivalent transitions in the time range. 82 * This method returns true when all of transition times, from/to standard 83 * offsets and DST savings used by this time zone match the other in the 84 * time range. 85 * 86 * @param tz The instance of <code>TimeZone</code> 87 * @param start The start time of the evaluated time range (inclusive) 88 * @param end The end time of the evaluated time range (inclusive) 89 * @param ignoreDstAmount When true, any transitions with only daylight saving amount 90 * changes will be ignored, except either of them is zero. For example, a transition 91 * from rawoffset 3:00/dstsavings 1:00 to rawoffset 2:00/dstsavings 2:00 is excluded 92 * from the comparison, but a transtion from rawoffset 2:00/dstsavings 1:00 to 93 * rawoffset 3:00/dstsavings 0:00 is included. 94 * 95 * @return true if the other time zone has the equivalent transitions in the 96 * time range. When tz is not a <code>BasicTimeZone</code>, this method 97 * returns false. 98 */ 99 public boolean hasEquivalentTransitions(TimeZone tz, long start, long end, 100 boolean ignoreDstAmount) { 101 if (this == tz) { 102 return true; 103 } 104 105 if (!(tz instanceof BasicTimeZone)) { 106 return false; 107 } 108 109 // Check the offsets at the start time 110 int[] offsets1 = new int[2]; 111 int[] offsets2 = new int[2]; 112 113 getOffset(start, false, offsets1); 114 tz.getOffset(start, false, offsets2); 115 116 if (ignoreDstAmount) { 117 if ((offsets1[0] + offsets1[1] != offsets2[0] + offsets2[1]) 118 || (offsets1[1] != 0 && offsets2[1] == 0) 119 || (offsets1[1] == 0 && offsets2[1] != 0)) { 120 return false; 121 } 122 } else { 123 if (offsets1[0] != offsets2[0] || offsets1[1] != offsets2[1]) { 124 return false; 125 } 126 } 127 128 // Check transitions in the range 129 long time = start; 130 while (true) { 131 TimeZoneTransition tr1 = getNextTransition(time, false); 132 TimeZoneTransition tr2 = ((BasicTimeZone)tz).getNextTransition(time, false); 133 134 if (ignoreDstAmount) { 135 // Skip a transition which only differ the amount of DST savings 136 while (true) { 137 if (tr1 != null 138 && tr1.getTime() <= end 139 && (tr1.getFrom().getRawOffset() + tr1.getFrom().getDSTSavings() 140 == tr1.getTo().getRawOffset() + tr1.getTo().getDSTSavings()) 141 && (tr1.getFrom().getDSTSavings() != 0 && tr1.getTo().getDSTSavings() != 0)) { 142 tr1 = getNextTransition(tr1.getTime(), false); 143 } else { 144 break; 145 } 146 } 147 while (true) { 148 if (tr2 != null 149 && tr2.getTime() <= end 150 && (tr2.getFrom().getRawOffset() + tr2.getFrom().getDSTSavings() 151 == tr2.getTo().getRawOffset() + tr2.getTo().getDSTSavings()) 152 && (tr2.getFrom().getDSTSavings() != 0 && tr2.getTo().getDSTSavings() != 0)) { 153 tr2 = ((BasicTimeZone)tz).getNextTransition(tr2.getTime(), false); 154 } else { 155 break; 156 } 157 } 158 } 159 160 boolean inRange1 = false; 161 boolean inRange2 = false; 162 if (tr1 != null) { 163 if (tr1.getTime() <= end) { 164 inRange1 = true; 165 } 166 } 167 if (tr2 != null) { 168 if (tr2.getTime() <= end) { 169 inRange2 = true; 170 } 171 } 172 if (!inRange1 && !inRange2) { 173 // No more transition in the range 174 break; 175 } 176 if (!inRange1 || !inRange2) { 177 return false; 178 } 179 if (tr1.getTime() != tr2.getTime()) { 180 return false; 181 } 182 if (ignoreDstAmount) { 183 if (tr1.getTo().getRawOffset() + tr1.getTo().getDSTSavings() 184 != tr2.getTo().getRawOffset() + tr2.getTo().getDSTSavings() 185 || tr1.getTo().getDSTSavings() != 0 && tr2.getTo().getDSTSavings() == 0 186 || tr1.getTo().getDSTSavings() == 0 && tr2.getTo().getDSTSavings() != 0) { 187 return false; 188 } 189 } else { 190 if (tr1.getTo().getRawOffset() != tr2.getTo().getRawOffset() || 191 tr1.getTo().getDSTSavings() != tr2.getTo().getDSTSavings()) { 192 return false; 193 } 194 } 195 time = tr1.getTime(); 196 } 197 return true; 198 } 199 200 /** 201 * <strong>[icu]</strong> Returns the array of <code>TimeZoneRule</code> which represents the rule 202 * of this time zone object. The first element in the result array will 203 * be the <code>InitialTimeZoneRule</code> instance for the initial rule. 204 * The rest will be either <code>AnnualTimeZoneRule</code> or 205 * <code>TimeArrayTimeZoneRule</code> instances representing transitions. 206 * 207 * @return The array of <code>TimeZoneRule</code> which represents this 208 * time zone. 209 */ 210 public abstract TimeZoneRule[] getTimeZoneRules(); 211 212 /** 213 * <strong>[icu]</strong> Returns the array of <code>TimeZoneRule</code> which represents the rule 214 * of this time zone object since the specified start time. The first 215 * element in the result array will be the <code>InitialTimeZoneRule</code> 216 * instance for the initial rule. The rest will be either 217 * <code>AnnualTimeZoneRule</code> or <code>TimeArrayTimeZoneRule</code> 218 * instances representing transitions. 219 * <p>Example code:{{@literal @}.jcite android.icu.samples.util.timezone.BasicTimeZoneExample:---getTimeZoneRulesExample} 220 * 221 * @param start The start time (inclusive). 222 * @return The array of <code>TimeZoneRule</code> which represents this 223 * time zone since the start time. 224 */ 225 public TimeZoneRule[] getTimeZoneRules(long start) { 226 TimeZoneRule[] all = getTimeZoneRules(); 227 TimeZoneTransition tzt = getPreviousTransition(start, true); 228 if (tzt == null) { 229 // No need to filter out rules only applicable to time before the start 230 return all; 231 } 232 233 BitSet isProcessed = new BitSet(all.length); 234 List<TimeZoneRule> filteredRules = new LinkedList<TimeZoneRule>(); 235 236 // Create initial rule 237 TimeZoneRule initial = new InitialTimeZoneRule(tzt.getTo().getName(), 238 tzt.getTo().getRawOffset(), tzt.getTo().getDSTSavings()); 239 filteredRules.add(initial); 240 isProcessed.set(0); 241 242 // Mark rules which does not need to be processed 243 for (int i = 1; i < all.length; i++) { 244 Date d = all[i].getNextStart(start, initial.getRawOffset(), 245 initial.getDSTSavings(), false); 246 if (d == null) { 247 isProcessed.set(i); 248 } 249 } 250 251 long time = start; 252 boolean bFinalStd = false, bFinalDst = false; 253 while(!bFinalStd || !bFinalDst) { 254 tzt = getNextTransition(time, false); 255 if (tzt == null) { 256 break; 257 } 258 time = tzt.getTime(); 259 260 TimeZoneRule toRule = tzt.getTo(); 261 int ruleIdx = 1; 262 for (; ruleIdx < all.length; ruleIdx++) { 263 if (all[ruleIdx].equals(toRule)) { 264 break; 265 } 266 } 267 if (ruleIdx >= all.length) { 268 throw new IllegalStateException("The rule was not found"); 269 } 270 if (isProcessed.get(ruleIdx)) { 271 continue; 272 } 273 if (toRule instanceof TimeArrayTimeZoneRule) { 274 TimeArrayTimeZoneRule tar = (TimeArrayTimeZoneRule)toRule; 275 276 // Get the previous raw offset and DST savings before the very first start time 277 long t = start; 278 while(true) { 279 tzt = getNextTransition(t, false); 280 if (tzt == null) { 281 break; 282 } 283 if (tzt.getTo().equals(tar)) { 284 break; 285 } 286 t = tzt.getTime(); 287 } 288 if (tzt != null) { 289 // Check if the entire start times to be added 290 Date firstStart = tar.getFirstStart(tzt.getFrom().getRawOffset(), 291 tzt.getFrom().getDSTSavings()); 292 if (firstStart.getTime() > start) { 293 // Just add the rule as is 294 filteredRules.add(tar); 295 } else { 296 // Collect transitions after the start time 297 long[] times = tar.getStartTimes(); 298 int timeType = tar.getTimeType(); 299 int idx; 300 for (idx = 0; idx < times.length; idx++) { 301 t = times[idx]; 302 if (timeType == DateTimeRule.STANDARD_TIME) { 303 t -= tzt.getFrom().getRawOffset(); 304 } 305 if (timeType == DateTimeRule.WALL_TIME) { 306 t -= tzt.getFrom().getDSTSavings(); 307 } 308 if (t > start) { 309 break; 310 } 311 } 312 int asize = times.length - idx; 313 if (asize > 0) { 314 long[] newtimes = new long[asize]; 315 System.arraycopy(times, idx, newtimes, 0, asize); 316 TimeArrayTimeZoneRule newtar = new TimeArrayTimeZoneRule( 317 tar.getName(), tar.getRawOffset(), tar.getDSTSavings(), 318 newtimes, tar.getTimeType()); 319 filteredRules.add(newtar); 320 } 321 } 322 } 323 } else if (toRule instanceof AnnualTimeZoneRule) { 324 AnnualTimeZoneRule ar = (AnnualTimeZoneRule)toRule; 325 Date firstStart = ar.getFirstStart(tzt.getFrom().getRawOffset(), 326 tzt.getFrom().getDSTSavings()); 327 if (firstStart.getTime() == tzt.getTime()) { 328 // Just add the rule as is 329 filteredRules.add(ar); 330 } else { 331 // Calculate the transition year 332 int[] dfields = new int[6]; 333 Grego.timeToFields(tzt.getTime(), dfields); 334 // Recreate the rule 335 AnnualTimeZoneRule newar = new AnnualTimeZoneRule(ar.getName(), 336 ar.getRawOffset(), ar.getDSTSavings(), 337 ar.getRule(), dfields[0], ar.getEndYear()); 338 filteredRules.add(newar); 339 } 340 // Check if this is a final rule 341 if (ar.getEndYear() == AnnualTimeZoneRule.MAX_YEAR) { 342 // After both final standard and dst rule are processed, 343 // exit this while loop. 344 if (ar.getDSTSavings() == 0) { 345 bFinalStd = true; 346 } else { 347 bFinalDst = true; 348 } 349 } 350 } 351 isProcessed.set(ruleIdx); 352 } 353 TimeZoneRule[] rules = filteredRules.toArray(new TimeZoneRule[filteredRules.size()]); 354 return rules; 355 } 356 357 /** 358 * <strong>[icu]</strong> Returns the array of <code>TimeZoneRule</code> which represents the rule of 359 * this time zone object near the specified date. Some applications are not 360 * capable to handle historic time zone rule changes. Also some applications 361 * can only handle certain type of rule definitions. This method returns 362 * either a single <code>InitialTimeZoneRule</code> if this time zone does not 363 * have any daylight saving time within 1 year from the specified time, or a 364 * pair of <code>AnnualTimeZoneRule</code> whose rule type is 365 * <code>DateTimeRule.DOW</code> for date and <code>DateTimeRule.WALL_TIME</code> 366 * for time with a single <code>InitialTimeZoneRule</code> representing the 367 * initial time, when this time zone observes daylight saving time near the 368 * specified date. Thus, the result may be only valid for dates around the 369 * specified date. 370 * 371 * @param date The date to be used for <code>TimeZoneRule</code> extraction. 372 * @return The array of <code>TimeZoneRule</code>, either a single 373 * <code>InitialTimeZoneRule</code> object, or a pair of <code>AnnualTimeZoneRule</code> 374 * with a single <code>InitialTimeZoneRule</code>. The first element in the 375 * array is always a <code>InitialTimeZoneRule</code>. 376 */ 377 public TimeZoneRule[] getSimpleTimeZoneRulesNear(long date) { 378 AnnualTimeZoneRule[] annualRules = null; 379 TimeZoneRule initialRule = null; 380 // Get the next transition 381 TimeZoneTransition tr = getNextTransition(date, false); 382 if (tr != null) { 383 String initialName = tr.getFrom().getName(); 384 int initialRaw = tr.getFrom().getRawOffset(); 385 int initialDst = tr.getFrom().getDSTSavings(); 386 387 // Check if the next transition is either DST->STD or STD->DST and 388 // within roughly 1 year from the specified date 389 long nextTransitionTime = tr.getTime(); 390 if (((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0) 391 || (tr.getFrom().getDSTSavings() != 0 && tr.getTo().getDSTSavings() == 0)) 392 && date + MILLIS_PER_YEAR > nextTransitionTime) { 393 annualRules = new AnnualTimeZoneRule[2]; 394 // Get local wall time for the transition time 395 int dtfields[] = Grego.timeToFields(nextTransitionTime 396 + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), null); 397 int weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]); 398 // Create DOW rule 399 DateTimeRule dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], 400 dtfields[5], DateTimeRule.WALL_TIME); 401 402 AnnualTimeZoneRule secondRule = null; 403 404 // Note: SimpleTimeZone does not support raw offset change. 405 // So we always use raw offset of the given time for the rule, 406 // even raw offset is changed. This will result that the result 407 // zone to return wrong offset after the transition. 408 // When we encounter such case, we do not inspect next next 409 // transition for another rule. 410 annualRules[0] = new AnnualTimeZoneRule(tr.getTo().getName(), 411 initialRaw, tr.getTo().getDSTSavings(), 412 dtr, dtfields[0], AnnualTimeZoneRule.MAX_YEAR); 413 414 if (tr.getTo().getRawOffset() == initialRaw) { 415 416 // Get the next next transition 417 tr = getNextTransition(nextTransitionTime, false); 418 if (tr != null) { 419 // Check if the next next transition is either DST->STD or STD->DST 420 // and within roughly 1 year from the next transition 421 if (((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0) 422 || (tr.getFrom().getDSTSavings() != 0 423 && tr.getTo().getDSTSavings() == 0)) 424 && nextTransitionTime + MILLIS_PER_YEAR > tr.getTime()) { 425 // Generate another DOW rule 426 dtfields = Grego.timeToFields(tr.getTime() 427 + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), 428 dtfields); 429 weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], 430 dtfields[2]); 431 dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], 432 dtfields[5], DateTimeRule.WALL_TIME); 433 secondRule = new AnnualTimeZoneRule(tr.getTo().getName(), 434 tr.getTo().getRawOffset(), tr.getTo().getDSTSavings(), 435 dtr, dtfields[0] - 1, AnnualTimeZoneRule.MAX_YEAR); 436 // Make sure this rule can be applied to the specified date 437 Date d = secondRule.getPreviousStart(date, tr.getFrom().getRawOffset(), 438 tr.getFrom().getDSTSavings(), true); 439 if (d != null && d.getTime() <= date 440 && initialRaw == tr.getTo().getRawOffset() 441 && initialDst == tr.getTo().getDSTSavings()) { 442 // We can use this rule as the second transition rule 443 annualRules[1] = secondRule; 444 } 445 } 446 } 447 } 448 449 if (annualRules[1] == null) { 450 // Try previous transition 451 tr = getPreviousTransition(date, true); 452 if (tr != null) { 453 // Check if the previous transition is either DST->STD or STD->DST. 454 // The actual transition time does not matter here. 455 if ((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0) 456 || (tr.getFrom().getDSTSavings() != 0 457 && tr.getTo().getDSTSavings() == 0)) { 458 // Generate another DOW rule 459 dtfields = Grego.timeToFields(tr.getTime() 460 + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), 461 dtfields); 462 weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], 463 dtfields[2]); 464 dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], 465 dtfields[5], DateTimeRule.WALL_TIME); 466 467 // second rule raw/dst offsets should match raw/dst offsets 468 // at the given time 469 secondRule = new AnnualTimeZoneRule( 470 tr.getTo().getName(), initialRaw, initialDst, dtr, 471 annualRules[0].getStartYear() - 1, AnnualTimeZoneRule.MAX_YEAR); 472 473 // Check if this rule start after the first rule after the 474 // specified date 475 Date d = secondRule.getNextStart(date, tr.getFrom().getRawOffset(), 476 tr.getFrom().getDSTSavings(), false); 477 if (d.getTime() > nextTransitionTime) { 478 // We can use this rule as the second transition rule 479 annualRules[1] = secondRule; 480 } 481 } 482 } 483 } 484 if (annualRules[1] == null) { 485 // Cannot generate a good pair of AnnualTimeZoneRule 486 annualRules = null; 487 } else { 488 // The initial rule should represent the rule before the previous transition 489 initialName = annualRules[0].getName(); 490 initialRaw = annualRules[0].getRawOffset(); 491 initialDst = annualRules[0].getDSTSavings(); 492 } 493 } 494 initialRule = new InitialTimeZoneRule(initialName, initialRaw, initialDst); 495 } else { 496 // Try the previous one 497 tr = getPreviousTransition(date, true); 498 if (tr != null) { 499 initialRule = new InitialTimeZoneRule(tr.getTo().getName(), 500 tr.getTo().getRawOffset(), tr.getTo().getDSTSavings()); 501 } else { 502 // No transitions in the past. Just use the current offsets 503 int[] offsets = new int[2]; 504 getOffset(date, false, offsets); 505 initialRule = new InitialTimeZoneRule(getID(), offsets[0], offsets[1]); 506 } 507 } 508 509 TimeZoneRule[] result = null; 510 if (annualRules == null) { 511 result = new TimeZoneRule[1]; 512 result[0] = initialRule; 513 } else { 514 result = new TimeZoneRule[3]; 515 result[0] = initialRule; 516 result[1] = annualRules[0]; 517 result[2] = annualRules[1]; 518 } 519 520 return result; 521 } 522 523 /** 524 * <strong>[icu]</strong> The time type option for standard time used by 525 * {@link #getOffsetFromLocal(long, int, int, int[])} 526 * @deprecated This API is ICU internal only. 527 * @hide draft / provisional / internal are hidden on Android 528 */ 529 @Deprecated 530 public static final int LOCAL_STD = 0x01; 531 532 /** 533 * <strong>[icu]</strong> The time type option for daylight saving time used by 534 * {@link #getOffsetFromLocal(long, int, int, int[])} 535 * @deprecated This API is ICU internal only. 536 * @hide draft / provisional / internal are hidden on Android 537 */ 538 @Deprecated 539 public static final int LOCAL_DST = 0x03; 540 541 /** 542 * <strong>[icu]</strong> The option designate former time to be used by 543 * {@link #getOffsetFromLocal(long, int, int, int[])} 544 * @deprecated This API is ICU internal only. 545 * @hide draft / provisional / internal are hidden on Android 546 */ 547 @Deprecated 548 public static final int LOCAL_FORMER = 0x04; 549 550 /** 551 * <strong>[icu]</strong> The option designate latter time to be used by 552 * {@link #getOffsetFromLocal(long, int, int, int[])} 553 * @deprecated This API is ICU internal only. 554 * @hide draft / provisional / internal are hidden on Android 555 */ 556 @Deprecated 557 public static final int LOCAL_LATTER = 0x0C; 558 559 /** 560 * <strong>[icu]</strong> The bit mask for the time type option used by 561 * {@link #getOffsetFromLocal(long, int, int, int[])} 562 * @deprecated This API is ICU internal only. 563 * @hide draft / provisional / internal are hidden on Android 564 */ 565 @Deprecated 566 protected static final int STD_DST_MASK = 0x03; 567 568 /** 569 * <strong>[icu]</strong> The bit mask for the former/latter option used by 570 * {@link #getOffsetFromLocal(long, int, int, int[])} 571 * @deprecated This API is ICU internal only. 572 * @hide draft / provisional / internal are hidden on Android 573 */ 574 @Deprecated 575 protected static final int FORMER_LATTER_MASK = 0x0C; 576 577 /** 578 * <strong>[icu]</strong> Returns time zone offsets from local wall time. 579 * @deprecated This API is ICU internal only. 580 * @hide draft / provisional / internal are hidden on Android 581 */ 582 @Deprecated 583 public void getOffsetFromLocal(long date, 584 int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) { 585 throw new IllegalStateException("Not implemented"); 586 } 587 588 /** 589 * Protected no arg constructor. 590 */ 591 protected BasicTimeZone() { 592 } 593 594 /** 595 * Constructing a BasicTimeZone with the given time zone ID. 596 * @param ID the time zone ID. 597 * @deprecated This API is ICU internal only. 598 * @hide draft / provisional / internal are hidden on Android 599 */ 600 @Deprecated 601 protected BasicTimeZone(String ID) { 602 super(ID); 603 } 604} 605