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