Search in sources :

Example 11 with InitialTimeZoneRule

use of android.icu.util.InitialTimeZoneRule in project j2objc by google.

the class TimeZoneRuleTest method TestSimpleTimeZoneCoverage.

/*
     * API coverage test for BasicTimeZone APIs in SimpleTimeZone
     */
@Test
public void TestSimpleTimeZoneCoverage() {
    long time1 = getUTCMillis(1990, Calendar.JUNE, 1);
    long time2 = getUTCMillis(2000, Calendar.JUNE, 1);
    TimeZoneTransition tzt1, tzt2;
    // BasicTimeZone API implementation in SimpleTimeZone
    SimpleTimeZone stz1 = new SimpleTimeZone(-5 * HOUR, "GMT-5");
    tzt1 = stz1.getNextTransition(time1, false);
    if (tzt1 != null) {
        errln("FAIL: No transition must be returned by getNextTranstion for SimpleTimeZone with no DST rule");
    }
    tzt1 = stz1.getPreviousTransition(time1, false);
    if (tzt1 != null) {
        errln("FAIL: No transition must be returned by getPreviousTransition  for SimpleTimeZone with no DST rule");
    }
    TimeZoneRule[] tzrules = stz1.getTimeZoneRules();
    if (tzrules.length != 1 || !(tzrules[0] instanceof InitialTimeZoneRule)) {
        errln("FAIL: Invalid results returned by SimpleTimeZone#getTimeZoneRules");
    }
    // Set DST rule
    // March 11
    stz1.setStartRule(Calendar.MARCH, 11, 2 * HOUR);
    // First Sunday in November
    stz1.setEndRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2 * HOUR);
    tzt1 = stz1.getNextTransition(time1, false);
    if (tzt1 == null) {
        errln("FAIL: Non-null transition must be returned by getNextTranstion for SimpleTimeZone with a DST rule");
    } else {
        String str = tzt1.toString();
        if (str == null || str.length() == 0) {
            errln("FAIL: TimeZoneTransition#toString returns null or empty string");
        } else {
            logln(str);
        }
    }
    tzt1 = stz1.getPreviousTransition(time1, false);
    if (tzt1 == null) {
        errln("FAIL: Non-null transition must be returned by getPreviousTransition  for SimpleTimeZone with a DST rule");
    }
    tzrules = stz1.getTimeZoneRules();
    if (tzrules.length != 3 || !(tzrules[0] instanceof InitialTimeZoneRule) || !(tzrules[1] instanceof AnnualTimeZoneRule) || !(tzrules[2] instanceof AnnualTimeZoneRule)) {
        errln("FAIL: Invalid results returned by SimpleTimeZone#getTimeZoneRules for a SimpleTimeZone with DST");
    }
    // Set DST start year
    stz1.setStartYear(2007);
    tzt1 = stz1.getPreviousTransition(time1, false);
    if (tzt1 != null) {
        errln("FAIL: No transition must be returned before 1990");
    }
    // transition after 1990-06-01
    tzt1 = stz1.getNextTransition(time1, false);
    // transition after 2000-06-01
    tzt2 = stz1.getNextTransition(time2, false);
    if (tzt1 == null || tzt2 == null || !tzt1.equals(tzt2)) {
        errln("FAIL: Bad transition returned by SimpleTimeZone#getNextTransition");
    }
}
Also used : InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) TimeArrayTimeZoneRule(android.icu.util.TimeArrayTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) TimeZoneRule(android.icu.util.TimeZoneRule) TimeZoneTransition(android.icu.util.TimeZoneTransition) InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) SimpleTimeZone(android.icu.util.SimpleTimeZone) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) Test(org.junit.Test)

Example 12 with InitialTimeZoneRule

use of android.icu.util.InitialTimeZoneRule in project j2objc by google.

the class IcuZoneRulesProvider method generateZoneRules.

/*
     * This implementation is only tested with BasicTimeZone objects and depends on
     * implementation details of that class:
     *
     * 0. TimeZone.getFrozenTimeZone() always returns a BasicTimeZone object.
     * 1. The first rule is always an InitialTimeZoneRule (guaranteed by spec).
     * 2. AnnualTimeZoneRules are only used as "final rules".
     * 3. The final rules are either 0 or 2 AnnualTimeZoneRules
     * 4. The final rules have endYear set to MAX_YEAR.
     * 5. Each transition generated by the rules changes either the raw offset, the total offset
     *    or both.
     * 6. There is a non-immense number of transitions for any rule before the final rules apply
     *    (enforced via the arbitrary limit defined in MAX_TRANSITIONS).
     *
     * Assumptions #5 and #6 are not strictly required for this code to work, but hold for the
     * the data and code at the time of implementation. If they were broken they would indicate
     * an incomplete understanding of how ICU TimeZoneRules are used which would probably mean that
     * this code needs to be updated.
     *
     * These assumptions are verified using the verify() method where appropriate.
     */
