ICU-5345 fix Japanese Calendar and tests

X-SVN-Rev: 20170
This commit is contained in:
Steven R. Loomis 2006-08-26 04:15:17 +00:00
parent 9cf34e0a84
commit 98385235ac
3 changed files with 215 additions and 7 deletions

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2002-2005, International Business Machines Corporation and *
* Copyright (C) 2002-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -19,7 +19,7 @@ import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.ULocale;
/**
* Tests for the <code>IslamicCalendar</code> class.
* Tests for the <code>JapaneseCalendar</code> class.
*/
public class JapaneseTest extends CalendarTest {
public static void main(String args[]) throws Exception {
@ -166,5 +166,131 @@ public class JapaneseTest extends CalendarTest {
logln("Got year " + gotYear + " and era " + gotEra + ", == " + inEn);
}
}
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 = -3197120400000L
+ 3600000L; // compensate for DST
Date aDate = new Date(aDateLong); //08 Sept 1868
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);
}
}
}
public void Test5345calendar() {
logln("** testIncompleteCalendar()");
// Test calendar with incomplete information
JapaneseCalendar c = new JapaneseCalendar(TimeZone.getDefault());
logln("test clear");
c.clear();
int expected0[] = { Calendar.ERA, 0 ,
Calendar.YEAR, -643 };
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);
}
}

View file

@ -4619,6 +4619,34 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
protected int[] handleCreateFields() {
return new int[BASE_FIELD_COUNT];
}
/**
* Subclasses may override this.
* Called by handleComputeJulianDay. Returns the default month (0-based) for the year,
* taking year and era into account. Defaults to 0 (JANUARY) for Gregorian.
* @parameter extendedYear the extendedYear, as returned by handleGetExtendedYear
* @return the default month
* @provisional ICU 3.6
* @see #MONTH
*/
protected int getDefaultMonthInYear(int extendedYear) {
return Calendar.JANUARY;
}
/**
* Subclasses may override this.
* Called by handleComputeJulianDay. Returns the default day (1-based) for the month,
* taking currently-set year and era into account. Defaults to 1 for Gregorian.
* @parameter extendedYear the extendedYear, as returned by handleGetExtendedYear
* @parameter month the month, as returned by getDefaultMonthInYear
* @return the default day of the month
* @provisional ICU 3.6
* @see #DAY_OF_MONTH
*/
protected int getDefaultDayInMonth(int extendedYear, int month) {
return 1;
}
/**
* Subclasses may override this. This method calls
@ -4635,12 +4663,20 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
int year = handleGetExtendedYear();
internalSet(EXTENDED_YEAR, year);
int month = useMonth ? internalGet(MONTH, getDefaultMonthInYear(year)) : 0;
int dom = internalGet(DAY_OF_MONTH, getDefaultDayInMonth(year, month));
// Get the Julian day of the day BEFORE the start of this year.
// If useMonth is true, get the day before the start of the month.
int julianDay = handleComputeMonthStart(year, useMonth ? internalGet(MONTH) : 0, useMonth);
int julianDay = handleComputeMonthStart(year, month, useMonth);
if (bestField == DAY_OF_MONTH) {
return julianDay + internalGet(DAY_OF_MONTH, 1);
if(isSet(DAY_OF_MONTH)) {
return julianDay + internalGet(DAY_OF_MONTH, getDefaultDayInMonth(year, month));
} else {
return julianDay + getDefaultDayInMonth(year, month);
}
}
if (bestField == DAY_OF_YEAR) {

View file

@ -215,16 +215,60 @@ public class JapaneseCalendar extends GregorianCalendar {
*/
protected int handleGetExtendedYear() {
int year;
// TODO reimplement this to be faster?
if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR &&
newerField(EXTENDED_YEAR, ERA) == EXTENDED_YEAR) {
year = internalGet(EXTENDED_YEAR, 1);
} else {
// Subtract one because year starts at 1
year = internalGet(YEAR) + ERAS[internalGet(ERA, CURRENT_ERA) * 3] - 1;
// extended year is a gregorian year, where 1 = 1AD, 0 = 1BC, -1 = 2BC, etc
year = internalGet(YEAR, 1) // pin to minimum of year 1 (first year)
+ ERAS[internalGet(ERA, CURRENT_ERA) * 3] // add gregorian starting year
- 1; // Subtract one because year starts at 1
}
return year;
}
/**
* Called by handleComputeJulianDay. Returns the default month (0-based) for the year,
* taking year and era into account. Defaults to 0 (JANUARY) for Gregorian.
* @parameter extendedYear the extendedYear, as returned by handleGetExtendedYear
* @return the default month
* @provisional ICU 3.6
* @see #MONTH
*/
protected int getDefaultMonthInYear(int extendedYear)
{
int era = internalGet(ERA, CURRENT_ERA);
//computeFields(status); // No need to compute fields here - expect the caller already did so.
// Find out if we are at the edge of an era
if(extendedYear == ERAS[era*3]) {
return ERAS[(era*3)+1] // month..
-1; // return 0-based month
} else {
return super.getDefaultMonthInYear(extendedYear);
}
}
/**
* Called by handleComputeJulianDay. Returns the default day (1-based) for the month,
* taking currently-set year and era into account. Defaults to 1 for Gregorian.
* @parameter extendedYear the extendedYear, as returned by handleGetExtendedYear
* @parameter month the month, as returned by getDefaultMonthInYear
* @return the default day of the month
* @provisional ICU 3.6
* @see #DAY_OF_MONTH
*/
protected int getDefaultDayInMonth(int extendedYear, int month) {
int era = internalGet(ERA, CURRENT_ERA);
if(extendedYear == ERAS[era*3]) { // if it is year 1..
if(month == ((ERAS[(era*3)+1])-1)) { // if it is the emperor's first month..
return ERAS[(era*3)+2]; // return the D_O_M of acession
}
}
return super.getDefaultDayInMonth(extendedYear, month);
}
/**
* @stable ICU 2.8
@ -588,6 +632,8 @@ public class JapaneseCalendar extends GregorianCalendar {
}
LIMITS[field][LEAST_MAXIMUM] = ++min; // 1-based
LIMITS[field][MAXIMUM] = ++max; // 1-based
YEAR_LIMIT_KNOWN=true;
}
return LIMITS[field][limitType];
default: