Search in sources :

Example 6 with AnnualTimeZoneRule

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

the class TimeZoneRuleTest method TestGetSimpleRules.

/*
     * Extract simple rules from an OlsonTimeZone and make sure the rule format matches
     * the expected format.
     */
@Test
public void TestGetSimpleRules() {
    long[] testTimes = new long[] { getUTCMillis(1970, Calendar.JANUARY, 1), getUTCMillis(2000, Calendar.MARCH, 31), getUTCMillis(2005, Calendar.JULY, 1), getUTCMillis(2010, Calendar.NOVEMBER, 1) };
    String[] tzids = getTestZIDs();
    for (int n = 0; n < testTimes.length; n++) {
        long time = testTimes[n];
        for (int i = 0; i < tzids.length; i++) {
            BasicTimeZone tz = (BasicTimeZone) TimeZone.getTimeZone(tzids[i], TimeZone.TIMEZONE_ICU);
            TimeZoneRule[] rules = tz.getSimpleTimeZoneRulesNear(time);
            if (rules == null) {
                errln("FAIL: Failed to extract simple rules for " + tzids[i] + " at " + time);
            } else {
                if (rules.length == 1) {
                    if (!(rules[0] instanceof InitialTimeZoneRule)) {
                        errln("FAIL: Unexpected rule object type is returned for " + tzids[i] + " at " + time);
                    }
                } else if (rules.length == 3) {
                    if (!(rules[0] instanceof InitialTimeZoneRule) || !(rules[1] instanceof AnnualTimeZoneRule) || !(rules[2] instanceof AnnualTimeZoneRule)) {
                        errln("FAIL: Unexpected rule object type is returned for " + tzids[i] + " at " + time);
                    }
                    for (int idx = 1; idx <= 2; idx++) {
                        DateTimeRule dtr = ((AnnualTimeZoneRule) rules[idx]).getRule();
                        if (dtr.getTimeRuleType() != DateTimeRule.WALL_TIME) {
                            errln("FAIL: WALL_TIME is not used as the time rule in the time zone rule(" + idx + ") for " + tzids[i] + " at " + time);
                        }
                        if (dtr.getDateRuleType() != DateTimeRule.DOW) {
                            errln("FAIL: DOW is not used as the date rule in the time zone rule(" + idx + ") for " + tzids[i] + " at " + time);
                        }
                    }
                } else {
                    errln("FAIL: Unexpected number of rules returned for " + tzids[i] + " at " + time);
                }
            }
        }
    }
}
Also used : InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) TimeArrayTimeZoneRule(android.icu.util.TimeArrayTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) TimeZoneRule(android.icu.util.TimeZoneRule) DateTimeRule(android.icu.util.DateTimeRule) BasicTimeZone(android.icu.util.BasicTimeZone) InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) Test(org.junit.Test)

Example 7 with AnnualTimeZoneRule

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

the class TimeZoneRuleTest method TestHistoricalRuleBasedTimeZone.

/*
     * Test equivalency between OlsonTimeZone and custom RBTZ representing the
     * equivalent rules in a certain time range
     */
