1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 2008-2015, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 */ 9 package com.ibm.icu.dev.test.localespi; 10 11 import java.text.DateFormat; 12 import java.text.ParseException; 13 import java.util.Calendar; 14 import java.util.Date; 15 import java.util.Locale; 16 17 import org.junit.Test; 18 import org.junit.runner.RunWith; 19 import org.junit.runners.JUnit4; 20 21 import com.ibm.icu.dev.test.TestFmwk; 22 import com.ibm.icu.impl.jdkadapter.CalendarICU; 23 import com.ibm.icu.util.ULocale; 24 25 @RunWith(JUnit4.class) 26 public class DateFormatTest extends TestFmwk { 27 /* 28 * Check if getInstance returns the ICU implementation. 29 */ 30 @Test 31 public void TestGetInstance() { 32 for (Locale loc : DateFormat.getAvailableLocales()) { 33 if (TestUtil.isExcluded(loc)) { 34 logln("Skipped " + loc); 35 continue; 36 } 37 checkGetInstance(DateFormat.FULL, DateFormat.LONG, loc); 38 checkGetInstance(DateFormat.MEDIUM, -1, loc); 39 checkGetInstance(1, DateFormat.SHORT, loc); 40 } 41 } 42 43 private void checkGetInstance(int dstyle, int tstyle, Locale loc) { 44 String method[] = new String[1]; 45 DateFormat df = getJDKInstance(dstyle, tstyle, loc, method); 46 47 boolean isIcuImpl = (df instanceof com.ibm.icu.impl.jdkadapter.SimpleDateFormatICU); 48 49 if (TestUtil.isICUExtendedLocale(loc)) { 50 if (!isIcuImpl) { 51 errln("FAIL: " + method[0] + " returned JDK DateFormat for locale " + loc); 52 } 53 } else { 54 if (isIcuImpl) { 55 logln("INFO: " + method[0] + " returned ICU DateFormat for locale " + loc); 56 } 57 Locale iculoc = TestUtil.toICUExtendedLocale(loc); 58 DateFormat dfIcu = getJDKInstance(dstyle, tstyle, iculoc, null); 59 if (isIcuImpl) { 60 if (!df.equals(dfIcu)) { 61 errln("FAIL: " + method[0] + " returned ICU DateFormat for locale " + loc 62 + ", but different from the one for locale " + iculoc); 63 } 64 } else { 65 if (!(dfIcu instanceof com.ibm.icu.impl.jdkadapter.SimpleDateFormatICU)) { 66 errln("FAIL: " + method[0] + " returned JDK DateFormat for locale " + iculoc); 67 } 68 } 69 } 70 } 71 72 private DateFormat getJDKInstance(int dstyle, int tstyle, Locale loc, String[] methodName) { 73 DateFormat df; 74 String method; 75 if (dstyle < 0) { 76 df = DateFormat.getTimeInstance(tstyle, loc); 77 method = "getTimeInstance"; 78 } else if (tstyle < 0) { 79 df = DateFormat.getDateInstance(dstyle, loc); 80 method = "getDateInstance"; 81 } else { 82 df = DateFormat.getDateTimeInstance(dstyle, tstyle, loc); 83 method = "getDateTimeInstance"; 84 } 85 if (methodName != null) { 86 methodName[0] = method; 87 } 88 return df; 89 } 90 91 private com.ibm.icu.text.DateFormat getICUInstance(int dstyle, int tstyle, Locale loc, String[] methodName) { 92 com.ibm.icu.text.DateFormat icudf; 93 String method; 94 if (dstyle < 0) { 95 icudf = com.ibm.icu.text.DateFormat.getTimeInstance(tstyle, loc); 96 method = "getTimeInstance"; 97 } else if (tstyle < 0) { 98 icudf = com.ibm.icu.text.DateFormat.getDateInstance(dstyle, loc); 99 method = "getDateInstance"; 100 } else { 101 icudf = com.ibm.icu.text.DateFormat.getDateTimeInstance(dstyle, tstyle, loc); 102 method = "getDateTimeInstance"; 103 } 104 if (methodName != null) { 105 methodName[0] = method; 106 } 107 return icudf; 108 } 109 110 /* 111 * Testing the behavior of date format between ICU instance and its 112 * equivalent created via the Locale SPI framework. 113 */ 114 @Test 115 public void TestICUEquivalent() { 116 Locale[] TEST_LOCALES = { 117 new Locale("en", "US"), 118 new Locale("it", "IT"), 119 new Locale("iw", "IL"), 120 new Locale("ja", "JP", "JP"), 121 new Locale("th", "TH"), 122 new Locale("zh", "TW"), 123 }; 124 125 long[] TEST_DATES = { 126 1199499330543L, // 2008-01-05T02:15:30.543Z 127 1217001308085L, // 2008-07-25T15:55:08.085Z 128 }; 129 130 for (Locale loc : TEST_LOCALES) { 131 for (int dstyle = -1; dstyle <= 3; dstyle++) { 132 for (int tstyle = -1; tstyle <= 3; tstyle++) { 133 if (tstyle == -1 && dstyle == -1) { 134 continue; 135 } 136 Locale iculoc = TestUtil.toICUExtendedLocale(loc); 137 DateFormat df = getJDKInstance(dstyle, tstyle, iculoc, null); 138 com.ibm.icu.text.DateFormat icudf = getICUInstance(dstyle, tstyle, loc, null); 139 140 for (long t : TEST_DATES) { 141 // Format 142 Date d = new Date(t); 143 String dstr1 = df.format(d); 144 String dstr2 = icudf.format(d); 145 146 if (!dstr1.equals(dstr2)) { 147 errln("FAIL: Different format results for locale " + loc + " (dstyle=" + dstyle 148 + ",tstyle=" + tstyle + ") at time " + t + " - JDK:" + dstr1 149 + " ICU:" + dstr2); 150 continue; 151 } 152 153 // Parse 154 Date d1, d2; 155 try { 156 d1 = df.parse(dstr1); 157 } catch (ParseException e) { 158 errln("FAIL: ParseException thrown for JDK DateFormat for string " 159 + dstr1 + "(locale=" + iculoc + ",dstyle=" + dstyle + ",tstyle=" + tstyle + ")"); 160 continue; 161 } 162 try { 163 d2 = icudf.parse(dstr1); 164 } catch (ParseException e) { 165 errln("FAIL: ParseException thrown for ICU DateFormat for string " 166 + dstr1 + "(locale=" + loc + ",dstyle=" + dstyle + ",tstyle=" + tstyle + ")"); 167 continue; 168 } 169 if (!d1.equals(d2)) { 170 errln("FAIL: Different parse results for locale " + loc 171 + " for date string " + dstr1 + " (dstyle=" + dstyle 172 + ",tstyle=" + tstyle + ") at time " + t + " - JDK:" + dstr1 173 + " ICU:" + dstr2); 174 } 175 } 176 } 177 } 178 } 179 } 180 181 /* 182 * Check if ICU DateFormatProvider uses Thai native digit for Locale 183 * th_TH_TH. 184 */ 185 @Test 186 public void TestThaiDigit() { 187 Locale thTHTH = new Locale("th", "TH", "TH"); 188 String pattern = "yyyy-MM-dd"; 189 190 DateFormat dfmt = DateFormat.getDateInstance(DateFormat.FULL, thTHTH); 191 DateFormat dfmtIcu = DateFormat.getDateInstance(DateFormat.FULL, TestUtil.toICUExtendedLocale(thTHTH)); 192 193 ((java.text.SimpleDateFormat)dfmt).applyPattern(pattern); 194 ((java.text.SimpleDateFormat)dfmtIcu).applyPattern(pattern); 195 196 Date d = new Date(); 197 String str1 = dfmt.format(d); 198 String str2 = dfmtIcu.format(d); 199 200 if (!str1.equals(str2)) { 201 errln("FAIL: ICU DateFormat returned a result different from JDK for th_TH_TH"); 202 } 203 } 204 205 @Test 206 public void TestCalendarKeyword() { 207 // ICU provider variant is appended 208 ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@calendar=buddhist"); 209 Locale loc = uloc0.toLocale(); 210 // On Java 7+, locale extension is preserved 211 ULocale uloc = ULocale.forLocale(loc); 212 String calType = uloc.getKeywordValue("calendar"); 213 if (calType == null) { 214 // Java 6 - skip this test 215 return; 216 } 217 218 DateFormat jdkDfmt = DateFormat.getDateInstance(DateFormat.FULL, loc); 219 Calendar cal = jdkDfmt.getCalendar(); 220 boolean isBuddhist = false; 221 if (cal instanceof CalendarICU) { 222 com.ibm.icu.util.Calendar icuCal = ((CalendarICU)cal).unwrap(); 223 isBuddhist = icuCal.getType().equals("buddhist"); 224 } 225 if (!isBuddhist) { 226 errln("FAIL: Calendar types is not Buddhist"); 227 } 228 } 229 } 230