// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2007-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.util;

import java.util.BitSet;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import com.ibm.icu.impl.Grego;

/**
 * {@icu} BasicTimeZone extends <code>TimeZone</code> with additional methods to access
 * time zone transitions and rules.  All ICU <code>TimeZone</code> concrete subclasses
 * extend this class. APIs added to <code>java.util.TimeZone</code> by
 * <code>BasicTimeZone</code> are annotated with <strong>'<font
 * style="color:red">[icu]</font>'</strong>.
 *
 * @see com.ibm.icu.util.TimeZoneRule
 * @see com.ibm.icu.util.TimeZoneTransition
 *
 * @stable ICU 3.8
 */
public abstract class BasicTimeZone extends TimeZone {

    private static final long serialVersionUID = -3204278532246180932L;

    private static final long MILLIS_PER_YEAR = 365*24*60*60*1000L;

    /**
     * {@icu} Returns the first time zone transition after the base time.
     * <p>Example code:{@.jcite com.ibm.icu.samples.util.timezone.BasicTimeZoneExample:---getNextTransitionExample}
     *
     * @param base      The base time.
     * @param inclusive Whether the base time is inclusive or not.
     *
     * @return  A <code>Date</code> holding the first time zone transition time
     *          after the given base time, or null if no time zone transitions
     *          are available after the base time.
     *
     * @stable ICU 3.8
     */
    public abstract TimeZoneTransition getNextTransition(long base, boolean inclusive);

    /**
     * {@icu} Returns the last time zone transition before the base time.
     * <p>Example code:{@.jcite com.ibm.icu.samples.util.timezone.BasicTimeZoneExample:---getPreviousTransitionExample}
     *
     * @param base      The base time.
     * @param inclusive Whether the base time is inclusive or not.
     *
     * @return  A <code>Date</code> holding the last time zone transition time
     *          before the given base time, or null if no time zone transitions
     *          are available before the base time.
     *
     * @stable ICU 3.8
     */
    public abstract TimeZoneTransition getPreviousTransition(long base, boolean inclusive);

    /**
     * {@icu} Checks if the time zone has equivalent transitions in the time range.
     * This method returns true when all of transition times, from/to standard
     * offsets and DST savings used by this time zone match the other in the
     * time range.
     * <p>Example code:{@.jcite com.ibm.icu.samples.util.timezone.BasicTimeZoneExample:---hasEquivalentTransitionsExample}
     *
     * @param tz    The instance of <code>TimeZone</code>
     * @param start The start time of the evaluated time range (inclusive)
     * @param end   The end time of the evaluated time range (inclusive)
     *
     * @return true if the other time zone has the equivalent transitions in the
     * time range.  When tz is not a <code>BasicTimeZone</code>, this method
     * returns false.
     *
     * @stable ICU 3.8
     */
    public boolean hasEquivalentTransitions(TimeZone tz, long start, long end) {
        return hasEquivalentTransitions(tz, start, end, false);
    }