static ZoneRules generateZoneRules(String zoneId) {
    TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId);
    // Assumption #0
    verify(timeZone instanceof BasicTimeZone, zoneId, "Unexpected time zone class " + timeZone.getClass());
    BasicTimeZone tz = (BasicTimeZone) timeZone;
    TimeZoneRule[] rules = tz.getTimeZoneRules();
    // Assumption #1
    InitialTimeZoneRule initial = (InitialTimeZoneRule) rules[0];
    ZoneOffset baseStandardOffset = millisToOffset(initial.getRawOffset());
    ZoneOffset baseWallOffset = millisToOffset((initial.getRawOffset() + initial.getDSTSavings()));
    List<ZoneOffsetTransition> standardOffsetTransitionList = new ArrayList<>();
    List<ZoneOffsetTransition> transitionList = new ArrayList<>();
    List<ZoneOffsetTransitionRule> lastRules = new ArrayList<>();
    int preLastDstSavings = 0;
    AnnualTimeZoneRule last1 = null;
    AnnualTimeZoneRule last2 = null;
    TimeZoneTransition transition = tz.getNextTransition(Long.MIN_VALUE, false);
    int transitionCount = 1;
    // "last rules" in java.time) the "break transitionLoop" will be used to exit the loop.
    transitionLoop: while (transition != null) {
        TimeZoneRule from = transition.getFrom();
        TimeZoneRule to = transition.getTo();
        boolean hadEffect = false;
        if (from.getRawOffset() != to.getRawOffset()) {
            standardOffsetTransitionList.add(new ZoneOffsetTransition(TimeUnit.MILLISECONDS.toSeconds(transition.getTime()), millisToOffset(from.getRawOffset()), millisToOffset(to.getRawOffset())));
            hadEffect = true;
        }
        int fromTotalOffset = from.getRawOffset() + from.getDSTSavings();
        int toTotalOffset = to.getRawOffset() + to.getDSTSavings();
        if (fromTotalOffset != toTotalOffset) {
            transitionList.add(new ZoneOffsetTransition(TimeUnit.MILLISECONDS.toSeconds(transition.getTime()), millisToOffset(fromTotalOffset), millisToOffset(toTotalOffset)));
            hadEffect = true;
        }
        // Assumption #5
        verify(hadEffect, zoneId, "Transition changed neither total nor raw offset.");
        if (to instanceof AnnualTimeZoneRule) {
            // The presence of an AnnualTimeZoneRule is taken as an indication of a final rule.
            if (last1 == null) {
                preLastDstSavings = from.getDSTSavings();
                last1 = (AnnualTimeZoneRule) to;
                // Assumption #4
                verify(last1.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId, "AnnualTimeZoneRule is not permanent.");
            } else {
                last2 = (AnnualTimeZoneRule) to;
                // Assumption #4
                verify(last2.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId, "AnnualTimeZoneRule is not permanent.");
                // Assumption #3
                transition = tz.getNextTransition(transition.getTime(), false);
                verify(transition.getTo() == last1, zoneId, "Unexpected rule after 2 AnnualTimeZoneRules.");
                break transitionLoop;
            }
        } else {
            // Assumption #2
            verify(last1 == null, zoneId, "Unexpected rule after AnnualTimeZoneRule.");
        }
        verify(transitionCount <= MAX_TRANSITIONS, zoneId, "More than " + MAX_TRANSITIONS + " transitions.");
        transition = tz.getNextTransition(transition.getTime(), false);
        transitionCount++;
    }
    if (last1 != null) {
        // Assumption #3
        verify(last2 != null, zoneId, "Only one AnnualTimeZoneRule.");
        lastRules.add(toZoneOffsetTransitionRule(last1, preLastDstSavings));
        lastRules.add(toZoneOffsetTransitionRule(last2, last1.getDSTSavings()));
    }
    return ZoneRules.of(baseStandardOffset, baseWallOffset, standardOffsetTransitionList, transitionList, lastRules);
}
Also used : InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) ArrayList(java.util.ArrayList) ZoneOffset(java.time.ZoneOffset) InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) TimeZoneRule(android.icu.util.TimeZoneRule) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition)

Aggregations

InitialTimeZoneRule (android.icu.util.InitialTimeZoneRule)12 AnnualTimeZoneRule (android.icu.util.AnnualTimeZoneRule)10 Test (org.junit.Test)9 RuleBasedTimeZone (android.icu.util.RuleBasedTimeZone)7 BasicTimeZone (android.icu.util.BasicTimeZone)6 DateTimeRule (android.icu.util.DateTimeRule)6 SimpleTimeZone (android.icu.util.SimpleTimeZone)6 TimeArrayTimeZoneRule (android.icu.util.TimeArrayTimeZoneRule)6 TimeZoneRule (android.icu.util.TimeZoneRule)6 TimeZone (android.icu.util.TimeZone)5 TimeZoneTransition (android.icu.util.TimeZoneTransition)3 VTimeZone (android.icu.util.VTimeZone)3 Date (java.util.Date)3 GregorianCalendar (android.icu.util.GregorianCalendar)2 JavaTimeZone (android.icu.impl.JavaTimeZone)1 DateFormat (android.icu.text.DateFormat)1 Calendar (android.icu.util.Calendar)1 NativeTimeZone (com.google.j2objc.util.NativeTimeZone)1 IOException (java.io.IOException)1 ZoneOffset (java.time.ZoneOffset)1