1 /* 2 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4833268 6253991 8008577 27 * @summary Test formatting and parsing with non-Gregorian calendars 28 * @run main/othervm -Djava.locale.providers=COMPAT,SPI NonGregorianFormatTest 29 */ 30 31 import java.util.*; 32 import java.text.*; 33 import static java.util.Calendar.*; 34 35 public class NonGregorianFormatTest { 36 static int errors; 37 38 static final Object[][] JAPANESE_EN = { 39 { "GGGG yyyy MMMM d", "Showa 1 December 31", new Date(1926-1900, DECEMBER, 31) }, 40 { "GGGG yyyy MMMM d", "Showa 64 January 6", new Date(1989-1900, JANUARY, 6) }, 41 { "GGGG yyyy MMMM d", "Heisei 1 August 9", new Date(1989-1900, AUGUST, 9) }, 42 { "GGGG yyyy MMMM d", "Heisei 17 June 10", new Date(2005-1900, JUNE, 10) }, 43 { "Gy.MM.dd", "S1.12.31", new Date(1926-1900, DECEMBER, 31) }, 44 { "Gy.MM.dd", "S64.01.06", new Date(1989-1900, JANUARY, 6) }, 45 { "Gyy.MM.dd", "H01.08.09", new Date(1989-1900, AUGUST, 9) }, 46 { "Gy.M.d", "H1.8.9", new Date(1989-1900, AUGUST, 9) }, 47 { "Gy.MM.dd", "H17.06.10", new Date(2005-1900, JUNE, 10) }, 48 }; 49 50 // Invalid dates for parse exception tests 51 static final Object[][] EXCEPTION_JAPANESE_EN = { 52 { "GGGG yyyy MMMM d", "Showa 1 December 10" }, 53 { "GGGG yyyy MMMM d", "Showa 64 January 16" }, 54 { "GGGG yyyy MMMM d", "Heisei 1 January 1" }, 55 { "Gy.MM.dd", "S1.12.10" }, 56 { "Gy.MM.dd", "S64.01.16" }, 57 { "Gyy.MM.dd", "H01.01.01" }, 58 }; 59 60 static final Object[][] BUDDHIST_EN = { 61 { "GGGG yyyy MMMM d", "B.E. 2469 December 31", new Date(1926-1900, DECEMBER, 31) }, 62 { "GGGG yyyy MMMM d", "B.E. 2532 January 6", new Date(1989-1900, JANUARY, 6) }, 63 { "GGGG yyyy MMMM d", "B.E. 2532 August 8", new Date(1989-1900, AUGUST, 8) }, 64 { "GGGG yyyy MMMM d", "B.E. 2548 June 10", new Date(2005-1900, JUNE, 10) }, 65 { "Gyyyy/MM/dd", "B.E.2469/12/31", new Date(1926-1900, DECEMBER, 31) }, 66 { "Gyyyy/MM/dd", "B.E.2532/01/06", new Date(1989-1900, JANUARY, 6) }, 67 { "Gyyyy/MM/dd", "B.E.2532/08/09", new Date(1989-1900, AUGUST, 9) }, 68 { "Gyyyy/MM/dd", "B.E.2548/06/10", new Date(2005-1900, JUNE, 10) }, 69 }; 70 71 static final String FULL_DATE_FORMAT_JA = "GGGGyyyy'\u5e74'M'\u6708'd'\u65e5'"; 72 73 static final Object[][] JAPANESE_JA = { 74 { FULL_DATE_FORMAT_JA, "\u662d\u548c\u5143\u5e7412\u670831\u65e5", new Date(1926-1900, DECEMBER, 31) }, 75 { FULL_DATE_FORMAT_JA, "\u662d\u548c64\u5e741\u67086\u65e5", new Date(1989-1900, JANUARY, 6) }, 76 { FULL_DATE_FORMAT_JA, "\u5e73\u6210\u5143\u5e748\u67089\u65e5", new Date(1989-1900, AUGUST, 9) }, 77 { FULL_DATE_FORMAT_JA, "\u5e73\u621017\u5e746\u670810\u65e5", new Date(2005-1900, JUNE, 10) }, 78 { "Gyy.MM.dd", "S01.12.31", new Date(1926-1900, DECEMBER, 31) }, 79 { "Gyy.MM.dd", "S64.01.06", new Date(1989-1900, JANUARY, 6) }, 80 { "Gyy.MM.dd", "H01.08.09", new Date(1989-1900, AUGUST, 9) }, 81 { "Gy.M.d", "H1.8.9", new Date(1989-1900, AUGUST, 9) }, 82 { "Gyy.MM.dd", "H17.06.10", new Date(2005-1900, JUNE, 10) }, 83 }; 84 85 // Invalid dates for parse exception tests 86 static final Object[][] EXCEPTION_JAPANESE_JA = { 87 { FULL_DATE_FORMAT_JA, "\u662d\u548c\u5143\u5e7412\u670810\u65e5" }, 88 { FULL_DATE_FORMAT_JA, "\u662d\u548c64\u5e741\u670816\u65e5" }, 89 { FULL_DATE_FORMAT_JA, "\u5e73\u6210\u5143\u5e741\u67081\u65e5" }, 90 { "Gyy.MM.dd", "S01.12.10" }, 91 { "Gyy.MM.dd", "S64.01.16" }, 92 { "Gyy.MM.dd", "H01.01.01" }, 93 }; 94 95 static final Object[][] BUDDHIST_JA = { 96 { FULL_DATE_FORMAT_JA, "\u4ecf\u66a62469\u5e7412\u670831\u65e5", new Date(1926-1900, DECEMBER, 31) }, 97 { FULL_DATE_FORMAT_JA, "\u4ecf\u66a62532\u5e741\u67086\u65e5", new Date(1989-1900, JANUARY, 6) }, 98 { FULL_DATE_FORMAT_JA, "\u4ecf\u66a62532\u5e748\u67089\u65e5", new Date(1989-1900, AUGUST, 9) }, 99 { FULL_DATE_FORMAT_JA, "\u4ecf\u66a62548\u5e746\u670810\u65e5", new Date(2005-1900, JUNE, 10) }, 100 { "Gyyyy/MM/dd", "B.E.2469/12/31", new Date(1926-1900, DECEMBER, 31) }, 101 { "Gyyyy/MM/dd", "B.E.2532/01/06", new Date(1989-1900, JANUARY, 6) }, 102 { "Gyyyy/MM/dd", "B.E.2532/08/09", new Date(1989-1900, AUGUST, 9) }, 103 { "Gyyyy/MM/dd", "B.E.2548/06/10", new Date(2005-1900, JUNE, 10) }, 104 }; 105 106 public static void main(String[] args) throws ParseException { 107 Locale defaultLocale = Locale.getDefault(); 108 Locale[] locales = { Locale.ENGLISH, Locale.JAPAN }; 109 try { 110 for (Locale locale : locales) { 111 test(locale); 112 } 113 } finally { 114 Locale.setDefault(defaultLocale); 115 } 116 if (errors > 0) { 117 throw new RuntimeException("FAILED: " + errors + " error(s)"); 118 } 119 } 120 121 private static void test(Locale locale) { 122 Locale.setDefault(locale); 123 124 // Tests with the Japanese imperial calendar 125 Locale calendarLocale = new Locale("ja", "JP", "JP"); 126 testRoundTrip(calendarLocale); 127 testRoundTripSimple(calendarLocale, 128 locale == Locale.ENGLISH ? JAPANESE_EN : JAPANESE_JA); 129 testParseExceptions(calendarLocale, 130 locale == Locale.ENGLISH ? EXCEPTION_JAPANESE_EN : EXCEPTION_JAPANESE_JA); 131 132 // Tests with the Thai Buddhist calendar 133 calendarLocale = new Locale("th", "TH"); 134 testRoundTrip(calendarLocale); 135 testRoundTripSimple(calendarLocale, 136 locale == Locale.ENGLISH ? BUDDHIST_EN : BUDDHIST_JA); 137 } 138 139 private static void testRoundTrip(Locale calendarLocale) { 140 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, 141 DateFormat.FULL, 142 calendarLocale); 143 144 long t = System.currentTimeMillis(); 145 t = (t / 1000) * 1000; // discard milliseconds 146 testRoundTrip(df, new Date(t)); 147 148 // H1.8.9 149 testRoundTrip(df, new Date(1989-1900, AUGUST, 9)); 150 151 // H17.6.13 152 testRoundTrip(df, new Date(2005-1900, JUNE, 13)); 153 } 154 155 private static void testRoundTrip(DateFormat df, Date orig) { 156 try { 157 String s = df.format(orig); 158 Date parsed = df.parse(s); 159 if (!orig.equals(parsed)) { 160 error("testRoundTrip: bad date: origianl: '%s', parsed '%s'%n", orig, parsed); 161 } 162 } catch (Exception e) { 163 error("Unexpected exception: %s%n", e); 164 } 165 } 166 167 private static void testRoundTripSimple(Locale calendarLocale, Object[][] data) { 168 try { 169 for (Object[] item : data) { 170 String pattern = (String) item[0]; 171 String str = (String) item[1]; 172 Date date = (Date) item[2]; 173 SimpleDateFormat sdf = new SimpleDateFormat(pattern); 174 Calendar cal = Calendar.getInstance(calendarLocale); 175 sdf.setCalendar(cal); 176 String s = sdf.format(date); 177 if (!s.equals(str)) { 178 error("testRoundTripSimple: Got '%s', expected '%s'%n", s, str); 179 } 180 Date d = sdf.parse(str); 181 if (!d.equals(date)) { 182 error("testRoundTripSimple: Got '%s', expected '%s'%n", d, date); 183 } 184 } 185 } catch (Exception e) { 186 error("Unexpected exception: %s%n", e); 187 } 188 } 189 190 private static void testParseExceptions(Locale calendarLocale, Object[][] data) { 191 for (Object[] item : data) { 192 String pattern = (String) item[0]; 193 String str = (String) item[1]; 194 SimpleDateFormat sdf = new SimpleDateFormat(pattern); 195 Calendar cal = Calendar.getInstance(calendarLocale); 196 sdf.setCalendar(cal); 197 sdf.setLenient(false); 198 try { 199 Date d = sdf.parse(str); 200 error("testParseExceptions: parsing '%s' doesn't throw a ParseException.%n", str); 201 } catch (ParseException e) { 202 // OK 203 } 204 } 205 } 206 207 private static void error(String msg) { 208 System.out.println(msg); 209 errors++; 210 } 211 212 private static void error(String fmt, Object... args) { 213 System.out.printf(fmt, args); 214 errors++; 215 } 216 }