    /**
     * {@icu} Checks if the time zone has equivalent transitions in the time range.
     * This method returns true when all of transition times, from/to standard
     * offsets and DST savings used by this time zone match the other in the
     * time range.
     *
     * @param tz    The instance of <code>TimeZone</code>
     * @param start The start time of the evaluated time range (inclusive)
     * @param end   The end time of the evaluated time range (inclusive)
     * @param ignoreDstAmount When true, any transitions with only daylight saving amount
     * changes will be ignored, except either of them is zero. For example, a transition
     * from rawoffset 3:00/dstsavings 1:00 to rawoffset 2:00/dstsavings 2:00 is excluded
     * from the comparison, but a transtion from rawoffset 2:00/dstsavings 1:00 to
     * rawoffset 3:00/dstsavings 0:00 is included.
     *
     * @return true if the other time zone has the equivalent transitions in the
     * time range.  When tz is not a <code>BasicTimeZone</code>, this method
     * returns false.
     *
     * @stable ICU 3.8
     */
    public boolean hasEquivalentTransitions(TimeZone tz, long start, long end,
                                            boolean ignoreDstAmount) {
        if (this == tz) {
            return true;
        }

        if (!(tz instanceof BasicTimeZone)) {
            return false;
        }

        // Check the offsets at the start time
        int[] offsets1 = new int[2];
        int[] offsets2 = new int[2];

        getOffset(start, false, offsets1);
        tz.getOffset(start, false, offsets2);

        if (ignoreDstAmount) {
            if ((offsets1[0] + offsets1[1] != offsets2[0] + offsets2[1])
                || (offsets1[1] != 0 && offsets2[1] == 0)
                || (offsets1[1] == 0 && offsets2[1] != 0)) {
                return false;
            }
        } else {
            if (offsets1[0] != offsets2[0] || offsets1[1] != offsets2[1]) {
                return false;
            }
        }

        // Check transitions in the range
        long time = start;
        while (true) {
            TimeZoneTransition tr1 = getNextTransition(time, false);
            TimeZoneTransition tr2 = ((BasicTimeZone)tz).getNextTransition(time, false);

            if (ignoreDstAmount) {
                // Skip a transition which only differ the amount of DST savings
                while (true) {
                    if (tr1 != null
                            && tr1.getTime() <= end
                            && (tr1.getFrom().getRawOffset() + tr1.getFrom().getDSTSavings()
                                    == tr1.getTo().getRawOffset() + tr1.getTo().getDSTSavings())
                            && (tr1.getFrom().getDSTSavings() != 0 && tr1.getTo().getDSTSavings() != 0)) {
                        tr1 = getNextTransition(tr1.getTime(), false);
                    } else {
                        break;
                    }
                }
                while (true) {
                    if (tr2 != null
                            && tr2.getTime() <= end
                            && (tr2.getFrom().getRawOffset() + tr2.getFrom().getDSTSavings()
                                    == tr2.getTo().getRawOffset() + tr2.getTo().getDSTSavings())
                            && (tr2.getFrom().getDSTSavings() != 0 && tr2.getTo().getDSTSavings() != 0)) {
                        tr2 = ((BasicTimeZone)tz).getNextTransition(tr2.getTime(), false);
                    } else {
                        break;
                    }
                }
            }

            boolean inRange1 = false;
            boolean inRange2 = false;
            if (tr1 != null) {
                if (tr1.getTime() <= end) {
                    inRange1 = true;
                }
            }
            if (tr2 != null) {
                if (tr2.getTime() <= end) {
                    inRange2 = true;
                }
            }
            if (!inRange1 && !inRange2) {
                // No more transition in the range
                break;
            }
            if (!inRange1 || !inRange2) {
                return false;
            }
            if (tr1.getTime() != tr2.getTime()) {
                return false;
            }
            if (ignoreDstAmount) {
                if (tr1.getTo().getRawOffset() + tr1.getTo().getDSTSavings()
                            != tr2.getTo().getRawOffset() + tr2.getTo().getDSTSavings()
                        || tr1.getTo().getDSTSavings() != 0 &&  tr2.getTo().getDSTSavings() == 0
                        || tr1.getTo().getDSTSavings() == 0 &&  tr2.getTo().getDSTSavings() != 0) {
                    return false;
                }
            } else {
                if (tr1.getTo().getRawOffset() != tr2.getTo().getRawOffset() ||
                    tr1.getTo().getDSTSavings() != tr2.getTo().getDSTSavings()) {
                    return false;
                }
            }
            time = tr1.getTime();
        }
        return true;
    }

    /**
     * {@icu} Returns the array of <code>TimeZoneRule</code> which represents the rule
     * of this time zone object.  The first element in the result array will
     * be the <code>InitialTimeZoneRule</code> instance for the initial rule.
     * The rest will be either <code>AnnualTimeZoneRule</code> or
     * <code>TimeArrayTimeZoneRule</code> instances representing transitions.
     *
     * @return  The array of <code>TimeZoneRule</code> which represents this
     *          time zone.
     *
     * @stable ICU 3.8
     */
    public abstract TimeZoneRule[] getTimeZoneRules();

