Search in sources :

Example 11 with TimeZoneTransition

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

the class TimeZoneGenericNames method formatGenericNonLocationName.

/**
 * Private method to get a generic string, with fallback logics involved,
 * that is,
 *
 * 1. If a generic non-location string is available for the zone, return it.
 * 2. If a generic non-location string is associated with a meta zone and
 *    the zone never use daylight time around the given date, use the standard
 *    string (if available).
 * 3. If a generic non-location string is associated with a meta zone and
 *    the offset at the given time is different from the preferred zone for the
 *    current locale, then return the generic partial location string (if available)
 * 4. If a generic non-location string is not available, use generic location
 *    string.
 *
 * @param tz the requested time zone
 * @param date the date
 * @param type the generic name type, either LONG or SHORT
 * @return the name used for a generic name type, which could be the
 * generic name, or the standard name (if the zone does not observes DST
 * around the date), or the partial location name.
 */
private String formatGenericNonLocationName(TimeZone tz, GenericNameType type, long date) {
    assert (type == GenericNameType.LONG || type == GenericNameType.SHORT);
    String tzID = ZoneMeta.getCanonicalCLDRID(tz);
    if (tzID == null) {
        return null;
    }
    // Try to get a name from time zone first
    NameType nameType = (type == GenericNameType.LONG) ? NameType.LONG_GENERIC : NameType.SHORT_GENERIC;
    String name = _tznames.getTimeZoneDisplayName(tzID, nameType);
    if (name != null) {
        return name;
    }
    // Try meta zone
    String mzID = _tznames.getMetaZoneID(tzID, date);
    if (mzID != null) {
        boolean useStandard = false;
        int[] offsets = { 0, 0 };
        tz.getOffset(date, false, offsets);
        if (offsets[1] == 0) {
            useStandard = true;
            // Check if the zone actually uses daylight saving time around the time
            if (tz instanceof BasicTimeZone) {
                BasicTimeZone btz = (BasicTimeZone) tz;
                TimeZoneTransition before = btz.getPreviousTransition(date, true);
                if (before != null && (date - before.getTime() < DST_CHECK_RANGE) && before.getFrom().getDSTSavings() != 0) {
                    useStandard = false;
                } else {
                    TimeZoneTransition after = btz.getNextTransition(date, false);
                    if (after != null && (after.getTime() - date < DST_CHECK_RANGE) && after.getTo().getDSTSavings() != 0) {
                        useStandard = false;
                    }
                }
            } else {
                // If not BasicTimeZone... only if the instance is not an ICU's implementation.
                // We may get a wrong answer in edge case, but it should practically work OK.
                int[] tmpOffsets = new int[2];
                tz.getOffset(date - DST_CHECK_RANGE, false, tmpOffsets);
                if (tmpOffsets[1] != 0) {
                    useStandard = false;
                } else {
                    tz.getOffset(date + DST_CHECK_RANGE, false, tmpOffsets);
                    if (tmpOffsets[1] != 0) {
                        useStandard = false;
                    }
                }
            }
        }
        if (useStandard) {
            NameType stdNameType = (nameType == NameType.LONG_GENERIC) ? NameType.LONG_STANDARD : NameType.SHORT_STANDARD;
            String stdName = _tznames.getDisplayName(tzID, stdNameType, date);
            if (stdName != null) {
                name = stdName;
                // TODO: revisit this issue later
                // In CLDR, a same display name is used for both generic and standard
                // for some meta zones in some locales.  This looks like a data bugs.
                // For now, we check if the standard name is different from its generic
                // name below.
                String mzGenericName = _tznames.getMetaZoneDisplayName(mzID, nameType);
                if (stdName.equalsIgnoreCase(mzGenericName)) {
                    name = null;
                }
            }
        }
        if (name == null) {
            // Get a name from meta zone
            String mzName = _tznames.getMetaZoneDisplayName(mzID, nameType);
            if (mzName != null) {
                // Check if we need to use a partial location format.
                // This check is done by comparing offset with the meta zone's
                // golden zone at the given date.
                String goldenID = _tznames.getReferenceZoneID(mzID, getTargetRegion());
                if (goldenID != null && !goldenID.equals(tzID)) {
                    TimeZone goldenZone = TimeZone.getFrozenTimeZone(goldenID);
                    int[] offsets1 = { 0, 0 };
                    // Check offset in the golden zone with wall time.
                    // With getOffset(date, false, offsets1),
                    // you may get incorrect results because of time overlap at DST->STD
                    // transition.
                    goldenZone.getOffset(date + offsets[0] + offsets[1], true, offsets1);
                    if (offsets[0] != offsets1[0] || offsets[1] != offsets1[1]) {
                        // Now we need to use a partial location format.
                        name = getPartialLocationName(tzID, mzID, (nameType == NameType.LONG_GENERIC), mzName);
                    } else {
                        name = mzName;
                    }
                } else {
                    name = mzName;
                }
            }
        }
    }
    return name;
}
Also used : BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) NameType(android.icu.text.TimeZoneNames.NameType)

