| // © 2016 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html#License |
| /* |
| ******************************************************************************* |
| * Copyright (C) 2002-2010, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| package com.ibm.icu.dev.test.calendar; |
| |
| import java.text.ParseException; |
| import java.text.ParsePosition; |
| import java.util.Date; |
| import java.util.Locale; |
| |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| import com.ibm.icu.impl.LocaleUtility; |
| import com.ibm.icu.text.DateFormat; |
| import com.ibm.icu.text.DateTimePatternGenerator; |
| import com.ibm.icu.text.SimpleDateFormat; |
| import com.ibm.icu.util.Calendar; |
| import com.ibm.icu.util.JapaneseCalendar; |
| import com.ibm.icu.util.TimeZone; |
| import com.ibm.icu.util.ULocale; |
| |
| /** |
| * Tests for the <code>JapaneseCalendar</code> class. |
| */ |
| @RunWith(JUnit4.class) |
| public class JapaneseTest extends CalendarTestFmwk { |
| |
| @Test |
| public void TestCoverage() { |
| { |
| // new JapaneseCalendar(TimeZone) |
| JapaneseCalendar cal = new JapaneseCalendar(TimeZone.getDefault()); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with TimeZone"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(ULocale) |
| JapaneseCalendar cal = new JapaneseCalendar(ULocale.getDefault()); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with ULocale"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(TimeZone, ULocale) |
| JapaneseCalendar cal = new JapaneseCalendar(TimeZone.getDefault(), ULocale.getDefault()); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with TimeZone ULocale"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(Locale) |
| JapaneseCalendar cal = new JapaneseCalendar(Locale.getDefault()); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with Locale"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(TimeZone, Locale) |
| JapaneseCalendar cal = new JapaneseCalendar(TimeZone.getDefault(), Locale.getDefault()); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with TimeZone Locale"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(Date) |
| JapaneseCalendar cal = new JapaneseCalendar(new Date()); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with Date"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(int year, int month, int date) |
| JapaneseCalendar cal = new JapaneseCalendar(1868, Calendar.JANUARY, 1); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with year,month,date"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(int era, int year, int month, int date) |
| JapaneseCalendar cal = new JapaneseCalendar(JapaneseCalendar.MEIJI, 43, Calendar.JANUARY, 1); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with era,year,month,date"); |
| } |
| } |
| |
| { |
| // new JapaneseCalendar(int year, int month, int date, int hour, int minute, int second) |
| JapaneseCalendar cal = new JapaneseCalendar(1868, Calendar.JANUARY, 1, 1, 1, 1); |
| if(cal == null){ |
| errln("could not create JapaneseCalendar with year,month,date,hour,min,second"); |
| } |
| } |
| |
| { |
| // limits |
| JapaneseCalendar cal = new JapaneseCalendar(); |
| DateFormat fmt = cal.getDateTimeFormat(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH); |
| |
| cal.set(Calendar.ERA, JapaneseCalendar.MEIJI); |
| logln("date: " + cal.getTime()); |
| logln("min era: " + cal.getMinimum(Calendar.ERA)); |
| logln("min year: " + cal.getMinimum(Calendar.YEAR)); |
| cal.set(Calendar.YEAR, cal.getActualMaximum(Calendar.YEAR)); |
| logln("date: " + fmt.format(cal.getTime())); |
| cal.add(Calendar.YEAR, 1); |
| logln("date: " + fmt.format(cal.getTime())); |
| } |
| |
| { |
| // data |
| JapaneseCalendar cal = new JapaneseCalendar(1868, Calendar.JANUARY, 1); |
| Date time = cal.getTime(); |
| |
| String[] calendarLocales = { |
| "en", "ja_JP" |
| }; |
| |
| String[] formatLocales = { |
| "en", "ja" |
| }; |
| for (int i = 0; i < calendarLocales.length; ++i) { |
| String calLocName = calendarLocales[i]; |
| Locale calLocale = LocaleUtility.getLocaleFromName(calLocName); |
| cal = new JapaneseCalendar(calLocale); |
| |
| for (int j = 0; j < formatLocales.length; ++j) { |
| String locName = formatLocales[j]; |
| Locale formatLocale = LocaleUtility.getLocaleFromName(locName); |
| DateFormat format = DateFormat.getDateTimeInstance(cal, DateFormat.FULL, DateFormat.FULL, formatLocale); |
| logln(calLocName + "/" + locName + " --> " + format.format(time)); |
| } |
| } |
| } |
| } |
| |
| @Test |
| public void Test3860() |
| { |
| final String jCalShortPattern = "y/M/d"; // Note: just 'y' doesn't work here. |
| final String jCalGannenDate = "1/5/9"; // A date in the above format after the accession date for Heisei era (Heisei year 1 Jan 8) |
| // or the new era in Gregorian 2019 (new era year 1 May 1). If before the accession date, |
| // the year will be in the previous era. |
| ULocale loc = new ULocale("ja_JP@calendar=japanese"); |
| Calendar cal = new JapaneseCalendar(loc); |
| DateFormat enjformat = cal.getDateTimeFormat(DateFormat.FULL,DateFormat.FULL,new ULocale("en_JP@calendar=japanese")); |
| DateFormat format = cal.getDateTimeFormat(DateFormat.SHORT,DateFormat.SHORT,loc); // SHORT => no jpanyear since we will apply a short pattern |
| ((SimpleDateFormat)format).applyPattern(jCalShortPattern); |
| ParsePosition pos = new ParsePosition(0); |
| Date aDate = format.parse(jCalGannenDate, pos); |
| String inEn = enjformat.format(aDate); |
| |
| cal.clear(); |
| cal.setTime(aDate); |
| int gotYear = cal.get(Calendar.YEAR); |
| int gotEra = cal.get(Calendar.ERA); |
| |
| int expectYear = 1; |
| int expectEra = JapaneseCalendar.CURRENT_ERA; |
| |
| if((gotYear != expectYear) || (gotEra != expectEra)) { |
| errln("Expected year " + expectYear + ", era " + expectEra +", but got year " + gotYear + " and era " + gotEra + ", == " + inEn); |
| } else { |
| logln("Got year " + gotYear + " and era " + gotEra + ", == " + inEn); |
| } |
| |
| // Test parse with missing era (should default to current era, heisei) |
| // Test parse with incomplete information |
| logln("Testing parse w/ just year..."); |
| Calendar cal2 = new JapaneseCalendar(loc); |
| SimpleDateFormat fmt = new SimpleDateFormat("y", loc); |
| SimpleDateFormat fmt2 = new SimpleDateFormat("HH:mm:ss.S MMMM d, yyyy G", new ULocale("en_US@calendar=gregorian")); |
| cal2.clear(); |
| String samplestr = "1"; |
| logln("Test Year: " + samplestr); |
| try { |
| aDate = fmt.parse(samplestr); |
| } catch (ParseException pe) { |
| errln("Error parsing " + samplestr); |
| } |
| ParsePosition pp = new ParsePosition(0); |
| fmt.parse(samplestr, cal2, pp); |
| logln("cal2 after 1 parse:"); |
| String str = fmt2.format(aDate); |
| logln("as Gregorian Calendar: " + str); |
| |
| cal2.setTime(aDate); |
| gotYear = cal2.get(Calendar.YEAR); |
| gotEra = cal2.get(Calendar.ERA); |
| expectYear = 1; |
| expectEra = JapaneseCalendar.CURRENT_ERA; |
| if((gotYear != 1) || (gotEra != expectEra)) { |
| errln("parse "+ samplestr + " of 'y' as Japanese Calendar, expected year " + expectYear + |
| " and era " + expectEra + ", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")"); |
| } else { |
| logln(" year: " + gotYear + ", era: " + gotEra); |
| } |
| |
| // Tests for formats with gannen numbering Gy年 |
| pos.setIndex(0); |
| aDate = format.parse(jCalGannenDate, pos); // reset |
| DateFormat fmtWithGannen = DateFormat.getDateInstance(cal, DateFormat.MEDIUM, loc); |
| String aString = fmtWithGannen.format(aDate); |
| if (aString.charAt(2) != '\u5143') { // 元 |
| errln("Formatting year 1 as Gannen, got " + aString + " but expected 3rd char to be \u5143"); |
| } else { |
| // Replace 元 with 1 and parse the result |
| String bString = aString.replace('\u5143', '1'); |
| try { |
| Date bDate = fmtWithGannen.parse(bString); |
| bString = fmtWithGannen.format(bDate); |
| if (!bString.equals(aString)) { |
| errln("Parsing 1 when expecting \u5143, formatting the result produced " + bString + " but expected " + aString); |
| } |
| } catch (ParseException pe) { |
| errln("Exception parsing 1 when expecting \u5143 in string " + bString); |
| } |
| } |
| } |
| |
| @Test |
| public void TestForceGannenNumbering() { |
| final String jCalShortPattern = "y/M/d"; // Note: just 'y' doesn't work here. |
| final String jCalGannenDate = "1/5/9"; // A date in the above format after the accession date for Heisei [1989-] era (Heisei year 1 Jan 8) |
| // or Reiwa [2019-] era (Reiwa year 1 May 1). If before the accession date, |
| // the year will be in the previous era. |
| ULocale loc = new ULocale("ja_JP@calendar=japanese"); |
| Date refDate = new Date(600336000000L); // 1989 Jan 9 Monday = Heisei 1 |
| final String patText = "Gy年M月d日"; |
| final String patNumr = "GGGGGy/MM/dd"; |
| final String skelText = "yMMMM"; |
| |
| // Test Gannen year forcing |
| SimpleDateFormat testFmt1 = new SimpleDateFormat(patText, loc); |
| SimpleDateFormat testFmt2 = new SimpleDateFormat(patNumr, loc); |
| String testString1 = testFmt1.format(refDate); |
| if (testString1.length() < 3 || testString1.charAt(2) != '\u5143') { // 元 |
| errln("Formatting year 1 in created text style, got " + testString1 + " but expected 3rd char to be \u5143"); |
| } |
| String testString2 = testFmt2.format(refDate); |
| if (testString2.length() < 2 || testString2.charAt(1) != '1') { |
| errln("Formatting year 1 in created numeric style, got " + testString2 + " but expected 2nd char to be 1"); |
| } |
| // Now switch the patterns and verify that Gannen use follows the pattern |
| testFmt1.applyPattern(patNumr); |
| testString1 = testFmt1.format(refDate); |
| if (testString1.length() < 2 || testString1.charAt(1) != '1') { // |
| errln("Formatting year 1 in applied numeric style, got " + testString1 + " but expected 2nd char to be 1"); |
| } |
| testFmt2.applyPattern(patText); |
| testString2 = testFmt2.format(refDate); |
| if (testString2.length() < 3 || testString2.charAt(2) != '\u5143') { // 元 |
| errln("Formatting year 1 in applied text style, got " + testString2 + " but expected 3rd char to be \u5143"); |
| } |
| |
| // Test disabling of Gannen year forcing |
| DateTimePatternGenerator dtpgen = DateTimePatternGenerator.getInstance(loc); |
| String pattern = dtpgen.getBestPattern(skelText); |
| SimpleDateFormat testFmt3 = new SimpleDateFormat(pattern, "", loc); // empty override string to disable Gannen year numbering |
| String testString3 = testFmt3.format(refDate); |
| if (testString3.length() < 3 || testString3.charAt(2) != '1') { |
| errln("Formatting year 1 with Gannen disabled, got " + testString3 + " but expected 3rd char to be 1"); |
| } |
| } |
| |
| @Test |
| public void Test5345parse() { |
| // Test parse with incomplete information |
| DateFormat fmt2= DateFormat.getDateInstance(); //DateFormat.LONG, Locale.US); |
| JapaneseCalendar c = new JapaneseCalendar(TimeZone.getDefault(), new ULocale("en_US")); |
| SimpleDateFormat fmt = (SimpleDateFormat)c.getDateTimeFormat(1,1,new ULocale("en_US@calendar=japanese")); |
| fmt.applyPattern("G y"); |
| logln("fmt's locale = " + fmt.getLocale(ULocale.ACTUAL_LOCALE)); |
| //SimpleDateFormat fmt = new SimpleDateFormat("G y", new Locale("en_US@calendar=japanese")); |
| long aDateLong = -3197117222000L; // 1868-09-08 00:00 Pacific Time (GMT-07:52:58) |
| if (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_JDK) { |
| // Java time zone implementation does not support LMTs |
| aDateLong = -3197116800000L; // 1868-09-08 00:00 Pacific Time (GMT-08:00) |
| } |
| Date aDate = new Date(aDateLong); |
| logln("aDate: " + aDate.toString() +", from " + aDateLong); |
| String str; |
| str = fmt2.format(aDate); |
| logln("Test Date: " + str); |
| str = fmt.format(aDate); |
| logln("as Japanese Calendar: " + str); |
| String expected = "Meiji 1"; |
| if(!str.equals(expected)) { |
| errln("FAIL: Expected " + expected + " but got " + str); |
| } |
| Date otherDate; |
| try { |
| otherDate = fmt.parse(expected); |
| if(!otherDate.equals(aDate)) { |
| String str3; |
| // ParsePosition pp; |
| Date dd = fmt.parse(expected); |
| str3 = fmt.format(otherDate); |
| long oLong = otherDate.getTime(); |
| long aLong = otherDate.getTime(); |
| |
| errln("FAIL: Parse incorrect of " + expected + ": wanted " + aDate + " ("+aLong+"), but got " + " " + |
| otherDate + " ("+oLong+") = " + str3 + " not " + dd.toString() ); |
| |
| |
| } else { |
| logln("Parsed OK: " + expected); |
| } |
| } catch(java.text.ParseException pe) { |
| errln("FAIL: ParseException: " + pe.toString()); |
| pe.printStackTrace(); |
| } |
| } |
| |
| |
| private void checkExpected(Calendar c, int expected[] ) { |
| final String[] FIELD_NAME = { |
| "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", |
| "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", |
| "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY", |
| "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", |
| "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR", |
| "JULIAN_DAY", "MILLISECONDS_IN_DAY", |
| }; |
| |
| for(int i= 0;i<expected.length;i += 2) { |
| int fieldNum = expected[i+0]; |
| int expectedVal = expected[i+1]; |
| int actualVal = c.get(fieldNum); |
| |
| if(expectedVal == actualVal) { |
| logln(FIELD_NAME[fieldNum]+": "+ actualVal); |
| } else { |
| errln("FAIL: "+FIELD_NAME[fieldNum]+": expected "+ expectedVal + " got " + actualVal); |
| } |
| } |
| } |
| |
| @Test |
| public void Test5345calendar() { |
| logln("** testIncompleteCalendar()"); |
| // Test calendar with incomplete information |
| JapaneseCalendar c = new JapaneseCalendar(TimeZone.getDefault()); |
| logln("test clear"); |
| c.clear(); |
| |
| // Showa 45 = Gregorian 1970 |
| int expected0[] = { Calendar.ERA, 234, |
| Calendar.YEAR, 45 }; |
| checkExpected(c, expected0); |
| |
| logln("test setting era"); |
| c.clear(); |
| c.set(Calendar.ERA, JapaneseCalendar.MEIJI); |
| |
| |
| int expectedA[] = { Calendar.ERA, JapaneseCalendar.MEIJI }; |
| checkExpected(c, expectedA); |
| |
| |
| logln("test setting era and year and month and date"); |
| c.clear(); |
| c.set(Calendar.ERA, JapaneseCalendar.MEIJI); |
| c.set(Calendar.YEAR, 1); |
| c.set(Calendar.MONTH, Calendar.JANUARY); |
| c.set(Calendar.DATE, 1); |
| |
| |
| int expectedC[] = { Calendar.ERA, JapaneseCalendar.MEIJI -1}; |
| checkExpected(c, expectedC); |
| |
| |
| logln("test setting year and month and date THEN era"); |
| c.clear(); |
| c.set(Calendar.YEAR, 1); |
| c.set(Calendar.MONTH, Calendar.JANUARY); |
| c.set(Calendar.DATE, 1); |
| c.set(Calendar.ERA, JapaneseCalendar.MEIJI); |
| |
| |
| checkExpected(c, expectedC); |
| |
| |
| logln("test setting era and year"); |
| c.clear(); |
| c.set(Calendar.YEAR, 1); |
| c.set(Calendar.ERA, JapaneseCalendar.MEIJI); |
| |
| |
| int expectedB[] = { Calendar.ERA, JapaneseCalendar.MEIJI, |
| Calendar.YEAR, 1 }; |
| checkExpected(c, expectedB); |
| |
| } |
| |
| @Test |
| public void TestJapaneseYear3282() { |
| Calendar c = Calendar.getInstance(ULocale.ENGLISH); |
| c.set(2003,Calendar.SEPTEMBER,25); |
| JapaneseCalendar jcal = new JapaneseCalendar(); |
| //jcal.setTime(new Date(1187906308151L)); alternate value |
| jcal.setTime(c.getTime()); |
| logln("Now is: " + jcal.getTime()); |
| c.setTime(jcal.getTime()); |
| int nowYear = c.get(Calendar.YEAR); |
| logln("Now year: "+nowYear); |
| SimpleDateFormat jdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(jcal, |
| SimpleDateFormat.DEFAULT, Locale.getDefault()); |
| jdf.applyPattern("G yy/MM/dd"); |
| String text = jdf.format(jcal.getTime()); |
| logln("Now is: " + text + " (in Japan)"); |
| try { |
| Date date = jdf.parse(text); |
| logln("But is this not the date?: " + date); |
| c.setTime(date); |
| int thenYear = c.get(Calendar.YEAR); |
| logln("Then year: "+thenYear); |
| if(thenYear != nowYear) { |
| errln("Nowyear "+nowYear +" is not thenyear "+thenYear); |
| } else { |
| logln("Nowyear "+nowYear +" == thenyear "+thenYear); |
| } |
| } catch (java.text.ParseException ex) { |
| ex.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Test limits of the Japanese calendar |
| */ |
| @Test |
| public void TestLimits() { |
| Calendar cal = Calendar.getInstance(); |
| cal.set(1988, Calendar.DECEMBER, 1); |
| JapaneseCalendar jcal = new JapaneseCalendar(); |
| doLimitsTest(jcal, null, cal.getTime()); |
| doTheoreticalLimitsTest(jcal, true); |
| } |
| |
| // The following currently assumes that Reiwa is the last known/valid era. |
| // Filed ICU-20551 to generalize this when we have more time... |
| @Test |
| public void TestJpnCalAddSetNextEra() { |
| final JapaneseCalendar jCal = new JapaneseCalendar(); |
| jCal.clear(); // This sets to 1970 in Showa |
| |
| final int sEra = jCal.get(Calendar.ERA); // Don't assume era number for Showa |
| final int[] startYears = { 1926, 1989, 2019, 0 }; // start years for Show, Heisei, Reiwa; 0 marks invalid era beyond |
| |
| for (int iEra = 1; iEra < 3; iEra++) { |
| jCal.clear(); |
| jCal.set(Calendar.ERA, sEra + iEra); |
| int eYear = jCal.get(Calendar.EXTENDED_YEAR); |
| if (eYear != startYears[iEra]) { |
| errln("ERROR: set " + iEra + ", expected start year " + startYears[iEra] + " but get " + eYear); |
| } else { |
| jCal.add(Calendar.ERA, 1); |
| eYear = jCal.get(Calendar.EXTENDED_YEAR); |
| int nextEraStart = (startYears[iEra + 1] == 0) ? startYears[iEra] : startYears[iEra + 1]; |
| if (eYear != nextEraStart) { |
| errln("ERROR: set " + iEra + " then add ERA 1, expected start year " + nextEraStart |
| + " but get " + eYear); |
| } |
| } |
| } |
| } |
| } |
| |