    /**
     * {@icu} Returns the array of <code>TimeZoneRule</code> which represents the rule
     * of this time zone object since the specified start time.  The first
     * element in the result array will be the <code>InitialTimeZoneRule</code>
     * instance for the initial rule.  The rest will be either
     * <code>AnnualTimeZoneRule</code> or <code>TimeArrayTimeZoneRule</code>
     * instances representing transitions.
     * <p>Example code:{@.jcite com.ibm.icu.samples.util.timezone.BasicTimeZoneExample:---getTimeZoneRulesExample}
     *
     * @param start The start time (inclusive).
     * @return  The array of <code>TimeZoneRule</code> which represents this
     *          time zone since the start time.
     *
     * @stable ICU 3.8
     */
    public TimeZoneRule[] getTimeZoneRules(long start) {
        TimeZoneRule[] all = getTimeZoneRules();
        TimeZoneTransition tzt = getPreviousTransition(start, true);
        if (tzt == null) {
            // No need to filter out rules only applicable to time before the start
            return all;
        }

        BitSet isProcessed = new BitSet(all.length);
        List<TimeZoneRule> filteredRules = new LinkedList<>();

        // Create initial rule
        TimeZoneRule initial = new InitialTimeZoneRule(tzt.getTo().getName(),
                tzt.getTo().getRawOffset(), tzt.getTo().getDSTSavings());
        filteredRules.add(initial);
        isProcessed.set(0);

        // Mark rules which does not need to be processed
        for (int i = 1; i < all.length; i++) {
            Date d = all[i].getNextStart(start, initial.getRawOffset(),
                    initial.getDSTSavings(), false);
            if (d == null) {
                isProcessed.set(i);
            }
        }

        long time = start;
        boolean bFinalStd = false, bFinalDst = false;
        while(!bFinalStd || !bFinalDst) {
            tzt = getNextTransition(time, false);
            if (tzt == null) {
                break;
            }
            time = tzt.getTime();

            TimeZoneRule toRule = tzt.getTo();
            int ruleIdx = 1;
            for (; ruleIdx < all.length; ruleIdx++) {
                if (all[ruleIdx].equals(toRule)) {
                    break;
                }
            }
            if (ruleIdx >= all.length) {
                throw new IllegalStateException("The rule was not found");
            }
            if (isProcessed.get(ruleIdx)) {
                continue;
            }
            if (toRule instanceof TimeArrayTimeZoneRule) {
                TimeArrayTimeZoneRule tar = (TimeArrayTimeZoneRule)toRule;

                // Get the previous raw offset and DST savings before the very first start time
                long t = start;
                while(true) {
                    tzt = getNextTransition(t, false);
                    if (tzt == null) {
                        break;
                    }
                    if (tzt.getTo().equals(tar)) {
                        break;
                    }
                    t = tzt.getTime();
                }
                if (tzt != null) {
                    // Check if the entire start times to be added
                    Date firstStart = tar.getFirstStart(tzt.getFrom().getRawOffset(),
                            tzt.getFrom().getDSTSavings());
                    if (firstStart.getTime() > start) {
                        // Just add the rule as is
                        filteredRules.add(tar);
                    } else {
                        // Collect transitions after the start time
                        long[] times = tar.getStartTimes();
                        int timeType = tar.getTimeType();
                        int idx;
                        for (idx = 0; idx < times.length; idx++) {
                            t = times[idx];
                            if (timeType == DateTimeRule.STANDARD_TIME) {
                                t -= tzt.getFrom().getRawOffset();
                            }
                            if (timeType == DateTimeRule.WALL_TIME) {
                                t -= tzt.getFrom().getDSTSavings();
                            }
                            if (t > start) {
                                break;
                            }
                        }
                        int asize = times.length - idx;
                        if (asize > 0) {
                            long[] newtimes = new long[asize];
                            System.arraycopy(times, idx, newtimes, 0, asize);
                            TimeArrayTimeZoneRule newtar = new TimeArrayTimeZoneRule(
                                    tar.getName(), tar.getRawOffset(), tar.getDSTSavings(),
                                    newtimes, tar.getTimeType());
                            filteredRules.add(newtar);
                        }
                    }
                }
            } else if (toRule instanceof AnnualTimeZoneRule) {
                AnnualTimeZoneRule ar = (AnnualTimeZoneRule)toRule;
                Date firstStart = ar.getFirstStart(tzt.getFrom().getRawOffset(),
                        tzt.getFrom().getDSTSavings());
                if (firstStart.getTime() == tzt.getTime()) {
                    // Just add the rule as is
                    filteredRules.add(ar);
                } else {
                    // Calculate the transition year
                    int[] dfields = new int[6];
                    Grego.timeToFields(tzt.getTime(), dfields);
                    // Recreate the rule
                    AnnualTimeZoneRule newar = new AnnualTimeZoneRule(ar.getName(),
                            ar.getRawOffset(), ar.getDSTSavings(),
                            ar.getRule(), dfields[0], ar.getEndYear());
                    filteredRules.add(newar);
                }
                // Check if this is a final rule
                if (ar.getEndYear() == AnnualTimeZoneRule.MAX_YEAR) {
                    // After both final standard and dst rule are processed,
                    // exit this while loop.
                    if (ar.getDSTSavings() == 0) {
                        bFinalStd = true;
                    } else {
                        bFinalDst = true;
                    }
                }
            }
            isProcessed.set(ruleIdx);
        }
        TimeZoneRule[] rules = filteredRules.toArray(new TimeZoneRule[filteredRules.size()]);
        return rules;
    }

