Search in sources :

Example 6 with BasicTimeZone

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

the class TimeZoneOffsetLocalTest method TestGetOffsetAroundTransition.

/*
     * Testing getOffset APIs around rule transition by local standard/wall time.
     */
@Test
public void TestGetOffsetAroundTransition() {
    final int HOUR = 60 * 60 * 1000;
    final int MINUTE = 60 * 1000;
    int[][] DATES = { { 2006, Calendar.APRIL, 2, 1, 30, 1 * HOUR + 30 * MINUTE }, { 2006, Calendar.APRIL, 2, 2, 00, 2 * HOUR }, { 2006, Calendar.APRIL, 2, 2, 30, 2 * HOUR + 30 * MINUTE }, { 2006, Calendar.APRIL, 2, 3, 00, 3 * HOUR }, { 2006, Calendar.APRIL, 2, 3, 30, 3 * HOUR + 30 * MINUTE }, { 2006, Calendar.OCTOBER, 29, 0, 30, 0 * HOUR + 30 * MINUTE }, { 2006, Calendar.OCTOBER, 29, 1, 00, 1 * HOUR }, { 2006, Calendar.OCTOBER, 29, 1, 30, 1 * HOUR + 30 * MINUTE }, { 2006, Calendar.OCTOBER, 29, 2, 00, 2 * HOUR }, { 2006, Calendar.OCTOBER, 29, 2, 30, 2 * HOUR + 30 * MINUTE } };
    // Expected offsets by getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds)
    int[] OFFSETS1 = { // April 2, 2006
    -8 * HOUR, -7 * HOUR, -7 * HOUR, -7 * HOUR, -7 * HOUR, // October 29, 2006
    -7 * HOUR, -8 * HOUR, -8 * HOUR, -8 * HOUR, -8 * HOUR };
    // Expected offsets by getOffset(long time, boolean local, int[] offsets) with local = true
    // or getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets)
    // with nonExistingTimeOpt = LOCAL_STD/duplicatedTimeOpt = LOCAL_STD
    int[][] OFFSETS2 = { // April 2, 2006
    { -8 * HOUR, 0 }, { -8 * HOUR, 0 }, { -8 * HOUR, 0 }, { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 1 * HOUR }, // Oct 29, 2006
    { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 0 }, { -8 * HOUR, 0 }, { -8 * HOUR, 0 }, { -8 * HOUR, 0 } };
    // Expected offsets by getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets)
    // with nonExistingTimeOpt = LOCAL_DST/duplicatedTimeOpt = LOCAL_DST
    int[][] OFFSETS3 = { // April 2, 2006
    { -8 * HOUR, 0 }, { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 1 * HOUR }, // October 29, 2006
    { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 1 * HOUR }, { -8 * HOUR, 0 }, { -8 * HOUR, 0 } };
    int[] offsets = new int[2];
    TimeZone utc = TimeZone.getTimeZone("UTC");
    Calendar cal = Calendar.getInstance(utc);
    cal.clear();
    // Set up TimeZone objects - OlsonTimeZone, SimpleTimeZone and RuleBasedTimeZone
    BasicTimeZone[] TESTZONES = new BasicTimeZone[3];
    TESTZONES[0] = (BasicTimeZone) TimeZone.getTimeZone("America/Los_Angeles", TimeZone.TIMEZONE_ICU);
    TESTZONES[1] = new SimpleTimeZone(-8 * HOUR, "Simple Pacific Time", Calendar.APRIL, 1, Calendar.SUNDAY, 2 * HOUR, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * HOUR);
    InitialTimeZoneRule ir = new InitialTimeZoneRule(// Initial time Name
    "Pacific Standard Time", // Raw offset
    -8 * HOUR, // DST saving amount
    0 * HOUR);
    RuleBasedTimeZone rbPT = new RuleBasedTimeZone("Rule based Pacific Time", ir);
    DateTimeRule dtr;
    AnnualTimeZoneRule atzr;
    final int STARTYEAR = 2000;
    dtr = new DateTimeRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * HOUR, // 1st Sunday in April, at 2AM wall time
    DateTimeRule.WALL_TIME);
    atzr = new AnnualTimeZoneRule("Pacific Daylight Time", -8 * HOUR, /* rawOffset */
    1 * HOUR, /* dstSavings */
    dtr, STARTYEAR, AnnualTimeZoneRule.MAX_YEAR);
    rbPT.addTransitionRule(atzr);
    dtr = new DateTimeRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * HOUR, // last Sunday in October, at 2AM wall time
    DateTimeRule.WALL_TIME);
    atzr = new AnnualTimeZoneRule("Pacific Standard Time", -8 * HOUR, /* rawOffset */
    0, /* dstSavings */
    dtr, STARTYEAR, AnnualTimeZoneRule.MAX_YEAR);
    rbPT.addTransitionRule(atzr);
    TESTZONES[2] = rbPT;
    // Calculate millis
    long[] MILLIS = new long[DATES.length];
    for (int i = 0; i < DATES.length; i++) {
        cal.clear();
        cal.set(DATES[i][0], DATES[i][1], DATES[i][2], DATES[i][3], DATES[i][4]);
        MILLIS[i] = cal.getTimeInMillis();
    }
    DateFormat df = DateFormat.getInstance();
    df.setTimeZone(utc);
    // Test getOffset(int era, int year, int month, int day, int dayOfWeek, int millis)
    for (int i = 0; i < TESTZONES.length; i++) {
        for (int d = 0; d < DATES.length; d++) {
            int offset = TESTZONES[i].getOffset(GregorianCalendar.AD, DATES[d][0], DATES[d][1], DATES[d][2], Calendar.SUNDAY, DATES[d][5]);
            if (offset != OFFSETS1[d]) {
                errln("Bad offset returned by " + TESTZONES[i].getID() + " at " + df.format(new Date(MILLIS[d])) + "(standard) - Got: " + offset + " Expected: " + OFFSETS1[d]);
            }
        }
    }
    // Test getOffset(long time, boolean local, int[] offsets) with local=true
    for (int i = 0; i < TESTZONES.length; i++) {
        for (int m = 0; m < MILLIS.length; m++) {
            TESTZONES[i].getOffset(MILLIS[m], true, offsets);
            if (offsets[0] != OFFSETS2[m][0] || offsets[1] != OFFSETS2[m][1]) {
                errln("Bad offset returned by " + TESTZONES[i].getID() + " at " + df.format(new Date(MILLIS[m])) + "(wall) - Got: " + offsets[0] + "/" + offsets[1] + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
            }
        }
    }
    // with nonExistingTimeOpt = LOCAL_STD/duplicatedTimeOpt = LOCAL_STD
    for (int i = 0; i < TESTZONES.length; i++) {
        for (int m = 0; m < MILLIS.length; m++) {
            TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_STD, BasicTimeZone.LOCAL_STD, offsets);
            if (offsets[0] != OFFSETS2[m][0] || offsets[1] != OFFSETS2[m][1]) {
                errln("Bad offset returned by " + TESTZONES[i].getID() + " at " + df.format(new Date(MILLIS[m])) + "(wall/STD/STD) - Got: " + offsets[0] + "/" + offsets[1] + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
            }
        }
    }
    // with nonExistingTimeOpt = LOCAL_DST/duplicatedTimeOpt = LOCAL_DST
    for (int i = 0; i < TESTZONES.length; i++) {
        for (int m = 0; m < MILLIS.length; m++) {
            TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_DST, BasicTimeZone.LOCAL_DST, offsets);
            if (offsets[0] != OFFSETS3[m][0] || offsets[1] != OFFSETS3[m][1]) {
                errln("Bad offset returned by " + TESTZONES[i].getID() + " at " + df.format(new Date(MILLIS[m])) + "(wall/DST/DST) - Got: " + offsets[0] + "/" + offsets[1] + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]);
            }
        }
    }
    // with nonExistingTimeOpt = LOCAL_FORMER/duplicatedTimeOpt = LOCAL_LATTER
    for (int i = 0; i < TESTZONES.length; i++) {
        for (int m = 0; m < MILLIS.length; m++) {
            TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_FORMER, BasicTimeZone.LOCAL_LATTER, offsets);
            if (offsets[0] != OFFSETS2[m][0] || offsets[1] != OFFSETS2[m][1]) {
                errln("Bad offset returned by " + TESTZONES[i].getID() + " at " + df.format(new Date(MILLIS[m])) + "(wall/FORMER/LATTER) - Got: " + offsets[0] + "/" + offsets[1] + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
            }
        }
    }
    // with nonExistingTimeOpt = LOCAL_LATTER/duplicatedTimeOpt = LOCAL_FORMER
    for (int i = 0; i < TESTZONES.length; i++) {
        for (int m = 0; m < MILLIS.length; m++) {
            TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_LATTER, BasicTimeZone.LOCAL_FORMER, offsets);
            if (offsets[0] != OFFSETS3[m][0] || offsets[1] != OFFSETS3[m][1]) {
                errln("Bad offset returned by " + TESTZONES[i].getID() + " at " + df.format(new Date(MILLIS[m])) + "(wall/LATTER/FORMER) - Got: " + offsets[0] + "/" + offsets[1] + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]);
            }
        }
    }
}
Also used : InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) GregorianCalendar(android.icu.util.GregorianCalendar) Calendar(android.icu.util.Calendar) RuleBasedTimeZone(android.icu.util.RuleBasedTimeZone) Date(java.util.Date) DateTimeRule(android.icu.util.DateTimeRule) SimpleTimeZone(android.icu.util.SimpleTimeZone) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) RuleBasedTimeZone(android.icu.util.RuleBasedTimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) SimpleTimeZone(android.icu.util.SimpleTimeZone) DateFormat(android.icu.text.DateFormat) Test(org.junit.Test)