Example 12 with TimeZoneTransition

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

the class OlsonTimeZone method setRawOffset.

/* (non-Javadoc)
     * @see android.icu.util.TimeZone#setRawOffset(int)
     */
@Override
public void setRawOffset(int offsetMillis) {
    if (isFrozen()) {
        throw new UnsupportedOperationException("Attempt to modify a frozen OlsonTimeZone instance.");
    }
    if (getRawOffset() == offsetMillis) {
        return;
    }
    long current = System.currentTimeMillis();
    if (current < finalStartMillis) {
        SimpleTimeZone stz = new SimpleTimeZone(offsetMillis, getID());
        boolean bDst = useDaylightTime();
        if (bDst) {
            TimeZoneRule[] currentRules = getSimpleTimeZoneRulesNear(current);
            if (currentRules.length != 3) {
                // DST was observed at the beginning of this year, so useDaylightTime
                // returned true.  getSimpleTimeZoneRulesNear requires at least one
                // future transition for making a pair of rules.  This implementation
                // rolls back the time before the latest offset transition.
                TimeZoneTransition tzt = getPreviousTransition(current, false);
                if (tzt != null) {
                    currentRules = getSimpleTimeZoneRulesNear(tzt.getTime() - 1);
                }
            }
            if (currentRules.length == 3 && (currentRules[1] instanceof AnnualTimeZoneRule) && (currentRules[2] instanceof AnnualTimeZoneRule)) {
                // A pair of AnnualTimeZoneRule
                AnnualTimeZoneRule r1 = (AnnualTimeZoneRule) currentRules[1];
                AnnualTimeZoneRule r2 = (AnnualTimeZoneRule) currentRules[2];
                DateTimeRule start, end;
                int offset1 = r1.getRawOffset() + r1.getDSTSavings();
                int offset2 = r2.getRawOffset() + r2.getDSTSavings();
                int sav;
                if (offset1 > offset2) {
                    start = r1.getRule();
                    end = r2.getRule();
                    sav = offset1 - offset2;
                } else {
                    start = r2.getRule();
                    end = r1.getRule();
                    sav = offset2 - offset1;
                }
                // getSimpleTimeZoneRulesNear always return rules using DOW / WALL_TIME
                stz.setStartRule(start.getRuleMonth(), start.getRuleWeekInMonth(), start.getRuleDayOfWeek(), start.getRuleMillisInDay());
                stz.setEndRule(end.getRuleMonth(), end.getRuleWeekInMonth(), end.getRuleDayOfWeek(), end.getRuleMillisInDay());
                // set DST saving amount and start year
                stz.setDSTSavings(sav);
            } else {
                // This could only happen if last rule is DST
                // and the rule used forever.  For example, Asia/Dhaka
                // in tzdata2009i stays in DST forever.
                // Hack - set DST starting at midnight on Jan 1st,
                // ending 23:59:59.999 on Dec 31st
                stz.setStartRule(0, 1, 0);
                stz.setEndRule(11, 31, Grego.MILLIS_PER_DAY - 1);
            }
        }
        int[] fields = Grego.timeToFields(current, null);
        finalStartYear = fields[0];
        finalStartMillis = Grego.fieldsToDay(fields[0], 0, 1);
        if (bDst) {
            // we probably do not need to set start year of final rule
            // to finalzone itself, but we always do this for now.
            stz.setStartYear(finalStartYear);
        }
        finalZone = stz;
    } else {
        finalZone.setRawOffset(offsetMillis);
    }
    transitionRulesInitialized = false;
}
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) TimeZoneTransition(android.icu.util.TimeZoneTransition) SimpleTimeZone(android.icu.util.SimpleTimeZone) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule)