@Test
public void TestHistoricalRuleBasedTimeZone() {
    // Compare to America/New_York with equivalent RBTZ
    TimeZone ny = TimeZone.getTimeZone("America/New_York", TimeZone.TIMEZONE_ICU);
    // RBTZ
    InitialTimeZoneRule ir = new InitialTimeZoneRule("EST", -5 * HOUR, 0);
    RuleBasedTimeZone rbtz = new RuleBasedTimeZone("EST5EDT", ir);
    DateTimeRule dtr;
    AnnualTimeZoneRule tzr;
    // Standard time
    dtr = new DateTimeRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * HOUR, // Last Sunday in October, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EST", -5 * HOUR, /* rawOffset */
    0, /* dstSavings */
    dtr, 1967, 2006);
    rbtz.addTransitionRule(tzr);
    dtr = new DateTimeRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, true, 2 * HOUR, // SUN>=1 in November, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EST", -5 * HOUR, 0, dtr, 2007, AnnualTimeZoneRule.MAX_YEAR);
    rbtz.addTransitionRule(tzr);
    // Daylight saving time
    dtr = new DateTimeRule(Calendar.APRIL, -1, Calendar.SUNDAY, 2 * HOUR, // Last Sunday in April, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EDT", -5 * HOUR, 1 * HOUR, dtr, 1967, 1973);
    rbtz.addTransitionRule(tzr);
    dtr = new DateTimeRule(Calendar.JANUARY, 6, 2 * HOUR, // January 6, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EDT", -5 * HOUR, 1 * HOUR, dtr, 1974, 1974);
    rbtz.addTransitionRule(tzr);
    dtr = new DateTimeRule(Calendar.FEBRUARY, 23, 2 * HOUR, // February 23, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EDT", -5 * HOUR, 1 * HOUR, dtr, 1975, 1975);
    rbtz.addTransitionRule(tzr);
    dtr = new DateTimeRule(Calendar.APRIL, -1, Calendar.SUNDAY, 2 * HOUR, // Last Sunday in April, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EDT", -5 * HOUR, 1 * HOUR, dtr, 1976, 1986);
    rbtz.addTransitionRule(tzr);
    dtr = new DateTimeRule(Calendar.APRIL, 1, Calendar.SUNDAY, true, 2 * HOUR, // SUN>=1 in April, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EDT", -5 * HOUR, 1 * HOUR, dtr, 1987, 2006);
    rbtz.addTransitionRule(tzr);
    dtr = new DateTimeRule(Calendar.MARCH, 8, Calendar.SUNDAY, true, 2 * HOUR, // SUN>=8 in March, at 2AM wall time
    DateTimeRule.WALL_TIME);
    tzr = new AnnualTimeZoneRule("EDT", -5 * HOUR, 1 * HOUR, dtr, 2007, AnnualTimeZoneRule.MAX_YEAR);
    rbtz.addTransitionRule(tzr);
    // hasEquivalentTransitions
    long jan1_1950 = getUTCMillis(1950, Calendar.JANUARY, 1);
    long jan1_1967 = getUTCMillis(1971, Calendar.JANUARY, 1);
    long jan1_2010 = getUTCMillis(2010, Calendar.JANUARY, 1);
    if (!(((BasicTimeZone) ny).hasEquivalentTransitions(rbtz, jan1_1967, jan1_2010))) {
        errln("FAIL: The RBTZ must be equivalent to America/New_York between 1967 and 2010");
    }
    if (((BasicTimeZone) ny).hasEquivalentTransitions(rbtz, jan1_1950, jan1_2010)) {
        errln("FAIL: The RBTZ must not be equivalent to America/New_York between 1950 and 2010");
    }
    // Same with above, but calling RBTZ#hasEquivalentTransitions against OlsonTimeZone
    if (!rbtz.hasEquivalentTransitions(ny, jan1_1967, jan1_2010)) {
        errln("FAIL: The RBTZ must be equivalent to America/New_York between 1967 and 2010");
    }
    if (rbtz.hasEquivalentTransitions(ny, jan1_1950, jan1_2010)) {
        errln("FAIL: The RBTZ must not be equivalent to America/New_York between 1950 and 2010");
    }
    // TimeZone APIs
    if (ny.hasSameRules(rbtz) || rbtz.hasSameRules(ny)) {
        errln("FAIL: hasSameRules must return false");
    }
    RuleBasedTimeZone rbtzc = (RuleBasedTimeZone) rbtz.clone();
    if (!rbtz.hasSameRules(rbtzc) || !rbtz.hasEquivalentTransitions(rbtzc, jan1_1950, jan1_2010)) {
        errln("FAIL: hasSameRules/hasEquivalentTransitions must return true for cloned RBTZs");
    }
    long[] times = { getUTCMillis(2006, Calendar.MARCH, 15), getUTCMillis(2006, Calendar.NOVEMBER, 1), getUTCMillis(2007, Calendar.MARCH, 15), getUTCMillis(2007, Calendar.NOVEMBER, 1), getUTCMillis(2008, Calendar.MARCH, 15), getUTCMillis(2008, Calendar.NOVEMBER, 1) };
    int[] offsets1 = new int[2];
    int[] offsets2 = new int[2];
    for (int i = 0; i < times.length; i++) {
        // Check getOffset - must return the same results for these time data
        rbtz.getOffset(times[i], false, offsets1);
        ny.getOffset(times[i], false, offsets2);
        if (offsets1[0] != offsets2[0] || offsets1[1] != offsets2[1]) {
            errln("FAIL: Incompatible time zone offsets for ny and rbtz");
        }
        // Check inDaylightTime
        Date d = new Date(times[i]);
        if (rbtz.inDaylightTime(d) != ny.inDaylightTime(d)) {
            errln("FAIL: Incompatible daylight saving time for ny and rbtz");
        }
    }
}
Also used : DateTimeRule(android.icu.util.DateTimeRule) SimpleTimeZone(android.icu.util.SimpleTimeZone) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) VTimeZone(android.icu.util.VTimeZone) RuleBasedTimeZone(android.icu.util.RuleBasedTimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) RuleBasedTimeZone(android.icu.util.RuleBasedTimeZone) Date(java.util.Date) Test(org.junit.Test)

Example 8 with AnnualTimeZoneRule

use of android.icu.util.AnnualTimeZoneRule 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 9 with AnnualTimeZoneRule

use of android.icu.util.AnnualTimeZoneRule 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

AnnualTimeZoneRule (android.icu.util.AnnualTimeZoneRule)9 InitialTimeZoneRule (android.icu.util.InitialTimeZoneRule)9 DateTimeRule (android.icu.util.DateTimeRule)7 Test (org.junit.Test)7 SimpleTimeZone (android.icu.util.SimpleTimeZone)5 BasicTimeZone (android.icu.util.BasicTimeZone)4 RuleBasedTimeZone (android.icu.util.RuleBasedTimeZone)4 TimeArrayTimeZoneRule (android.icu.util.TimeArrayTimeZoneRule)4 TimeZoneRule (android.icu.util.TimeZoneRule)4 TimeZone (android.icu.util.TimeZone)3 TimeZoneTransition (android.icu.util.TimeZoneTransition)3 Date (java.util.Date)3 GregorianCalendar (android.icu.util.GregorianCalendar)2 DateFormat (android.icu.text.DateFormat)1 Calendar (android.icu.util.Calendar)1 VTimeZone (android.icu.util.VTimeZone)1 IOException (java.io.IOException)1 ZoneOffset (java.time.ZoneOffset)1 ArrayList (java.util.ArrayList)1