Example 7 with BasicTimeZone

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

the class TimeZoneRuleTest method TestRBTZTransition.

/*
     * Check if an OlsonTimeZone and its equivalent RBTZ have the exact same
     * transitions.
     */
@Test
public void TestRBTZTransition() {
    int[] STARTYEARS = { 1950, 1975, 2000, 2010 };
    String[] zids = getTestZIDs();
    for (int i = 0; i < zids.length; i++) {
        TimeZone tz = TimeZone.getTimeZone(zids[i], TimeZone.TIMEZONE_ICU);
        if (tz == null) {
            break;
        }
        for (int j = 0; j < STARTYEARS.length; j++) {
            long startTime = getUTCMillis(STARTYEARS[j], Calendar.JANUARY, 1);
            TimeZoneRule[] rules = ((BasicTimeZone) tz).getTimeZoneRules(startTime);
            RuleBasedTimeZone rbtz = new RuleBasedTimeZone(tz.getID() + "(RBTZ)", (InitialTimeZoneRule) rules[0]);
            for (int k = 1; k < rules.length; k++) {
                rbtz.addTransitionRule(rules[k]);
            }
            // Compare the original OlsonTimeZone with the RBTZ starting the startTime for 20 years
            long until = getUTCMillis(STARTYEARS[j] + 20, Calendar.JANUARY, 1);
            // Ascending
            compareTransitionsAscending(tz, rbtz, startTime, until, false);
            // Ascending/inclusive
            compareTransitionsAscending(tz, rbtz, startTime + 1, until, true);
            // Descending
            compareTransitionsDescending(tz, rbtz, startTime, until, false);
            // Descending/inclusive
            compareTransitionsDescending(tz, rbtz, startTime + 1, until, true);
        }
    }
}
Also used : InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) TimeArrayTimeZoneRule(android.icu.util.TimeArrayTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) TimeZoneRule(android.icu.util.TimeZoneRule) 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) RuleBasedTimeZone(android.icu.util.RuleBasedTimeZone) Test(org.junit.Test)