    /**
     * {@icu} Returns the array of <code>TimeZoneRule</code> which represents the rule of
     * this time zone object near the specified date.  Some applications are not
     * capable to handle historic time zone rule changes.  Also some applications
     * can only handle certain type of rule definitions.  This method returns
     * either a single <code>InitialTimeZoneRule</code> if this time zone does not
     * have any daylight saving time within 1 year from the specified time, or a
     * pair of <code>AnnualTimeZoneRule</code> whose rule type is
     * <code>DateTimeRule.DOW</code> for date and <code>DateTimeRule.WALL_TIME</code>
     * for time with a single <code>InitialTimeZoneRule</code> representing the
     * initial time, when this time zone observes daylight saving time near the
     * specified date.  Thus, the result may be only valid for dates around the
     * specified date.
     *
     * @param date The date to be used for <code>TimeZoneRule</code> extraction.
     * @return The array of <code>TimeZoneRule</code>, either a single
     * <code>InitialTimeZoneRule</code> object, or a pair of <code>AnnualTimeZoneRule</code>
     * with a single <code>InitialTimeZoneRule</code>.  The first element in the
     * array is always a <code>InitialTimeZoneRule</code>.
     *
     * @stable ICU 3.8
     */
    public TimeZoneRule[] getSimpleTimeZoneRulesNear(long date) {
        AnnualTimeZoneRule[] annualRules = null;
        TimeZoneRule initialRule = null;
        // Get the next transition
        TimeZoneTransition tr = getNextTransition(date, false);
        if (tr != null) {
            String initialName = tr.getFrom().getName();
            int initialRaw = tr.getFrom().getRawOffset();
            int initialDst = tr.getFrom().getDSTSavings();

            // Check if the next transition is either DST->STD or STD->DST and
            // within roughly 1 year from the specified date
            long nextTransitionTime = tr.getTime();
            if (((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0)
                    || (tr.getFrom().getDSTSavings() != 0 && tr.getTo().getDSTSavings() == 0))
                        && date + MILLIS_PER_YEAR > nextTransitionTime) {
                annualRules = new AnnualTimeZoneRule[2];
                // Get local wall time for the transition time
                int dtfields[] = Grego.timeToFields(nextTransitionTime
                        + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(), null);
                int weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]);
                // Create DOW rule
                DateTimeRule dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3],
                        dtfields[5], DateTimeRule.WALL_TIME);

                AnnualTimeZoneRule secondRule = null;

                // Note:  SimpleTimeZone does not support raw offset change.
                // So we always use raw offset of the given time for the rule,
                // even raw offset is changed.  This will result that the result
                // zone to return wrong offset after the transition.
                // When we encounter such case, we do not inspect next next
                // transition for another rule.
                annualRules[0] = new AnnualTimeZoneRule(tr.getTo().getName(),
                        initialRaw, tr.getTo().getDSTSavings(),
                        dtr, dtfields[0], AnnualTimeZoneRule.MAX_YEAR);

                if (tr.getTo().getRawOffset() == initialRaw) {

                    // Get the next next transition
                    tr = getNextTransition(nextTransitionTime, false);
                    if (tr != null) {
                        // Check if the next next transition is either DST->STD or STD->DST
                        // and within roughly 1 year from the next transition
                        if (((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0)
                                || (tr.getFrom().getDSTSavings() != 0
                                    && tr.getTo().getDSTSavings() == 0))
                            && nextTransitionTime + MILLIS_PER_YEAR > tr.getTime()) {
                            // Generate another DOW rule
                            dtfields = Grego.timeToFields(tr.getTime()
                                    + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(),
                                                          dtfields);
                            weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1],
                                                                    dtfields[2]);
                            dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3],
                                                   dtfields[5], DateTimeRule.WALL_TIME);
                            secondRule = new AnnualTimeZoneRule(tr.getTo().getName(),
                                    tr.getTo().getRawOffset(), tr.getTo().getDSTSavings(),
                                    dtr, dtfields[0] - 1, AnnualTimeZoneRule.MAX_YEAR);
                            // Make sure this rule can be applied to the specified date
                            Date d = secondRule.getPreviousStart(date, tr.getFrom().getRawOffset(),
                                    tr.getFrom().getDSTSavings(), true);
                            if (d != null && d.getTime() <= date
                                    && initialRaw == tr.getTo().getRawOffset()
                                    && initialDst == tr.getTo().getDSTSavings()) {
                                // We can use this rule as the second transition rule
                                annualRules[1] = secondRule;
                            }
                        }
                    }
                }

                if (annualRules[1] == null) {
                    // Try previous transition
                    tr = getPreviousTransition(date, true);
                    if (tr != null) {
                        // Check if the previous transition is either DST->STD or STD->DST.
                        // The actual transition time does not matter here.
                        if ((tr.getFrom().getDSTSavings() == 0 && tr.getTo().getDSTSavings() != 0)
                                || (tr.getFrom().getDSTSavings() != 0
                                    && tr.getTo().getDSTSavings() == 0)) {
                            // Generate another DOW rule
                            dtfields = Grego.timeToFields(tr.getTime()
                                    + tr.getFrom().getRawOffset() + tr.getFrom().getDSTSavings(),
                                                          dtfields);
                            weekInMonth = Grego.getDayOfWeekInMonth(dtfields[0], dtfields[1],
                                                                    dtfields[2]);
                            dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3],
                                                   dtfields[5], DateTimeRule.WALL_TIME);

                            // second rule raw/dst offsets should match raw/dst offsets
                            // at the given time
                            secondRule = new AnnualTimeZoneRule(
                                tr.getTo().getName(), initialRaw, initialDst, dtr,
                                annualRules[0].getStartYear() - 1, AnnualTimeZoneRule.MAX_YEAR);

                            // Check if this rule start after the first rule after the
                            // specified date
                            Date d = secondRule.getNextStart(date, tr.getFrom().getRawOffset(),
                                                             tr.getFrom().getDSTSavings(), false);
                            if (d.getTime() > nextTransitionTime) {
                                // We can use this rule as the second transition rule
                                annualRules[1] = secondRule;
                            }
                        }
                    }
                }
                if (annualRules[1] == null) {
                    // Cannot generate a good pair of AnnualTimeZoneRule
                    annualRules = null;
                } else {
                    // The initial rule should represent the rule before the previous transition
                    initialName = annualRules[0].getName();
                    initialRaw = annualRules[0].getRawOffset();
                    initialDst = annualRules[0].getDSTSavings();
                }
            }
            initialRule = new InitialTimeZoneRule(initialName, initialRaw, initialDst);
        } else {
            // Try the previous one
            tr = getPreviousTransition(date, true);
            if (tr != null) {
                initialRule = new InitialTimeZoneRule(tr.getTo().getName(),
                        tr.getTo().getRawOffset(), tr.getTo().getDSTSavings());
            } else {
                // No transitions in the past.  Just use the current offsets
                int[] offsets = new int[2];
                getOffset(date, false, offsets);
                initialRule = new InitialTimeZoneRule(getID(), offsets[0], offsets[1]);
            }
        }

        TimeZoneRule[] result = null;
        if (annualRules == null) {
            result = new TimeZoneRule[1];
            result[0] = initialRule;
        } else {
            result = new TimeZoneRule[3];
            result[0] = initialRule;
            result[1] = annualRules[0];
            result[2] = annualRules[1];
        }

        return result;
    }

    /**
     * {@icu} Options used by {@link #getOffsetFromLocal(long, LocalOption, LocalOption, int[])}
     * to specify how to interpret an input time when it does not exist, or when it is ambiguous,
     * around a time zone transition.
     *
     * @draft ICU 69
     */
    public static enum LocalOption {
        /**
         * An input time is always interpreted as local time before
         * a time zone transition.
         * @draft ICU 69
         */
        FORMER(0x04),
        /**
         * An input time is always interpreted as local time after
         * a time zone transition.
         * @draft ICU 69
         */
        LATTER(0x0C),
        /**
         * An input time is interpreted as standard time when local
         * time is switched to/from daylight saving time. When both
         * sides of a time zone transition are standard time,
         * or daylight saving time, the local time before the
         * transition is used.
         * @draft ICU 69
         */
        STANDARD_FORMER(0x05),
        /**
         * An input time is interpreted as standard time when local
         * time is switched to/from daylight saving time. When both
         * sides of a time zone transition are standard time,
         * or daylight saving time, the local time after the
         * transition is used.
         * @draft ICU 69
         */
        STANDARD_LATTER(0x0D),
        /**
         * An input time is interpreted as daylight saving time when
         * local time is switched to/from standard time. When both
         * sides of a time zone transition are standard time,
         * or daylight saving time, the local time before the
         * transition is used.
         * @draft ICU 69
         */
        DAYLIGHT_FORMER(0x07),
        /**
         * An input time is interpreted as daylight saving time when
         * local time is switched to/from standard time. When both
         * sides of a time zone transition are standard time,
         * or daylight saving time, the local time after the
         * transition is used.
         * @draft ICU 69
         */
        DAYLIGHT_LATTER(0x0F);

        private int flagVal;

        LocalOption(int flagVal) {
            this.flagVal = flagVal;
        }
    }

    /**
     * Get {@link LocalOption}'s internal flag value. This is used by ICU internal
     * implementation only.
     * @param locOpt    A LocalOption
     * @return LocalOption's internal flag value.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static int getLocalOptionValue(LocalOption locOpt) {
        return locOpt.flagVal;
    }

    /**
     * The time type option for standard time used by internal implementation.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static final int LOCAL_STD = 0x01;

    /**
     * The time type option for daylight saving time used internally.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static final int LOCAL_DST = 0x03;

    /**
     * The option designate former time used by internal implementation.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static final int LOCAL_FORMER = 0x04;

    /**
     * The option designate latter time used by internal implementation.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static final int LOCAL_LATTER = 0x0C;

    /**
     * The bit mask for the time type option used by internal implementation.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static final int STD_DST_MASK = 0x03;

    /**
     * The bit mask for the former/latter option used by internal implementation.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected static final int FORMER_LATTER_MASK = 0x0C;

    /**
     * {@icu} Returns time zone offsets from local wall time.
     * @draft ICU 69
     */
    public void getOffsetFromLocal(long date,
            LocalOption nonExistingTimeOpt, LocalOption duplicatedTimeOpt, int[] offsets) {
        throw new IllegalStateException("Not implemented");
    }

    /**
     * Protected no arg constructor.
     * @stable ICU 3.8
     */
    protected BasicTimeZone() {
    }

    /**
     * Constructing a BasicTimeZone with the given time zone ID.
     * @param ID the time zone ID.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected BasicTimeZone(String ID) {
        super(ID);
    }
}
