Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5ea5f61 authored by Neil Fuller's avatar Neil Fuller Committed by android-build-merger
Browse files

Merge "Remove some usages of NitzData.isDst()"

am: 273986db

Change-Id: I3952f4dd77e542b2548f4544a90519bcf0ade3bb
parents 342856b1 273986db
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import java.util.Calendar;
import java.util.TimeZone;

/**
 * Represents NITZ data. Various static methods are provided to help with parsing and intepretation
 * Represents NITZ data. Various static methods are provided to help with parsing and interpretation
 * of NITZ data.
 *
 * {@hide}
@@ -153,7 +153,11 @@ public final class NitzData {

    /**
     * Returns the total offset to apply to the {@link #getCurrentTimeInMillis()} to arrive at a
     * local time.
     * local time. NITZ is limited in only being able to express total offsets in multiples of 15
     * minutes.
     *
     * <p>Note that some time zones change offset during the year for reasons other than "daylight
     * savings", e.g. for Ramadan. This is not well handled by most date / time APIs.
     */
    public int getLocalOffsetMillis() {
        return mZoneOffset;
@@ -162,7 +166,25 @@ public final class NitzData {
    /**
     * Returns the offset (already included in {@link #getLocalOffsetMillis()}) associated with
     * Daylight Savings Time (DST). This field is optional: {@code null} means the DST offset is
     * unknown.
     * unknown. NITZ is limited in only being able to express DST offsets in positive multiples of
     * one or two hours.
     *
     * <p>Callers should remember that standard time / DST is a matter of convention: it has
     * historically been assumed by NITZ and many date/time APIs that DST happens in the summer and
     * the "raw" offset will increase during this time, usually by one hour. However, the tzdb
     * maintainers have moved to different conventions on a country-by-country basis so that some
     * summer times are considered the "standard" time (i.e. in this model winter time is the "DST"
     * and a negative adjustment, usually of (negative) one hour.
     *
     * <p>There is nothing that says NITZ and tzdb need to treat DST conventions the same.
     *
     * <p>At the time of writing Android date/time APIs are sticking with the historic tzdb
     * convention that DST is used in summer time and is <em>always</em> a positive offset but this
     * could change in future. If Android or carriers change the conventions used then it might make
     * NITZ comparisons with tzdb information more error-prone.
     *
     * <p>See also {@link #getLocalOffsetMillis()} for other reasons besides DST that a local offset
     * may change.
     */
    public Integer getDstAdjustmentMillis() {
        return mDstOffset;
+1 −1
Original line number Diff line number Diff line
@@ -263,7 +263,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        }

        NitzData newNitzData = nitzSignal.getValue();
        boolean zeroOffsetNitz = newNitzData.getLocalOffsetMillis() == 0 && !newNitzData.isDst();
        boolean zeroOffsetNitz = newNitzData.getLocalOffsetMillis() == 0;
        return zeroOffsetNitz && !countryUsesUtc(isoCountryCode, nitzSignal);
    }

+36 −13
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import libcore.timezone.CountryTimeZones;
import libcore.timezone.CountryTimeZones.TimeZoneMapping;
import libcore.timezone.TimeZoneFinder;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@@ -314,30 +313,36 @@ public class TimeZoneLookupHelper {

    private static OffsetResult lookupByNitzStatic(NitzData nitzData) {
        int utcOffsetMillis = nitzData.getLocalOffsetMillis();
        boolean isDst = nitzData.isDst();
        long timeMillis = nitzData.getCurrentTimeInMillis();

        // Android NITZ time zone matching doesn't try to do a precise match using the DST offset
        // supplied by the carrier. It only considers whether or not the carrier suggests local time
        // is DST (if known). NITZ is limited in only being able to express DST offsets in whole
        // hours and the DST info is optional.
        Integer dstAdjustmentMillis = nitzData.getDstAdjustmentMillis();
        Boolean isDst = dstAdjustmentMillis == null ? null : dstAdjustmentMillis != 0;

        OffsetResult match = lookupByInstantOffsetDst(timeMillis, utcOffsetMillis, isDst);
        if (match == null) {
            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
            match = lookupByInstantOffsetDst(timeMillis, utcOffsetMillis, !isDst);
        if (match == null && isDst != null) {
            // This branch is extremely unlikely and could probably be removed. The match above will
            // have searched the entire tzdb for a zone with the same total offset and isDst state.
            // Here we try another match but use "null" for isDst to indicate that only the total
            // offset should be considered. If, by the end of this, there isn't a match then the
            // current offset suggested by the carrier must be highly unusual.
            match = lookupByInstantOffsetDst(timeMillis, utcOffsetMillis, null /* isDst */);
        }
        return match;
    }

    private static OffsetResult lookupByInstantOffsetDst(long timeMillis, int utcOffsetMillis,
            boolean isDst) {
        int rawOffset = utcOffsetMillis;
        if (isDst) {
            rawOffset -= MS_PER_HOUR;
        }
        String[] zones = TimeZone.getAvailableIDs(rawOffset);
            Boolean isDst) {

        String[] zones = TimeZone.getAvailableIDs();
        TimeZone match = null;
        Date d = new Date(timeMillis);
        boolean isOnlyMatch = true;
        for (String zone : zones) {
            TimeZone tz = TimeZone.getFrozenTimeZone(zone);
            if (tz.getOffset(timeMillis) == utcOffsetMillis && tz.inDaylightTime(d) == isDst) {
            if (offsetMatchesAtTime(tz, utcOffsetMillis, isDst, timeMillis)) {
                if (match == null) {
                    match = tz;
                } else {
@@ -353,6 +358,24 @@ public class TimeZoneLookupHelper {
        return new OffsetResult(match, isOnlyMatch);
    }

    /**
     * Returns {@code true} if the specified {@code totalOffset} and {@code isDst} would be valid in
     * the {@code timeZone} at time {@code whenMillis}. {@code totalOffetMillis} is always matched.
     * If {@code isDst} is {@code null} this means the DST state is unknown so DST state is ignored.
     * If {@code isDst} is not {@code null} then it is also matched.
     */
    private static boolean offsetMatchesAtTime(TimeZone timeZone, int totalOffsetMillis,
            Boolean isDst, long whenMillis) {
        int[] offsets = new int[2];
        timeZone.getOffset(whenMillis, false /* local */, offsets);

        if (totalOffsetMillis != (offsets[0] + offsets[1])) {
            return false;
        }

        return isDst == null || isDst == (offsets[1] != 0);
    }

    /**
     * Returns {@code true} if the supplied (lower-case) ISO country code is for a country known to
     * use a raw offset of zero from UTC at the time specified.