Skip to content

Commit

Permalink
Add support for CLDR/BCP47 Calender type names
Browse files Browse the repository at this point in the history
  • Loading branch information
RogerRiggs committed Oct 22, 2012
1 parent e767806 commit 39a9419
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 42 deletions.
39 changes: 23 additions & 16 deletions src-standard/main/java/javax/time/chrono/Chronology.java
Expand Up @@ -54,11 +54,11 @@
* It is built on the generic concepts of year, month and day - subclasses define the
* meaning of those concepts in the calendar system that they represent.
* <p>
* In practical terms, the {@code Chrono} instance also acts as a factory.
* In practical terms, the {@code Chronology} instance also acts as a factory.
* The {@link #ofName(String)} method allows an instance to be looked up by name.
* Note that the result will be an instance configured using the default values for that calendar.
* <p>
* The {@code Chrono} class provides a set of methods to create {@code ChronoDate} instances.
* The {@code Chronology} class provides a set of methods to create {@code ChronoDate} instances.
* The date classes are used to manipulate specific dates.
* <ul>
* <li> {@link #now() now()}
Expand Down Expand Up @@ -97,7 +97,7 @@ public abstract class Chronology {
ServiceLoader<Chronology> loader = ServiceLoader.load(Chronology.class);
for (Chronology chronology : loader) {
names.putIfAbsent(chronology.getName(), chronology);
String id = chronology.getLocaleId();
String id = chronology.getCalendarType();
if (id != null) {
ids.putIfAbsent(id, chronology);
}
Expand Down Expand Up @@ -125,7 +125,7 @@ public static Chronology from(DateTimeAccessor calendrical) {

//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code Chrono} from a locale.
* Obtains an instance of {@code Chronology} from a locale.
* <p>
* The locale can be used to identify a calendar.
* This uses {@link Locale#getUnicodeLocaleType(String)} to obtain the "ca" key
Expand All @@ -148,32 +148,38 @@ public static Chronology ofLocale(Locale locale) {
} else {
Chronology chrono = CHRONOS_BY_ID.get(localeId);
if (chrono == null) {
throw new DateTimeException("Unknown Chrono calendar system: " + localeId);
throw new DateTimeException("Unknown calendar system: " + localeId);
}
return chrono;
}
}

//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code Chrono} from a name.
* Obtains an instance of {@code Chronology} from a name or a calendar identifier.
* <p>
* The name is a standard way of identifying a calendar.
* The name is a standard way of identifying a calendar either by its familiar
* name or by its CLDR calendar identifier.
* Since some calendars can be customized, the name typically refers to the
* default customization. For example, the Gregorian calendar can have
* multiple cutover dates from the Julian, but the lookup by name only
* provides the default cutover date.
*
* @param name the calendar system name, not null
* @param name the calendar system name or calendar identifier, not null
* @return the calendar system with the name requested, not null
* @throws DateTimeException if the named calendar cannot be found
*/
public static Chronology ofName(String name) {
Chronology chrono = CHRONOS_BY_NAME.get(name);
if (chrono == null) {
throw new DateTimeException("Unknown Chrono calendar system: " + name);
if (chrono != null) {
return chrono;
}
chrono = CHRONOS_BY_ID.get(name);
if (chrono != null) {
return chrono;
}
return chrono;
// No chronology with the requested name
throw new DateTimeException("Unknown calendar system: " + name);
}

/**
Expand All @@ -194,7 +200,7 @@ public static Set<String> getAvailableNames() {
protected Chronology() {
// register the subclass
CHRONOS_BY_NAME.putIfAbsent(this.getName(), this);
String localeId = this.getLocaleId();
String localeId = this.getCalendarType();
if (localeId != null) {
CHRONOS_BY_ID.putIfAbsent(localeId, this);
}
Expand All @@ -209,14 +215,15 @@ protected Chronology() {
public abstract String getName();

/**
* Gets the identifier of the calendar system for locale lookup.
* Gets the calendar type of this calendar. Calendar types are defined by
* the <em>Unicode Locale Data Markup Language (LDML)</em> specification.
* <p>
* The lookup by locale, {@link #ofLocale(Locale)}, uses this identifier
* rather than the name. This is to support the pre-defined constants from CLDR.
*
* @return the locale identifier, null if lookup by locale not supported
* @return the calendar identifier, null if the calendar identifier is not defined by CLDR.
*/
protected abstract String getLocaleId();
public abstract String getCalendarType();

//-----------------------------------------------------------------------
/**
Expand Down Expand Up @@ -445,7 +452,7 @@ public int hashCode() {
*/
@Override
public String toString() {
return getName() + "Chrono";
return getName() + " Chronology";
}

}
Expand Up @@ -115,7 +115,7 @@ public String getName() {
}

@Override
protected String getLocaleId() {
public String getCalendarType() {
return "coptic";
}

Expand Down
Expand Up @@ -206,7 +206,7 @@ public String getName() {
}

@Override
protected String getLocaleId() {
public String getCalendarType() {
return "islamic"; // TODO: or islamic-civil or arabic or arabic-civil ?
}

Expand Down
4 changes: 2 additions & 2 deletions src-standard/main/java/javax/time/chrono/ISOChronology.java
Expand Up @@ -100,8 +100,8 @@ public String getName() {
}

@Override
protected String getLocaleId() {
return "iso";
public String getCalendarType() {
return "iso8601";
}

//-----------------------------------------------------------------------
Expand Down
Expand Up @@ -138,7 +138,7 @@ public String getName() {
}

@Override
protected String getLocaleId() {
public String getCalendarType() {
return "japanese";
}

Expand Down
Expand Up @@ -107,7 +107,7 @@ public String getName() {
}

@Override
protected String getLocaleId() {
public String getCalendarType() {
return "roc";
}

Expand Down
Expand Up @@ -127,7 +127,7 @@ public String getName() {
}

@Override
protected String getLocaleId() {
public String getCalendarType() {
return "buddhist";
}

Expand Down
37 changes: 18 additions & 19 deletions src-standard/test/java/javax/time/chrono/TestChronology.java
Expand Up @@ -66,23 +66,21 @@ public void setUp() {
@DataProvider(name = "calendars")
Object[][] data_of_calendars() {
return new Object[][] {
{"Coptic", null, "Coptic calendar"},
{"Hijrah", null, "Hijrah calendar"},
{"ISO", null, "ISO calendar"},
{"Japanese", null, "Japanese calendar"},
{"Minguo", null, "Minguo Calendar"}, // {"Islamic", null, "Islamic"},
{"ThaiBuddhist", null, "Thai Buddhist calendar"},
// {"Chinese", null, "Traditional Chinese calendar" },
// {"Ethioaa", "ethiopic-amete-alem", "Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E)" },
// {"Ethiopic", null, "Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.)" },
// {"Hebrew", null, "Traditional Hebrew calendar" },
{"Coptic", "coptic", "Coptic calendar"},
{"Hijrah", "islamic", "Hijrah calendar"},
{"ISO", "iso8601", "ISO calendar"},
{"Japanese", "japanese", "Japanese calendar"},
{"Minguo", "roc", "Minguo Calendar"},
{"ThaiBuddhist", "buddhist", "Thai Buddhist calendar"},
};
}

@Test(dataProvider = "calendars")
public void test_required_calendars(String name, String alias, String description) {
Chronology chrono = Chronology.ofName(name);
Assert.assertNotNull(chrono, "Required calendar not found: " + name);
chrono = Chronology.ofName(alias);
Assert.assertNotNull(chrono, "Required calendar not found by alias: " + name);
Set<String> cals = Chronology.getAvailableNames();
Assert.assertTrue(cals.contains(name), "Required calendar not found in set of available calendars");
}
Expand Down Expand Up @@ -115,26 +113,27 @@ public void test_epoch(String name, String alias, String description) {
//-----------------------------------------------------------------------
// locale based lookup
//-----------------------------------------------------------------------
@DataProvider(name = "localeid")
Object[][] data_localeid() {
@DataProvider(name = "typeid")
Object[][] data_CalendarType() {
return new Object[][] {
{CopticChronology.INSTANCE, "coptic"},
{HijrahChronology.INSTANCE, "islamic"},
{ISOChronology.INSTANCE, "iso"},
{ISOChronology.INSTANCE, "iso8601"},
{JapaneseChronology.INSTANCE, "japanese"},
{MinguoChronology.INSTANCE, "roc"},
{ThaiBuddhistChronology.INSTANCE, "buddhist"},
};
}

@Test(dataProvider = "localeid")
public void test_getLocaleId(Chronology chrono, String localeId) {
assertEquals(chrono.getLocaleId(), localeId);
@Test(dataProvider = "typeid")
public void test_getCalendarType(Chronology chrono, String calendarType) {
assertEquals(chrono.getCalendarType(), calendarType);
}

@Test(dataProvider = "localeid")
public void test_lookupLocale(Chronology chrono, String localeId) {
Locale locale = new Locale.Builder().setLanguage("en").setRegion("CA").setUnicodeLocaleKeyword("ca", localeId).build();
@Test(dataProvider = "typeid")
public void test_lookupLocale(Chronology chrono, String calendarType) {
Locale locale = new Locale.Builder().setLanguage("en").setRegion("CA").setUnicodeLocaleKeyword("ca", calendarType).build();
System.err.printf(" typeid: %s, locale: %s%n", calendarType, locale);
assertEquals(Chronology.ofLocale(locale), chrono);
}

Expand Down

0 comments on commit 39a9419

Please sign in to comment.