Example 13 with TimeZoneTransition

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

the class TimeZoneRuleTest method TestVTimeZoneCoverage.

/*
     * API coverage test for VTimeZone
     */
@Test
public void TestVTimeZoneCoverage() {
    final String TZID = "Europe/Moscow";
    BasicTimeZone otz = (BasicTimeZone) TimeZone.getTimeZone(TZID, TimeZone.TIMEZONE_ICU);
    VTimeZone vtz = VTimeZone.create(TZID);
    // getOffset(era, year, month, day, dayOfWeek, milliseconds)
    int offset1 = otz.getOffset(GregorianCalendar.AD, 2007, Calendar.JULY, 1, Calendar.SUNDAY, 0);
    int offset2 = vtz.getOffset(GregorianCalendar.AD, 2007, Calendar.JULY, 1, Calendar.SUNDAY, 0);
    if (offset1 != offset2) {
        errln("FAIL: getOffset(int,int,int,int,int,int) returned different results in VTimeZone and OlsonTimeZone");
    }
    // getOffset(date, local, offsets)
    int[] offsets1 = new int[2];
    int[] offsets2 = new int[2];
    long t = System.currentTimeMillis();
    otz.getOffset(t, false, offsets1);
    vtz.getOffset(t, false, offsets2);
    if (offsets1[0] != offsets2[0] || offsets1[1] != offsets2[1]) {
        errln("FAIL: getOffset(long,boolean,int[]) returned different results in VTimeZone and OlsonTimeZone");
    }
    // getRawOffset
    if (otz.getRawOffset() != vtz.getRawOffset()) {
        errln("FAIL: getRawOffset returned different results in VTimeZone and OlsonTimeZone");
    }
    // inDaylightTime
    Date d = new Date();
    if (otz.inDaylightTime(d) != vtz.inDaylightTime(d)) {
        errln("FAIL: inDaylightTime returned different results in VTimeZone and OlsonTimeZone");
    }
    // useDaylightTime
    if (otz.useDaylightTime() != vtz.useDaylightTime()) {
        errln("FAIL: useDaylightTime returned different results in VTimeZone and OlsonTimeZone");
    }
    // setRawOffset
    final int RAW = -10 * HOUR;
    VTimeZone tmpvtz = (VTimeZone) vtz.clone();
    tmpvtz.setRawOffset(RAW);
    if (tmpvtz.getRawOffset() != RAW) {
        logln("setRawOffset is implemented");
    }
    // hasSameRules
    boolean bSame = otz.hasSameRules(vtz);
    logln("OlsonTimeZone#hasSameRules(VTimeZone) should return false always for now - actual: " + bSame);
    // getTZURL/setTZURL
    final String TZURL = "http://icu-project.org/timezone";
    String tzurl = vtz.getTZURL();
    if (tzurl != null) {
        errln("FAIL: getTZURL returned non-null value");
    }
    vtz.setTZURL(TZURL);
    tzurl = vtz.getTZURL();
    if (!TZURL.equals(tzurl)) {
        errln("FAIL: URL returned by getTZURL does not match the one set by setTZURL");
    }
    // getLastModified/setLastModified
    Date lastmod = vtz.getLastModified();
    if (lastmod != null) {
        errln("FAIL: getLastModified returned non-null value");
    }
    Date newdate = new Date();
    vtz.setLastModified(newdate);
    lastmod = vtz.getLastModified();
    if (!newdate.equals(lastmod)) {
        errln("FAIL: Date returned by getLastModified does not match the one set by setLastModified");
    }
    // getNextTransition/getPreviousTransition
    long base = getUTCMillis(2007, Calendar.JULY, 1);
    TimeZoneTransition tzt1 = otz.getNextTransition(base, true);
    TimeZoneTransition tzt2 = vtz.getNextTransition(base, true);
    if (tzt1.equals(tzt2)) {
        errln("FAIL: getNextTransition returned different results in VTimeZone and OlsonTimeZone");
    }
    tzt1 = otz.getPreviousTransition(base, false);
    tzt2 = vtz.getPreviousTransition(base, false);
    if (tzt1.equals(tzt2)) {
        errln("FAIL: getPreviousTransition returned different results in VTimeZone and OlsonTimeZone");
    }
    // hasEquivalentTransitions
    long time1 = getUTCMillis(1950, Calendar.JANUARY, 1);
    long time2 = getUTCMillis(2020, Calendar.JANUARY, 1);
    if (!vtz.hasEquivalentTransitions(otz, time1, time2)) {
        errln("FAIL: hasEquivalentTransitons returned false for the same time zone");
    }
    // getTimeZoneRules
    TimeZoneRule[] rulesetAll = vtz.getTimeZoneRules();
    TimeZoneRule[] ruleset1 = vtz.getTimeZoneRules(time1);
    TimeZoneRule[] ruleset2 = vtz.getTimeZoneRules(time2);
    if (rulesetAll.length < ruleset1.length || ruleset1.length < ruleset2.length) {
        errln("FAIL: Number of rules returned by getRules is invalid");
    }
    int[] offsets_vtzc = new int[2];
    VTimeZone vtzc = VTimeZone.create("PST");
    vtzc.getOffsetFromLocal(Calendar.getInstance(vtzc).getTimeInMillis(), VTimeZone.LOCAL_STD, VTimeZone.LOCAL_STD, offsets_vtzc);
    if (offsets_vtzc[0] > offsets_vtzc[1]) {
        errln("Error getOffsetFromLocal()");
    }
}
Also used : InitialTimeZoneRule(android.icu.util.InitialTimeZoneRule) TimeArrayTimeZoneRule(android.icu.util.TimeArrayTimeZoneRule) AnnualTimeZoneRule(android.icu.util.AnnualTimeZoneRule) TimeZoneRule(android.icu.util.TimeZoneRule) BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition) VTimeZone(android.icu.util.VTimeZone) Date(java.util.Date) Test(org.junit.Test)

