Loading core/java/android/text/format/DateFormat.java +17 −1 Original line number Diff line number Diff line Loading @@ -17,10 +17,14 @@ package android.text.format; import android.annotation.NonNull; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.icu.text.DateFormatSymbols; import android.icu.text.DateTimePatternGenerator; import android.os.Build; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.text.Spanned; Loading Loading @@ -158,6 +162,16 @@ public class DateFormat { private static Locale sIs24HourLocale; private static boolean sIs24Hour; /** * {@link #getBestDateTimePattern(Locale, String)} does not allow non-consecutive repeated * symbol in the skeleton. For example, please use a skeleton of {@code "jmm"} or * {@code "hmma"} instead of {@code "ahmma"} or {@code "jmma"}, because the field 'j' could * mean using 12-hour in some locales and, in this case, is duplicated as the 'a' field. */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) static final long DISALLOW_DUPLICATE_FIELD_IN_SKELETON = 170233598L; /** * Returns true if times should be formatted as 24 hour times, false if times should be * formatted as 12 hour (AM/PM) times. Based on the user's chosen locale and other preferences. Loading Loading @@ -251,7 +265,9 @@ public class DateFormat { */ public static String getBestDateTimePattern(Locale locale, String skeleton) { DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale); return dtpg.getBestPattern(skeleton); boolean allowDuplicateFields = !CompatChanges.isChangeEnabled( DISALLOW_DUPLICATE_FIELD_IN_SKELETON); return dtpg.getBestPattern(skeleton, allowDuplicateFields); } /** Loading core/tests/coretests/src/android/text/format/DateFormatTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -21,13 +21,19 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.compat.testing.PlatformCompatChangeRule; import android.icu.text.DateFormatSymbols; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import java.util.Arrays; Loading @@ -38,6 +44,9 @@ import java.util.Locale; @RunWith(AndroidJUnit4.class) public class DateFormatTest { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @Test public void testHasDesignator() { assertTrue(DateFormat.hasDesignator("hh:mm:ss", DateFormat.MINUTE)); Loading Loading @@ -135,4 +144,29 @@ public class DateFormatTest { private static String best(Locale l, String skeleton) { return DateFormat.getBestDateTimePattern(l, skeleton); } @Test @EnableCompatChanges({DateFormat.DISALLOW_DUPLICATE_FIELD_IN_SKELETON}) public void testGetBestDateTimePattern_disableDuplicateField() { assertIllegalArgumentException(Locale.US, "jmma"); assertIllegalArgumentException(Locale.US, "ahmma"); } @Test @DisableCompatChanges({DateFormat.DISALLOW_DUPLICATE_FIELD_IN_SKELETON}) public void testGetBestDateTimePattern_enableDuplicateField() { // en-US uses 12-hour format by default. assertEquals("h:mm a", DateFormat.getBestDateTimePattern(Locale.US, "jmma")); assertEquals("h:mm a", DateFormat.getBestDateTimePattern(Locale.US, "ahmma")); } private static void assertIllegalArgumentException(Locale l, String skeleton) { try { DateFormat.getBestDateTimePattern(l, skeleton); fail("getBestDateTimePattern() does not fail with Locale: " + l + " skeleton: " + skeleton); } catch (IllegalArgumentException expected) { // ignored } } } Loading
core/java/android/text/format/DateFormat.java +17 −1 Original line number Diff line number Diff line Loading @@ -17,10 +17,14 @@ package android.text.format; import android.annotation.NonNull; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.icu.text.DateFormatSymbols; import android.icu.text.DateTimePatternGenerator; import android.os.Build; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.text.Spanned; Loading Loading @@ -158,6 +162,16 @@ public class DateFormat { private static Locale sIs24HourLocale; private static boolean sIs24Hour; /** * {@link #getBestDateTimePattern(Locale, String)} does not allow non-consecutive repeated * symbol in the skeleton. For example, please use a skeleton of {@code "jmm"} or * {@code "hmma"} instead of {@code "ahmma"} or {@code "jmma"}, because the field 'j' could * mean using 12-hour in some locales and, in this case, is duplicated as the 'a' field. */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) static final long DISALLOW_DUPLICATE_FIELD_IN_SKELETON = 170233598L; /** * Returns true if times should be formatted as 24 hour times, false if times should be * formatted as 12 hour (AM/PM) times. Based on the user's chosen locale and other preferences. Loading Loading @@ -251,7 +265,9 @@ public class DateFormat { */ public static String getBestDateTimePattern(Locale locale, String skeleton) { DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale); return dtpg.getBestPattern(skeleton); boolean allowDuplicateFields = !CompatChanges.isChangeEnabled( DISALLOW_DUPLICATE_FIELD_IN_SKELETON); return dtpg.getBestPattern(skeleton, allowDuplicateFields); } /** Loading
core/tests/coretests/src/android/text/format/DateFormatTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -21,13 +21,19 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.compat.testing.PlatformCompatChangeRule; import android.icu.text.DateFormatSymbols; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import java.util.Arrays; Loading @@ -38,6 +44,9 @@ import java.util.Locale; @RunWith(AndroidJUnit4.class) public class DateFormatTest { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @Test public void testHasDesignator() { assertTrue(DateFormat.hasDesignator("hh:mm:ss", DateFormat.MINUTE)); Loading Loading @@ -135,4 +144,29 @@ public class DateFormatTest { private static String best(Locale l, String skeleton) { return DateFormat.getBestDateTimePattern(l, skeleton); } @Test @EnableCompatChanges({DateFormat.DISALLOW_DUPLICATE_FIELD_IN_SKELETON}) public void testGetBestDateTimePattern_disableDuplicateField() { assertIllegalArgumentException(Locale.US, "jmma"); assertIllegalArgumentException(Locale.US, "ahmma"); } @Test @DisableCompatChanges({DateFormat.DISALLOW_DUPLICATE_FIELD_IN_SKELETON}) public void testGetBestDateTimePattern_enableDuplicateField() { // en-US uses 12-hour format by default. assertEquals("h:mm a", DateFormat.getBestDateTimePattern(Locale.US, "jmma")); assertEquals("h:mm a", DateFormat.getBestDateTimePattern(Locale.US, "ahmma")); } private static void assertIllegalArgumentException(Locale l, String skeleton) { try { DateFormat.getBestDateTimePattern(l, skeleton); fail("getBestDateTimePattern() does not fail with Locale: " + l + " skeleton: " + skeleton); } catch (IllegalArgumentException expected) { // ignored } } }