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

Commit 072143a0 authored by Neil Fuller's avatar Neil Fuller
Browse files

Move isDefaultOkForCountryTimeZoneDetection

Push the CountryTimeZones.isDefaultOkForCountryTimeZoneDetection(long)
method up to telephony code. When written it was unclear whether the
method was going to be useful for future time zone detection code but
it was "cheap" to put it in the libcore code / Core Platform API. It is
still unclear whether it will be used but it's far from certain and
every API method will carry a support cost in future so pushing it up
to the one user and making the libcore code more general makes more
sense.

This commit also contains an improvement to
CountryTimeZones.getTimeZone() logic and makes it part of the
Core Platform API.

Bug: 139928367
Test: atest com.android.internal.telephony.TimeZoneLookupHelperTest
Change-Id: I954a42208a013fd009f1ad6541b6c98d7cc94f6f
parent ccbfdb90
Loading
Loading
Loading
Loading
+50 −4
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@ import android.icu.util.TimeZone;
import android.text.TextUtils;

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;

/**
@@ -225,11 +227,55 @@ public class TimeZoneLookupHelper {
            return null;
        }

        List<TimeZoneMapping> effectiveTimeZoneMappings =
                countryTimeZones.getEffectiveTimeZoneMappingsAt(whenMillis);
        boolean multipleZonesInCountry = effectiveTimeZoneMappings.size() > 1;
        boolean defaultOkForCountryTimeZoneDetection = isDefaultOkForCountryTimeZoneDetection(
                countryTimeZones.getDefaultTimeZone(), effectiveTimeZoneMappings, whenMillis);
        return new CountryResult(
                countryTimeZones.getDefaultTimeZoneId(),
                countryTimeZones.getEffectiveTimeZoneMappingsAt(whenMillis).size() > 1,
                countryTimeZones.isDefaultOkForCountryTimeZoneDetection(whenMillis),
                whenMillis);
                countryTimeZones.getDefaultTimeZoneId(), multipleZonesInCountry,
                defaultOkForCountryTimeZoneDetection, whenMillis);
    }

    /**
     * Returns {@code true} if the default time zone for the country is either the only zone used or
     * if it has the same offsets as all other zones used by the country <em>at the specified time
     * </em> making the default equivalent to all other zones used by the country <em>at that time
     * </em>.
     */
    private static boolean isDefaultOkForCountryTimeZoneDetection(
            TimeZone countryDefault, List<TimeZoneMapping> timeZoneMappings, long whenMillis) {
        if (timeZoneMappings.isEmpty()) {
            // Should never happen unless there's been an error loading the data.
            return false;
        } else if (timeZoneMappings.size() == 1) {
            // The default is the only zone so it's a good candidate.
            return true;
        } else {
            if (countryDefault == null) {
                return false;
            }

            String countryDefaultId = countryDefault.getID();
            int countryDefaultOffset = countryDefault.getOffset(whenMillis);
            for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
                if (timeZoneMapping.timeZoneId.equals(countryDefaultId)) {
                    continue;
                }

                TimeZone timeZone = timeZoneMapping.getTimeZone();
                if (timeZone == null) {
                    continue;
                }

                int candidateOffset = timeZone.getOffset(whenMillis);
                if (countryDefaultOffset != candidateOffset) {
                    // Multiple different offsets means the default should not be used.
                    return false;
                }
            }
            return true;
        }
    }

    /**