blob: 8f76fb3939048657af16f30c64465e102a5ce853 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.calendar;
import java.util.Date;
import java.util.Locale;
import java.util.MissingResourceException;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.HebrewCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
/**
* Tests for the <code>HebrewCalendar</code> class.
*/
public class HebrewTest extends CalendarTest {
public static void main(String args[]) throws Exception {
new HebrewTest().run(args);
}
// Constants to save typing.
public static final int TISHRI = HebrewCalendar.TISHRI;
public static final int HESHVAN = HebrewCalendar.HESHVAN;
public static final int KISLEV = HebrewCalendar.KISLEV;
public static final int TEVET = HebrewCalendar.TEVET;
public static final int SHEVAT = HebrewCalendar.SHEVAT;
public static final int ADAR_1 = HebrewCalendar.ADAR_1;
public static final int ADAR = HebrewCalendar.ADAR;
public static final int NISAN = HebrewCalendar.NISAN;
public static final int IYAR = HebrewCalendar.IYAR;
public static final int SIVAN = HebrewCalendar.SIVAN;
public static final int TAMUZ = HebrewCalendar.TAMUZ;
public static final int AV = HebrewCalendar.AV;
public static final int ELUL = HebrewCalendar.ELUL;
/**
* Test the behavior of HebrewCalendar.roll
* The only real nastiness with roll is the MONTH field, since a year can
* have a variable number of months.
*/
public void TestRoll() {
int[][] tests = new int[][] {
// input roll by output
// year month day field amount year month day
{ 5759, HESHVAN, 2, MONTH, 1, 5759, KISLEV, 2 }, // non-leap years
{ 5759, SHEVAT, 2, MONTH, 1, 5759, ADAR, 2 },
{ 5759, SHEVAT, 2, MONTH, 2, 5759, NISAN, 2 },
{ 5759, SHEVAT, 2, MONTH, 12, 5759, SHEVAT, 2 },
{ 5759, AV, 1, MONTH, 12, 5759, AV, 1 }, // Alan
{ 5757, HESHVAN, 2, MONTH, 1, 5757, KISLEV, 2 }, // leap years
{ 5757, SHEVAT, 2, MONTH, 1, 5757, ADAR_1, 2 },
{ 5757, SHEVAT, 2, MONTH, 2, 5757, ADAR, 2 },
{ 5757, SHEVAT, 2, MONTH, 3, 5757, NISAN, 2 },
{ 5757, SHEVAT, 2, MONTH, 12, 5757, TEVET, 2 },
{ 5757, SHEVAT, 2, MONTH, 13, 5757, SHEVAT, 2 },
{ 5757, AV, 1, MONTH, 12, 5757, TAMUZ, 1 }, // Alan
{ 5757, KISLEV, 1, DATE, 30, 5757, KISLEV, 2 }, // 29-day month
{ 5758, KISLEV, 1, DATE, 31, 5758, KISLEV, 2 }, // 30-day month
// Try some other fields too
{ 5757, TISHRI, 1, YEAR, 1, 5758, TISHRI, 1 },
// Try some rolls that require other fields to be adjusted
{ 5757, TISHRI, 30, MONTH, 1, 5757, HESHVAN, 29 },
{ 5758, KISLEV, 30, YEAR, -1, 5757, KISLEV, 29 },
};
// try{
HebrewCalendar cal = new HebrewCalendar(UTC, Locale.getDefault());
doRollAdd(ROLL, cal, tests);
// }catch(MissingResourceException ex){
// warnln("Got Exception: "+ ex.getMessage());
// }
}
/**
* Test the behavior of HebrewCalendar.roll
* The only real nastiness with roll is the MONTH field, since a year can
* have a variable number of months.
*/
public void TestAdd() {
int[][] tests = new int[][] {
// input add by output
// year month day field amount year month day
{ 5759, HESHVAN, 2, MONTH, 1, 5759, KISLEV, 2 }, // non-leap years
{ 5759, SHEVAT, 2, MONTH, 1, 5759, ADAR, 2 },
{ 5759, SHEVAT, 2, MONTH, 2, 5759, NISAN, 2 },
{ 5759, SHEVAT, 2, MONTH, 12, 5760, SHEVAT, 2 },
{ 5757, HESHVAN, 2, MONTH, 1, 5757, KISLEV, 2 }, // leap years
{ 5757, SHEVAT, 2, MONTH, 1, 5757, ADAR_1, 2 },
{ 5757, SHEVAT, 2, MONTH, 2, 5757, ADAR, 2 },
{ 5757, SHEVAT, 2, MONTH, 3, 5757, NISAN, 2 },
{ 5757, SHEVAT, 2, MONTH, 12, 5758, TEVET, 2 },
{ 5757, SHEVAT, 2, MONTH, 13, 5758, SHEVAT, 2 },
{ 5762, AV, 1, MONTH, 1, 5762, ELUL, 1 }, // JB#2327
{ 5762, AV, 30, DATE, 1, 5762, ELUL, 1 }, // JB#2327
{ 5762, ELUL, 1, DATE, -1, 5762, AV, 30 }, // JB#2327
{ 5762, ELUL, 1, MONTH, -1, 5762, AV, 1 }, // JB#2327
{ 5757, KISLEV, 1, DATE, 30, 5757, TEVET, 2 }, // 29-day month
{ 5758, KISLEV, 1, DATE, 31, 5758, TEVET, 2 }, // 30-day month
};
try{
HebrewCalendar cal = new HebrewCalendar(UTC, Locale.getDefault());
doRollAdd(ADD, cal, tests);
}catch( MissingResourceException ex){
warnln("Could not load the locale data");
}
}
/**
* A huge list of test cases to make sure that computeTime and computeFields
* work properly for a wide range of data.
*/
public void TestCases() {
try{
final TestCase[] testCases = {
//
// Most of these test cases were taken from the back of
// "Calendrical Calculations", with some extras added to help
// debug a few of the problems that cropped up in development.
//
// The months in this table are 1-based rather than 0-based,
// because it's easier to edit that way.
//
// Julian Day Era Year Month Day WkDay Hour Min Sec
new TestCase(1507231.5, 0, 3174, 12, 10, SUN, 0, 0, 0),
new TestCase(1660037.5, 0, 3593, 3, 25, WED, 0, 0, 0),
new TestCase(1746893.5, 0, 3831, 1, 3, WED, 0, 0, 0),
new TestCase(1770641.5, 0, 3896, 1, 9, SUN, 0, 0, 0),
new TestCase(1892731.5, 0, 4230, 4, 18, WED, 0, 0, 0),
new TestCase(1931579.5, 0, 4336, 10, 4, MON, 0, 0, 0),
new TestCase(1974851.5, 0, 4455, 2, 13, SAT, 0, 0, 0),
new TestCase(2091164.5, 0, 4773, 9, 6, SUN, 0, 0, 0),
new TestCase(2121509.5, 0, 4856, 9, 23, SUN, 0, 0, 0),
new TestCase(2155779.5, 0, 4950, 8, 7, FRI, 0, 0, 0),
new TestCase(2174029.5, 0, 5000, 7, 8, SAT, 0, 0, 0),
new TestCase(2191584.5, 0, 5048, 8, 21, FRI, 0, 0, 0),
new TestCase(2195261.5, 0, 5058, 9, 7, SUN, 0, 0, 0),
new TestCase(2229274.5, 0, 5151, 11, 1, SUN, 0, 0, 0),
new TestCase(2245580.5, 0, 5196, 5, 7, WED, 0, 0, 0),
new TestCase(2266100.5, 0, 5252, 8, 3, SAT, 0, 0, 0),
new TestCase(2288542.5, 0, 5314, 1, 1, SAT, 0, 0, 0),
new TestCase(2290901.5, 0, 5320, 6, 27, SAT, 0, 0, 0),
new TestCase(2323140.5, 0, 5408, 10, 20, WED, 0, 0, 0),
new TestCase(2334551.5, 0, 5440, 1, 1, THU, 0, 0, 0),
new TestCase(2334581.5, 0, 5440, 2, 1, SAT, 0, 0, 0),
new TestCase(2334610.5, 0, 5440, 3, 1, SUN, 0, 0, 0),
new TestCase(2334639.5, 0, 5440, 4, 1, MON, 0, 0, 0),
new TestCase(2334668.5, 0, 5440, 5, 1, TUE, 0, 0, 0),
new TestCase(2334698.5, 0, 5440, 6, 1, THU, 0, 0, 0),
new TestCase(2334728.5, 0, 5440, 7, 1, SAT, 0, 0, 0),
new TestCase(2334757.5, 0, 5440, 8, 1, SUN, 0, 0, 0),
new TestCase(2334787.5, 0, 5440, 9, 1, TUE, 0, 0, 0),
new TestCase(2334816.5, 0, 5440, 10, 1, WED, 0, 0, 0),
new TestCase(2334846.5, 0, 5440, 11, 1, FRI, 0, 0, 0),
new TestCase(2334848.5, 0, 5440, 11, 3, SUN, 0, 0, 0),
new TestCase(2334934.5, 0, 5441, 1, 1, TUE, 0, 0, 0),
new TestCase(2348020.5, 0, 5476, 12, 5, FRI, 0, 0, 0),
new TestCase(2366978.5, 0, 5528, 11, 4, SUN, 0, 0, 0),
new TestCase(2385648.5, 0, 5579, 12, 11, MON, 0, 0, 0),
new TestCase(2392825.5, 0, 5599, 8, 12, WED, 0, 0, 0),
new TestCase(2416223.5, 0, 5663, 8, 22, SUN, 0, 0, 0),
new TestCase(2425848.5, 0, 5689, 12, 19, SUN, 0, 0, 0),
new TestCase(2430266.5, 0, 5702, 1, 8, MON, 0, 0, 0),
new TestCase(2430833.5, 0, 5703, 8, 14, MON, 0, 0, 0),
new TestCase(2431004.5, 0, 5704, 1, 8, THU, 0, 0, 0),
new TestCase(2448698.5, 0, 5752, 7, 12, TUE, 0, 0, 0),
new TestCase(2450138.5, 0, 5756, 7, 5, SUN, 0, 0, 0),
new TestCase(2465737.5, 0, 5799, 2, 12, WED, 0, 0, 0),
new TestCase(2486076.5, 0, 5854, 12, 5, SUN, 0, 0, 0),
// Additional test cases for bugs found during development
// G.YY/MM/DD Era Year Month Day WkDay Hour Min Sec
new TestCase(1013, 9, 8, 0, 4774, 1, 1, TUE, 0, 0, 0),
new TestCase(1239, 9, 1, 0, 5000, 1, 1, THU, 0, 0, 0),
new TestCase(1240, 9,18, 0, 5001, 1, 1, TUE, 0, 0, 0),
// Test cases taken from a table of 14 "year types" in the Help file
// of the application "Hebrew Calendar"
new TestCase(2456187.5, 0, 5773, 1, 1, MON, 0, 0, 0),
new TestCase(2459111.5, 0, 5781, 1, 1, SAT, 0, 0, 0),
new TestCase(2453647.5, 0, 5766, 1, 1, TUE, 0, 0, 0),
new TestCase(2462035.5, 0, 5789, 1, 1, THU, 0, 0, 0),
new TestCase(2458756.5, 0, 5780, 1, 1, MON, 0, 0, 0),
new TestCase(2460586.5, 0, 5785, 1, 1, THU, 0, 0, 0),
new TestCase(2463864.5, 0, 5794, 1, 1, SAT, 0, 0, 0),
new TestCase(2463481.5, 0, 5793, 1, 1, MON, 0, 0, 0),
new TestCase(2470421.5, 0, 5812, 1, 1, THU, 0, 0, 0),
new TestCase(2460203.5, 0, 5784, 1, 1, SAT, 0, 0, 0),
new TestCase(2459464.5, 0, 5782, 1, 1, TUE, 0, 0, 0),
new TestCase(2467142.5, 0, 5803, 1, 1, MON, 0, 0, 0),
new TestCase(2455448.5, 0, 5771, 1, 1, THU, 0, 0, 0),
// Test cases for JB#2327
// http://www.fourmilab.com/documents/calendar/
// http://www.calendarhome.com/converter/
// 2452465.5, 2002, JULY, 10, 5762, AV, 1,
// 2452494.5, 2002, AUGUST, 8, 5762, AV, 30,
// 2452495.5, 2002, AUGUST, 9, 5762, ELUL, 1,
// 2452523.5, 2002, SEPTEMBER, 6, 5762, ELUL, 29,
// 2452524.5, 2002, SEPTEMBER, 7, 5763, TISHRI, 1,
// Julian Day Era Year Month Day WkDay Hour Min Sec
new TestCase(2452465.5, 0, 5762, AV+1, 1, WED, 0, 0, 0),
new TestCase(2452494.5, 0, 5762, AV+1, 30, THU, 0, 0, 0),
new TestCase(2452495.5, 0, 5762, ELUL+1, 1, FRI, 0, 0, 0),
new TestCase(2452523.5, 0, 5762, ELUL+1, 29, FRI, 0, 0, 0),
new TestCase(2452524.5, 0, 5763,TISHRI+1, 1, SAT, 0, 0, 0),
};
doTestCases(testCases, new HebrewCalendar());
}catch(MissingResourceException ex){
warnln("Got Exception: "+ ex.getMessage());
}
}
/**
* Problem reported by Armand Bendanan in which setting of the MONTH
* field in a Hebrew calendar causes the time fields to go negative.
*/
public void TestTimeFields() {
try{
HebrewCalendar calendar = new HebrewCalendar(5761, 0, 11, 12, 28, 15);
calendar.set(Calendar.YEAR, 5717);
calendar.set(Calendar.MONTH, 2);
calendar.set(Calendar.DAY_OF_MONTH, 23);
if (calendar.get(Calendar.HOUR_OF_DAY) != 12) {
errln("Fail: HebrewCalendar HOUR_OF_DAY = " + calendar.get(Calendar.HOUR_OF_DAY));
}
}catch(MissingResourceException ex){
warnln("Got Exception: "+ ex.getMessage());
}
}
/**
* Problem reported by Armand Bendanan (armand.bendanan@free.fr)
* in which setting of the MONTH field in a Hebrew calendar to
* ELUL on non leap years causes the date to be set on TISHRI next year.
*/
public void TestElulMonth() {
try{
HebrewCalendar cal = new HebrewCalendar();
// Leap years are:
// 3 6 8 11 14 17 19 (and so on - 19-year cycle)
for (int year=1; year<50; year++) {
// I hope that year = 0 does not exists
// because the test fails for it !
cal.clear();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, ELUL);
cal.set(Calendar.DAY_OF_MONTH, 1);
int yact = cal.get(Calendar.YEAR);
int mact = cal.get(Calendar.MONTH);
if (year != yact || ELUL != mact) {
errln("Fail: " + ELUL + "/" + year +
" -> " +
mact + "/" + yact);
}
}
}catch(MissingResourceException ex){
warnln("Got Exception: "+ ex.getMessage());
}
}
/**
* Test of the behavior of the month field. This requires special
* handling in the Hebrew calendar because of the pattern of leap
* years.
*/
public void TestMonthMovement() {
try{
HebrewCalendar cal = new HebrewCalendar();
// Leap years are:
// 3 6 8 11 14 17 19 (and so on - 19-year cycle)
// We can't test complete() on some lines below because of ADAR_1 -- if
// the calendar is set to ADAR_1 on a non-leap year, the result is undefined.
int[] DATA = {
// m1/y1 - month/year before (month is 1-based)
// delta - amount to add to month field
// m2/y2 - month/year after add(MONTH, delta)
// m3/y3 - month/year after set(MONTH, m1+delta)
//m1 y1 delta m2 y2 m3 y3
10, 2, +24, 9, 4, 9, 4,
10, 2, +60, 8, 7, 8, 7,
1 , 2, +12, 1, 3, 13, 2, //*set != add; also see '*' below
3 , 18, -24, 4, 16, 4, 16,
1 , 6, -24, 1, 4, 1, 4,
4 , 3, +2, 6, 3, 6, 3, // Leap year - no skip 4,5,6,7,8
8 , 3, -2, 6, 3, 6, 3, // Leap year - no skip
4 , 2, +2, 7, 2, 7, 2, // Skip leap month 4,5,(6),7,8
8 , 2, -2, 5, 2, 7, 2, //*Skip leap month going backward
};
for (int i=0; i<DATA.length; ) {
int m = DATA[i++], y = DATA[i++];
int monthDelta = DATA[i++];
int m2 = DATA[i++], y2 = DATA[i++];
int m3 = DATA[i++], y3 = DATA[i++];
int mact, yact;
cal.clear();
cal.set(Calendar.YEAR, y);
cal.set(Calendar.MONTH, m-1);
cal.add(Calendar.MONTH, monthDelta);
yact = cal.get(Calendar.YEAR); mact = cal.get(Calendar.MONTH) + 1;
if (y2 != yact || m2 != mact) {
errln("Fail: " + m + "/" + y +
" -> add(MONTH, " + monthDelta + ") -> " +
mact + "/" + yact + ", expected " +
m2 + "/" + y2);
cal.clear();
cal.set(Calendar.YEAR, y);
cal.set(Calendar.MONTH, m-1);
logln("Start: " + m + "/" + y);
int delta = monthDelta > 0 ? 1 : -1;
for (int c=0; c!=monthDelta; c+=delta) {
cal.add(Calendar.MONTH, delta);
logln("+ " + delta + " MONTH -> " +
(cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.YEAR));
}
}
cal.clear();
cal.set(Calendar.YEAR, y);
cal.set(Calendar.MONTH, m + monthDelta - 1);
yact = cal.get(Calendar.YEAR); mact = cal.get(Calendar.MONTH) + 1;
if (y3 != yact || m3 != mact) {
errln("Fail: " + (m+monthDelta) + "/" + y +
" -> complete() -> " +
mact + "/" + yact + ", expected " +
m3 + "/" + y3);
}
}
}catch(MissingResourceException ex){
warnln("Got Exception: "+ ex.getMessage());
}
}
/**
* Test handling of ADAR_1.
*/
/*
public void TestAdar1() {
HebrewCalendar cal = new HebrewCalendar();
cal.clear();
cal.set(Calendar.YEAR, 1903); // leap
cal.set(Calendar.MONTH, HebrewCalendar.ADAR_1);
logln("1903(leap)/ADAR_1 => " +
cal.get(Calendar.YEAR) + "/" + (cal.get(Calendar.MONTH)+1));
cal.clear();
cal.set(Calendar.YEAR, 1904); // non-leap
cal.set(Calendar.MONTH, HebrewCalendar.ADAR_1);
logln("1904(non-leap)/ADAR_1 => " +
cal.get(Calendar.YEAR) + "/" + (cal.get(Calendar.MONTH)+1));
}
*/
/**
* With no fields set, the calendar should use default values.
*/
public void TestDefaultFieldValues() {
try{
HebrewCalendar cal = new HebrewCalendar();
cal.clear();
logln("cal.clear() -> " + cal.getTime());
}catch(MissingResourceException ex){
warnln("could not load the locale data");
}
}
/**
* Test limits of the Hebrew calendar
*/
public void TestLimits() {
Calendar cal = Calendar.getInstance();
cal.set(2007, Calendar.JANUARY, 1);
HebrewCalendar hebrew = new HebrewCalendar();
doLimitsTest(hebrew, null, cal.getTime());
doTheoreticalLimitsTest(hebrew, true);
}
public void TestCoverage() {
try{
{
// new HebrewCalendar(TimeZone)
HebrewCalendar cal = new HebrewCalendar(TimeZone.getDefault());
if(cal == null){
errln("could not create HebrewCalendar with TimeZone");
}
}
{
// new HebrewCalendar(ULocale)
HebrewCalendar cal = new HebrewCalendar(ULocale.getDefault());
if(cal == null){
errln("could not create HebrewCalendar with ULocale");
}
}
{
// new HebrewCalendar(Locale)
HebrewCalendar cal = new HebrewCalendar(Locale.getDefault());
if(cal == null){
errln("could not create HebrewCalendar with locale");
}
}
{
// new HebrewCalendar(Date)
HebrewCalendar cal = new HebrewCalendar(new Date());
if(cal == null){
errln("could not create HebrewCalendar with date");
}
}
{
// data
HebrewCalendar cal = new HebrewCalendar(2800, HebrewCalendar.SHEVAT, 1);
Date time = cal.getTime();
String[] calendarLocales = {
"iw_IL"
};
String[] formatLocales = {
"en", "fi", "fr", "hu", "iw", "nl"
};
for (int i = 0; i < calendarLocales.length; ++i) {
String calLocName = calendarLocales[i];
Locale calLocale = LocaleUtility.getLocaleFromName(calLocName);
cal = new HebrewCalendar(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));
}
}
}
}catch( MissingResourceException ex){
warnln("Could not load the locale data. "+ ex.getMessage());
}
}
public void Test1624() {
HebrewCalendar hc = new HebrewCalendar (5742, HebrewCalendar.AV, 22);
DateFormat df = hc.getDateTimeFormat(DateFormat.FULL, DateFormat.FULL, Locale.getDefault());
String dateString = df.format(hc.getTime());
for (int year = 5600; year < 5800; year ++) {
boolean leapYear = HebrewCalendar.isLeapYear (year);
for (int month = HebrewCalendar.TISHRI; month <= HebrewCalendar.ELUL;month++) {
// skip the adar 1 month if year is not a leap year
if (leapYear == false && month == HebrewCalendar.ADAR_1) {
continue;
}
int day = 15;
hc = new HebrewCalendar (year, month, day);
dateString = df.format(hc.getTime());
int dayHC = hc.get (HebrewCalendar.DATE);
int monthHC = hc.get (HebrewCalendar.MONTH);
int yearHC = hc.get (HebrewCalendar.YEAR);
String header = "year:" + year + " isleap:" + leapYear + " " + dateString;
if (dayHC != day) {
errln (header + " ==> day:" + dayHC + " incorrect, should be:" + day);
break;
}
if (monthHC != month) {
errln (header + " ==> month:" + monthHC + " incorrect, should be:" + month);
break;
}
if (yearHC != year) {
errln (header + " ==> year:" + yearHC + " incorrecte, should be:" + year);
break;
}
}
}
}
}