Example 8 with BasicTimeZone

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

the class TimeZoneFormatTest method TestTimeRoundTrip.

/*
     * Test case of round trip time and text.  This test case detects every canonical TimeZone's
     * rule transition since 1900 until 2020, then check if time around each transition can
     * round trip as expected.
     */
@Test
public void TestTimeRoundTrip() {
    boolean TEST_ALL = getBooleanProperty("TimeZoneRoundTripAll", false);
    int startYear, endYear;
    if (TEST_ALL || TestFmwk.getExhaustiveness() > 5) {
        startYear = 1900;
    } else {
        startYear = 1990;
    }
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    endYear = cal.get(Calendar.YEAR) + 3;
    cal.set(startYear, Calendar.JANUARY, 1);
    final long START_TIME = cal.getTimeInMillis();
    cal.set(endYear, Calendar.JANUARY, 1);
    final long END_TIME = cal.getTimeInMillis();
    // These patterns are ambiguous at DST->STD local time overlap
    List<String> AMBIGUOUS_DST_DECESSION = Arrays.asList("v", "vvvv", "V", "VV", "VVV", "VVVV");
    // These patterns are ambiguous at STD->STD/DST->DST local time overlap
    List<String> AMBIGUOUS_NEGATIVE_SHIFT = Arrays.asList("z", "zzzz", "v", "vvvv", "V", "VV", "VVV", "VVVV");
    // These patterns only support integer minutes offset
    List<String> MINUTES_OFFSET = Arrays.asList("X", "XX", "XXX", "x", "xx", "xxx");
    // Regex pattern used for filtering zone IDs without exemplar location
    final Pattern LOC_EXCLUSION_PATTERN = Pattern.compile("Etc/.*|SystemV/.*|.*/Riyadh8[7-9]");
    final String BASEPATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS";
    ULocale[] LOCALES = null;
    // timer for performance analysis
    long[] times = new long[PATTERNS.length];
    long timer;
    if (TEST_ALL) {
        // It may take about an hour for testing all locales
        LOCALES = ULocale.getAvailableLocales();
    } else if (TestFmwk.getExhaustiveness() > 5) {
        LOCALES = new ULocale[] { new ULocale("ar_EG"), new ULocale("bg_BG"), new ULocale("ca_ES"), new ULocale("da_DK"), new ULocale("de"), new ULocale("de_DE"), new ULocale("el_GR"), new ULocale("en"), new ULocale("en_AU"), new ULocale("en_CA"), new ULocale("en_US"), new ULocale("es"), new ULocale("es_ES"), new ULocale("es_MX"), new ULocale("fi_FI"), new ULocale("fr"), new ULocale("fr_CA"), new ULocale("fr_FR"), new ULocale("he_IL"), new ULocale("hu_HU"), new ULocale("it"), new ULocale("it_IT"), new ULocale("ja"), new ULocale("ja_JP"), new ULocale("ko"), new ULocale("ko_KR"), new ULocale("nb_NO"), new ULocale("nl_NL"), new ULocale("nn_NO"), new ULocale("pl_PL"), new ULocale("pt"), new ULocale("pt_BR"), new ULocale("pt_PT"), new ULocale("ru_RU"), new ULocale("sv_SE"), new ULocale("th_TH"), new ULocale("tr_TR"), new ULocale("zh"), new ULocale("zh_Hans"), new ULocale("zh_Hans_CN"), new ULocale("zh_Hant"), new ULocale("zh_Hant_HK"), new ULocale("zh_Hant_TW") };
    } else {
        LOCALES = new ULocale[] { new ULocale("en") };
    }
    SimpleDateFormat sdfGMT = new SimpleDateFormat(BASEPATTERN);
    sdfGMT.setTimeZone(TimeZone.getTimeZone("Etc/GMT"));
    long testCounts = 0;
    long[] testTimes = new long[4];
    boolean[] expectedRoundTrip = new boolean[4];
    int testLen = 0;
    for (int locidx = 0; locidx < LOCALES.length; locidx++) {
        logln("Locale: " + LOCALES[locidx].toString());
        for (int patidx = 0; patidx < PATTERNS.length; patidx++) {
            logln("    pattern: " + PATTERNS[patidx]);
            String pattern = BASEPATTERN + " " + PATTERNS[patidx];
            SimpleDateFormat sdf = new SimpleDateFormat(pattern, LOCALES[locidx]);
            boolean minutesOffset = MINUTES_OFFSET.contains(PATTERNS[patidx]);
            Set<String> ids = null;
            if (JDKTZ) {
                ids = new TreeSet<String>();
                String[] jdkIDs = java.util.TimeZone.getAvailableIDs();
                for (String jdkID : jdkIDs) {
                    if (EXCL_TZ_PATTERN.matcher(jdkID).matches()) {
                        continue;
                    }
                    String tmpID = TimeZone.getCanonicalID(jdkID);
                    if (tmpID != null) {
                        ids.add(tmpID);
                    }
                }
            } else {
                ids = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL, null, null);
            }
            for (String id : ids) {
                if (PATTERNS[patidx].equals("V")) {
                    // Some zones do not have short ID assigned, such as Asia/Riyadh87.
                    // The time roundtrip will fail for such zones with pattern "V" (short zone ID).
                    // This is expected behavior.
                    String shortZoneID = ZoneMeta.getShortID(id);
                    if (shortZoneID == null) {
                        continue;
                    }
                } else if (PATTERNS[patidx].equals("VVV")) {
                    // This is expected behavior.
                    if (id.indexOf('/') < 0 || LOC_EXCLUSION_PATTERN.matcher(id).matches()) {
                        continue;
                    }
                }
                if (id.equals("Pacific/Apia") && PATTERNS[patidx].equals("vvvv") && logKnownIssue("11052", "Ambiguous zone name - Samoa Time")) {
                    continue;
                }
                BasicTimeZone btz = (BasicTimeZone) TimeZone.getTimeZone(id, TimeZone.TIMEZONE_ICU);
                TimeZone tz = TimeZone.getTimeZone(id);
                sdf.setTimeZone(tz);
                long t = START_TIME;
                TimeZoneTransition tzt = null;
                boolean middle = true;
                boolean last = false;
                while (t < END_TIME) {
                    if (tzt == null) {
                        testTimes[0] = t;
                        expectedRoundTrip[0] = true;
                        testLen = 1;
                    } else {
                        int fromOffset = tzt.getFrom().getRawOffset() + tzt.getFrom().getDSTSavings();
                        int toOffset = tzt.getTo().getRawOffset() + tzt.getTo().getDSTSavings();
                        int delta = toOffset - fromOffset;
                        if (delta < 0) {
                            boolean isDstDecession = tzt.getFrom().getDSTSavings() > 0 && tzt.getTo().getDSTSavings() == 0;
                            testTimes[0] = t + delta - 1;
                            expectedRoundTrip[0] = true;
                            testTimes[1] = t + delta;
                            expectedRoundTrip[1] = isDstDecession ? !AMBIGUOUS_DST_DECESSION.contains(PATTERNS[patidx]) : !AMBIGUOUS_NEGATIVE_SHIFT.contains(PATTERNS[patidx]);
                            testTimes[2] = t - 1;
                            expectedRoundTrip[2] = isDstDecession ? !AMBIGUOUS_DST_DECESSION.contains(PATTERNS[patidx]) : !AMBIGUOUS_NEGATIVE_SHIFT.contains(PATTERNS[patidx]);
                            testTimes[3] = t;
                            expectedRoundTrip[3] = true;
                            testLen = 4;
                        } else {
                            testTimes[0] = t - 1;
                            expectedRoundTrip[0] = true;
                            testTimes[1] = t;
                            expectedRoundTrip[1] = true;
                            testLen = 2;
                        }
                    }
                    for (int testidx = 0; testidx < testLen; testidx++) {
                        testCounts++;
                        timer = System.currentTimeMillis();
                        String text = sdf.format(new Date(testTimes[testidx]));
                        try {
                            Date parsedDate = sdf.parse(text);
                            long restime = parsedDate.getTime();
                            long timeDiff = restime - testTimes[testidx];
                            boolean bTimeMatch = minutesOffset ? (timeDiff / 60000) * 60000 == 0 : timeDiff == 0;
                            if (!bTimeMatch) {
                                StringBuffer msg = new StringBuffer();
                                msg.append("Time round trip failed for ").append("tzid=").append(id).append(", locale=").append(LOCALES[locidx]).append(", pattern=").append(PATTERNS[patidx]).append(", text=").append(text).append(", gmt=").append(sdfGMT.format(new Date(testTimes[testidx]))).append(", time=").append(testTimes[testidx]).append(", restime=").append(restime).append(", diff=").append(timeDiff);
                                if (expectedRoundTrip[testidx] && !isSpecialTimeRoundTripCase(LOCALES[locidx], id, PATTERNS[patidx], testTimes[testidx])) {
                                    errln("FAIL: " + msg.toString());
                                } else if (REALLY_VERBOSE_LOG) {
                                    logln(msg.toString());
                                }
                            }
                        } catch (ParseException pe) {
                            errln("FAIL: " + pe.getMessage() + " tzid=" + id + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", text=" + text);
                        }
                        times[patidx] += System.currentTimeMillis() - timer;
                    }
                    if (last) {
                        break;
                    }
                    tzt = btz.getNextTransition(t, false);
                    if (tzt == null) {
                        last = true;
                        t = END_TIME - 1;
                    } else if (middle) {
                        // Test the date in the middle of two transitions.
                        t += (tzt.getTime() - t) / 2;
                        middle = false;
                        tzt = null;
                    } else {
                        t = tzt.getTime();
                    }
                }
            }
        }
    }
    long total = 0;
    logln("### Elapsed time by patterns ###");
    for (int i = 0; i < PATTERNS.length; i++) {
        logln(times[i] + "ms (" + PATTERNS[i] + ")");
        total += times[i];
    }
    logln("Total: " + total + "ms");
    logln("Iteration: " + testCounts);
}
Also used : Pattern(java.util.regex.Pattern) ULocale(android.icu.util.ULocale) Calendar(android.icu.util.Calendar) Date(java.util.Date) BasicTimeZone(android.icu.util.BasicTimeZone) SimpleTimeZone(android.icu.util.SimpleTimeZone) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition) ParseException(java.text.ParseException) SimpleDateFormat(android.icu.text.SimpleDateFormat) Test(org.junit.Test)