Example 14 with TimeZoneTransition

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

the class TimeZoneRuleTest method TestVTimeZoneRoundTrip.

/*
     * Write out time zone rules of OlsonTimeZone into VTIMEZONE format, create a new
     * VTimeZone from the VTIMEZONE data, then compare transitions
     */
@Test
public void TestVTimeZoneRoundTrip() {
    long startTime = getUTCMillis(1850, Calendar.JANUARY, 1);
    long endTime = getUTCMillis(2050, Calendar.JANUARY, 1);
    String[] tzids = getTestZIDs();
    for (int i = 0; i < tzids.length; i++) {
        BasicTimeZone olsontz = (BasicTimeZone) TimeZone.getTimeZone(tzids[i], TimeZone.TIMEZONE_ICU);
        VTimeZone vtz_org = VTimeZone.create(tzids[i]);
        vtz_org.setTZURL("http://source.icu-project.org/timezone");
        vtz_org.setLastModified(new Date());
        VTimeZone vtz_new = null;
        try {
            // Write out VTIMEZONE
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(baos);
            vtz_org.write(writer);
            writer.close();
            byte[] vtzdata = baos.toByteArray();
            // Read VTIMEZONE
            ByteArrayInputStream bais = new ByteArrayInputStream(vtzdata);
            InputStreamReader reader = new InputStreamReader(bais);
            vtz_new = VTimeZone.create(reader);
            reader.close();
            // Write out VTIMEZONE one more time
            ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
            OutputStreamWriter writer1 = new OutputStreamWriter(baos1);
            vtz_new.write(writer1);
            writer1.close();
            byte[] vtzdata1 = baos1.toByteArray();
            // Make sure VTIMEZONE data is exactly same with the first one
            if (vtzdata.length != vtzdata1.length) {
                errln("FAIL: different VTIMEZONE data length");
            }
            for (int j = 0; j < vtzdata.length; j++) {
                if (vtzdata[j] != vtzdata1[j]) {
                    errln("FAIL: different VTIMEZONE data");
                    break;
                }
            }
        } catch (IOException ioe) {
            errln("FAIL: IO error while writing/reading VTIMEZONE data");
        }
        // VTIMEZONE.
        if (vtz_new.getOffset(startTime) != olsontz.getOffset(startTime)) {
            errln("FAIL: VTimeZone for " + tzids[i] + " is not equivalent to its OlsonTimeZone corresponding at " + startTime);
        }
        TimeZoneTransition tzt = olsontz.getNextTransition(startTime, false);
        if (tzt != null) {
            if (!vtz_new.hasEquivalentTransitions(olsontz, tzt.getTime(), endTime, true)) {
                int maxDelta = 1000;
                if (!hasEquivalentTransitions(vtz_new, olsontz, tzt.getTime() + maxDelta, endTime, true, maxDelta)) {
                    errln("FAIL: VTimeZone for " + tzids[i] + " is not equivalent to its OlsonTimeZone corresponding.");
                } else {
                    logln("VTimeZone for " + tzids[i] + " differs from its OlsonTimeZone corresponding with maximum transition time delta - " + maxDelta);
                }
            }
            if (!vtz_new.hasEquivalentTransitions(olsontz, tzt.getTime(), endTime, false)) {
                logln("VTimeZone for " + tzids[i] + " is not equivalent to its OlsonTimeZone corresponding in strict comparison mode.");
            }
        }
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) VTimeZone(android.icu.util.VTimeZone) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Date(java.util.Date) BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition) ByteArrayInputStream(java.io.ByteArrayInputStream) OutputStreamWriter(java.io.OutputStreamWriter) Test(org.junit.Test)

