1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; 4 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; 5 import static android.os.Build.VERSION_CODES.LOLLIPOP; 6 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; 7 import static android.os.Build.VERSION_CODES.M; 8 import static android.os.Build.VERSION_CODES.P; 9 import static org.robolectric.RuntimeEnvironment.getApiLevel; 10 11 import java.util.Locale; 12 import libcore.icu.LocaleData; 13 import org.robolectric.annotation.Implementation; 14 import org.robolectric.annotation.Implements; 15 import org.robolectric.shadow.api.Shadow; 16 import org.robolectric.util.ReflectionHelpers; 17 18 /** 19 * Robolectric only supports en_US regardless of the default locale set in the JVM. 20 */ 21 @Implements(value = LocaleData.class, isInAndroidSdk = false) 22 public class ShadowLocaleData { 23 public static final String REAL_CLASS_NAME = "libcore.icu.LocaleData"; 24 25 @Implementation 26 public static LocaleData get(Locale locale) { 27 LocaleData localeData = (LocaleData) Shadow.newInstanceOf(REAL_CLASS_NAME); 28 if (locale == null) { 29 locale = Locale.getDefault(); 30 } 31 setEnUsLocaleData(localeData); 32 return localeData; 33 } 34 35 private static void setEnUsLocaleData(LocaleData localeData) { 36 localeData.amPm = new String[]{"AM", "PM"}; 37 localeData.eras = new String[]{"BC", "AD"}; 38 39 localeData.firstDayOfWeek = 1; 40 localeData.minimalDaysInFirstWeek = 1; 41 42 localeData.longMonthNames = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; 43 localeData.shortMonthNames = new String[]{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 44 45 if (getApiLevel() >= JELLY_BEAN_MR1) { 46 localeData.tinyMonthNames = new String[]{"J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"}; 47 localeData.tinyStandAloneMonthNames = localeData.tinyMonthNames; 48 localeData.tinyWeekdayNames = new String[]{"", "S", "M", "T", "W", "T", "F", "S"}; 49 localeData.tinyStandAloneWeekdayNames = localeData.tinyWeekdayNames; 50 51 localeData.yesterday = "Yesterday"; 52 localeData.today = "Today"; 53 localeData.tomorrow = "Tomorrow"; 54 } 55 56 localeData.longStandAloneMonthNames = localeData.longMonthNames; 57 localeData.shortStandAloneMonthNames = localeData.shortMonthNames; 58 59 localeData.longWeekdayNames = new String[]{"", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 60 localeData.shortWeekdayNames = new String[]{"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 61 62 localeData.longStandAloneWeekdayNames = localeData.longWeekdayNames; 63 localeData.shortStandAloneWeekdayNames = localeData.shortWeekdayNames; 64 65 localeData.fullTimeFormat = "h:mm:ss a zzzz"; 66 localeData.longTimeFormat = "h:mm:ss a z"; 67 localeData.mediumTimeFormat = "h:mm:ss a"; 68 localeData.shortTimeFormat = "h:mm a"; 69 70 if (getApiLevel() >= M) { 71 localeData.timeFormat_hm = "h:mm a"; 72 localeData.timeFormat_Hm = "HH:mm"; 73 } else if (getApiLevel() >= JELLY_BEAN_MR2) { 74 ReflectionHelpers.setField(localeData, "timeFormat12", "h:mm a"); 75 ReflectionHelpers.setField(localeData, "timeFormat24", "HH:mm"); 76 } 77 78 localeData.fullDateFormat = "EEEE, MMMM d, y"; 79 localeData.longDateFormat = "MMMM d, y"; 80 localeData.mediumDateFormat = "MMM d, y"; 81 localeData.shortDateFormat = "M/d/yy"; 82 83 localeData.zeroDigit = '0'; 84 localeData.decimalSeparator = '.'; 85 localeData.groupingSeparator = ','; 86 localeData.patternSeparator = ';'; 87 88 if (getApiLevel() >= LOLLIPOP_MR1) { 89 // Lollipop MR1 uses a String 90 localeData.percent = "%"; 91 } else { 92 // Upto Lollipop was a char 93 ReflectionHelpers.setField(localeData, "percent", '%'); 94 } 95 96 // BEGIN-INTERNAL 97 if (getApiLevel() >= P) { 98 // P uses a String 99 localeData.perMill = ""; 100 } else { 101 // Upto P was a char 102 ReflectionHelpers.setField(localeData, "perMill", ''); 103 } 104 // END-INTERNAL 105 106 localeData.monetarySeparator = '.'; 107 108 if (getApiLevel() >= LOLLIPOP) { 109 // Lollipop uses a String 110 localeData.minusSign = "-"; 111 } else { 112 // Upto KitKat was a char 113 ReflectionHelpers.setField(localeData, "minusSign", '-'); 114 } 115 116 localeData.exponentSeparator = "E"; 117 localeData.infinity = "\u221E"; 118 localeData.NaN = "NaN"; 119 120 localeData.currencySymbol = "$"; 121 localeData.internationalCurrencySymbol = "USD"; 122 123 localeData.numberPattern = "\u0023,\u0023\u00230.\u0023\u0023\u0023"; 124 localeData.integerPattern = "\u0023,\u0023\u00230"; 125 localeData.currencyPattern = "\u00A4\u0023,\u0023\u00230.00;(\u00A4\u0023,\u0023\u00230.00)"; 126 localeData.percentPattern = "\u0023,\u0023\u00230%"; 127 } 128 } 129