Example 9 with BasicTimeZone

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

the class TimeZoneFormatTest method TestTimeZoneRoundTrip.

/*
     * Test case for checking if a TimeZone is properly set in the result calendar
     * and if the result TimeZone has the expected behavior.
     */
@Test
public void TestTimeZoneRoundTrip() {
    boolean TEST_ALL = getBooleanProperty("TimeZoneRoundTripAll", false);
    TimeZone unknownZone = new SimpleTimeZone(-31415, "Etc/Unknown");
    int badDstOffset = -1234;
    int badZoneOffset = -2345;
    int[][] testDateData = { { 2007, 1, 15 }, { 2007, 6, 15 }, { 1990, 1, 15 }, { 1990, 6, 15 }, { 1960, 1, 15 }, { 1960, 6, 15 } };
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    cal.clear();
    // Set up rule equivalency test range
    long low, high;
    cal.set(1900, 0, 1);
    low = cal.getTimeInMillis();
    cal.set(2040, 0, 1);
    high = cal.getTimeInMillis();
    // Set up test dates
    Date[] DATES = new Date[testDateData.length];
    cal.clear();
    for (int i = 0; i < DATES.length; i++) {
        cal.set(testDateData[i][0], testDateData[i][1], testDateData[i][2]);
        DATES[i] = cal.getTime();
    }
    // Set up test locales
    ULocale[] LOCALES = null;
    if (TEST_ALL || TestFmwk.getExhaustiveness() > 5) {
        LOCALES = ULocale.getAvailableLocales();
    } else {
        LOCALES = new ULocale[] { new ULocale("en"), new ULocale("en_CA"), new ULocale("fr"), new ULocale("zh_Hant") };
    }
    String[] tzids;
    if (JDKTZ) {
        tzids = java.util.TimeZone.getAvailableIDs();
    } else {
        tzids = TimeZone.getAvailableIDs();
    }
    int[] inOffsets = new int[2];
    int[] outOffsets = new int[2];
    // Run the roundtrip test
    for (int locidx = 0; locidx < LOCALES.length; locidx++) {
        logln("Locale: " + LOCALES[locidx].toString());
        String localGMTString = TimeZoneFormat.getInstance(LOCALES[locidx]).formatOffsetLocalizedGMT(0);
        for (int patidx = 0; patidx < PATTERNS.length; patidx++) {
            logln("    pattern: " + PATTERNS[patidx]);
            SimpleDateFormat sdf = new SimpleDateFormat(PATTERNS[patidx], LOCALES[locidx]);
            for (int tzidx = 0; tzidx < tzids.length; tzidx++) {
                if (EXCL_TZ_PATTERN.matcher(tzids[tzidx]).matches()) {
                    continue;
                }
                TimeZone tz = TimeZone.getTimeZone(tzids[tzidx]);
                for (int datidx = 0; datidx < DATES.length; datidx++) {
                    // Format
                    sdf.setTimeZone(tz);
                    String tzstr = sdf.format(DATES[datidx]);
                    // Before parse, set unknown zone to SimpleDateFormat instance
                    // just for making sure that it does not depends on the time zone
                    // originally set.
                    sdf.setTimeZone(unknownZone);
                    // Parse
                    ParsePosition pos = new ParsePosition(0);
                    Calendar outcal = Calendar.getInstance(unknownZone);
                    outcal.set(Calendar.DST_OFFSET, badDstOffset);
                    outcal.set(Calendar.ZONE_OFFSET, badZoneOffset);
                    sdf.parse(tzstr, outcal, pos);
                    // Check the result
                    TimeZone outtz = outcal.getTimeZone();
                    tz.getOffset(DATES[datidx].getTime(), false, inOffsets);
                    outtz.getOffset(DATES[datidx].getTime(), false, outOffsets);
                    if (PATTERNS[patidx].equals("V")) {
                        // Short zone ID - should support roundtrip for canonical CLDR IDs
                        String canonicalID = TimeZone.getCanonicalID(tzids[tzidx]);
                        if (!outtz.getID().equals(canonicalID)) {
                            if (outtz.getID().equals("Etc/Unknown")) {
                                // short zone ID and "unk" is used as the fallback
                                if (REALLY_VERBOSE_LOG) {
                                    logln("Canonical round trip failed (probably as expected); tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", outtz=" + outtz.getID());
                                }
                            } else {
                                errln("Canonical round trip failed; tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", outtz=" + outtz.getID());
                            }
                        }
                    } else if (PATTERNS[patidx].equals("VV")) {
                        // Zone ID - full roundtrip support
                        if (!outtz.getID().equals(tzids[tzidx])) {
                            errln("Zone ID round trip failed; tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", outtz=" + outtz.getID());
                        }
                    } else if (PATTERNS[patidx].equals("VVV") || PATTERNS[patidx].equals("VVVV")) {
                        // Location: time zone rule must be preserved except
                        // zones not actually associated with a specific location.
                        String canonicalID = TimeZone.getCanonicalID(tzids[tzidx]);
                        if (canonicalID != null && !outtz.getID().equals(canonicalID)) {
                            // Canonical ID did not match - check the rules
                            boolean bFailure = false;
                            if ((tz instanceof BasicTimeZone) && (outtz instanceof BasicTimeZone)) {
                                boolean hasNoLocation = TimeZone.getRegion(tzids[tzidx]).equals("001");
                                bFailure = !hasNoLocation && !((BasicTimeZone) outtz).hasEquivalentTransitions(tz, low, high);
                            }
                            if (bFailure) {
                                errln("Canonical round trip failed; tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", outtz=" + outtz.getID());
                            } else if (REALLY_VERBOSE_LOG) {
                                logln("Canonical round trip failed (as expected); tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", outtz=" + outtz.getID());
                            }
                        }
                    } else {
                        boolean isOffsetFormat = (PATTERNS[patidx].charAt(0) == 'Z' || PATTERNS[patidx].charAt(0) == 'O' || PATTERNS[patidx].charAt(0) == 'X' || PATTERNS[patidx].charAt(0) == 'x');
                        boolean minutesOffset = false;
                        if (PATTERNS[patidx].charAt(0) == 'X' || PATTERNS[patidx].charAt(0) == 'x') {
                            minutesOffset = PATTERNS[patidx].length() <= 3;
                        }
                        if (!isOffsetFormat) {
                            // Check if localized GMT format is used as a fallback of name styles
                            int numDigits = 0;
                            for (int n = 0; n < tzstr.length(); n++) {
                                if (UCharacter.isDigit(tzstr.charAt(n))) {
                                    numDigits++;
                                }
                            }
                            isOffsetFormat = (numDigits > 0);
                        }
                        if (isOffsetFormat || tzstr.equals(localGMTString)) {
                            // Localized GMT or ISO: total offset (raw + dst) must be preserved.
                            int inOffset = inOffsets[0] + inOffsets[1];
                            int outOffset = outOffsets[0] + outOffsets[1];
                            int diff = outOffset - inOffset;
                            if (minutesOffset) {
                                diff = (diff / 60000) * 60000;
                            }
                            if (diff != 0) {
                                errln("Offset round trip failed; tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", inOffset=" + inOffset + ", outOffset=" + outOffset);
                            }
                        } else {
                            // Specific or generic: raw offset must be preserved.
                            if (inOffsets[0] != outOffsets[0]) {
                                if (JDKTZ && tzids[tzidx].startsWith("SystemV/")) {
                                    // ICU handles these zones as aliases of existing time zones
                                    if (REALLY_VERBOSE_LOG) {
                                        logln("Raw offset round trip failed; tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", inRawOffset=" + inOffsets[0] + ", outRawOffset=" + outOffsets[0]);
                                    }
                                } else {
                                    errln("Raw offset round trip failed; tz=" + tzids[tzidx] + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + ", inRawOffset=" + inOffsets[0] + ", outRawOffset=" + outOffsets[0]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : ULocale(android.icu.util.ULocale) Calendar(android.icu.util.Calendar) Date(java.util.Date) SimpleTimeZone(android.icu.util.SimpleTimeZone) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) SimpleTimeZone(android.icu.util.SimpleTimeZone) SimpleDateFormat(android.icu.text.SimpleDateFormat) ParsePosition(java.text.ParsePosition) Test(org.junit.Test)

Example 10 with BasicTimeZone

use of android.icu.util.BasicTimeZone in project Resurrection_packages_apps_Settings by ResurrectionRemix.

the class TimeZoneInfoPreferenceController method findNextDstTransition.

private TimeZoneTransition findNextDstTransition(TimeZone timeZone) {
    if (!(timeZone instanceof BasicTimeZone)) {
        return null;
    }
    final BasicTimeZone basicTimeZone = (BasicTimeZone) timeZone;
    TimeZoneTransition transition = basicTimeZone.getNextTransition(mDate.getTime(), /* inclusive */
    false);
    do {
        if (transition.getTo().getDSTSavings() != transition.getFrom().getDSTSavings()) {
            break;
        }
        transition = basicTimeZone.getNextTransition(transition.getTime(), /*inclusive */
        false);
    } while (transition != null);
    return transition;
}
Also used : BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition)

Aggregations

BasicTimeZone (android.icu.util.BasicTimeZone)23 TimeZoneTransition (android.icu.util.TimeZoneTransition)15 Test (org.junit.Test)14 TimeZone (android.icu.util.TimeZone)11 SimpleTimeZone (android.icu.util.SimpleTimeZone)8 VTimeZone (android.icu.util.VTimeZone)8 Date (java.util.Date)8 AnnualTimeZoneRule (android.icu.util.AnnualTimeZoneRule)6 InitialTimeZoneRule (android.icu.util.InitialTimeZoneRule)6 RuleBasedTimeZone (android.icu.util.RuleBasedTimeZone)6 Calendar (android.icu.util.Calendar)4 TimeZoneRule (android.icu.util.TimeZoneRule)4 DateTimeRule (android.icu.util.DateTimeRule)3 TimeArrayTimeZoneRule (android.icu.util.TimeArrayTimeZoneRule)3 SimpleDateFormat (android.icu.text.SimpleDateFormat)2 ULocale (android.icu.util.ULocale)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 InputStreamReader (java.io.InputStreamReader)2