Example 15 with TimeZoneTransition

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

the class TimeZoneRuleTest method compareTransitionsAscending.

/*
     * Compare all time transitions in 2 time zones in the specified time range in ascending order
     */
private void compareTransitionsAscending(TimeZone tz1, TimeZone tz2, long start, long end, boolean inclusive) {
    BasicTimeZone z1 = (BasicTimeZone) tz1;
    BasicTimeZone z2 = (BasicTimeZone) tz2;
    String zid1 = tz1.getID();
    String zid2 = tz2.getID();
    long time = start;
    while (true) {
        TimeZoneTransition tzt1 = z1.getNextTransition(time, inclusive);
        TimeZoneTransition tzt2 = z2.getNextTransition(time, inclusive);
        boolean inRange1 = false;
        boolean inRange2 = false;
        if (tzt1 != null) {
            if (tzt1.getTime() < end || (inclusive && tzt1.getTime() == end)) {
                inRange1 = true;
            }
        }
        if (tzt2 != null) {
            if (tzt2.getTime() < end || (inclusive && tzt2.getTime() == end)) {
                inRange2 = true;
            }
        }
        if (!inRange1 && !inRange2) {
            // No more transition in the range
            break;
        }
        if (!inRange1) {
            errln("FAIL: " + zid1 + " does not have any transitions after " + time + " before " + end);
            break;
        }
        if (!inRange2) {
            errln("FAIL: " + zid2 + " does not have any transitions after " + time + " before " + end);
            break;
        }
        if (tzt1.getTime() != tzt2.getTime()) {
            errln("FAIL: First transition after " + time + " " + zid1 + "[" + tzt1.getTime() + "] " + zid2 + "[" + tzt2.getTime() + "]");
            break;
        }
        time = tzt1.getTime();
        if (inclusive) {
            time++;
        }
    }
}
Also used : BasicTimeZone(android.icu.util.BasicTimeZone) TimeZoneTransition(android.icu.util.TimeZoneTransition)

Aggregations

TimeZoneTransition (android.icu.util.TimeZoneTransition)22 BasicTimeZone (android.icu.util.BasicTimeZone)17 Test (org.junit.Test)8 TimeZone (android.icu.util.TimeZone)6 AnnualTimeZoneRule (android.icu.util.AnnualTimeZoneRule)5 InitialTimeZoneRule (android.icu.util.InitialTimeZoneRule)5 TimeZoneRule (android.icu.util.TimeZoneRule)5 Date (java.util.Date)5 Calendar (android.icu.util.Calendar)4 SimpleTimeZone (android.icu.util.SimpleTimeZone)4 TimeArrayTimeZoneRule (android.icu.util.TimeArrayTimeZoneRule)4 VTimeZone (android.icu.util.VTimeZone)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 InputStreamReader (java.io.InputStreamReader)2 OutputStreamWriter (java.io.OutputStreamWriter)2 Instant (java.time.Instant)2 ZoneOffset (java.time.ZoneOffset)2 ZoneOffsetTransition (java.time.zone.ZoneOffsetTransition)2