Skip to content

Commit 12cd0ca

Browse files
authored
CLDR-17851 SupplementalCalendarData parser, update ExampleGenerator (#4642)
1 parent 627b0c2 commit 12cd0ca

File tree

6 files changed

+383
-104
lines changed

6 files changed

+383
-104
lines changed

tools/cldr-code/src/main/java/org/unicode/cldr/icu/LDMLConstants.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,13 @@ public class LDMLConstants {
258258
public static final String SEGMENTATIONS = "segmentations";
259259
public static final String TIMEZONE_DATA = "timezoneData";
260260
public static final String CALENDAR_DATA = "calendarData";
261-
public static final String CALENDAR_PREFERENCE_DATA = "calendarPreferenceData";
262261
public static final String CALENDAR_PREFERENCE = "calendarPreference";
262+
public static final String CALENDAR_PREFERENCE_DATA = "calendarPreferenceData";
263+
public static final String CALENDAR_SYSTEM = "calendarSystem";
264+
public static final String INHERIT_ERAS = "inheritEras";
265+
public static final String CODE = "code";
266+
public static final String END = "end";
267+
public static final String START = "start";
263268
public static final String ORDERING = "ordering";
264269
public static final String WEEK_DATA = "weekData";
265270
public static final String MEASUREMENT_DATA = "measurementData";

tools/cldr-code/src/main/java/org/unicode/cldr/test/ExampleGenerator.java

Lines changed: 76 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import org.unicode.cldr.util.Rational.FormatStyle;
8282
import org.unicode.cldr.util.ScriptToExemplars;
8383
import org.unicode.cldr.util.SimpleUnicodeSetFormatter;
84+
import org.unicode.cldr.util.SupplementalCalendarData;
8485
import org.unicode.cldr.util.SupplementalDataInfo;
8586
import org.unicode.cldr.util.SupplementalDataInfo.CurrencyNumberInfo;
8687
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
@@ -293,58 +294,6 @@ public void setCachingEnabled(boolean enabled) {
293294

294295
HelpMessages helpMessages;
295296

296-
/* For each calendar type, maps the closest two eras to 2025
297-
* defined in that calendar to their corresponding start/end date.
298-
* Dates are adjusted to be 2 days after official era start date and
299-
* 2 days before era end date to avoid time zone issues.
300-
* TODO: include methods for calendarData in supplementalDataInfo API
301-
* to extract this data directly from supplementaldata.xml
302-
*/
303-
public static final Map<String, List<Date>> CALENDAR_ERAS =
304-
new HashMap<>() {
305-
{ // month 0-indexed. start/end days adjusted by +/- 2, respectively
306-
put(
307-
"gregorian",
308-
List.of(
309-
new GregorianCalendar(0, 11, 29).getTime(),
310-
new GregorianCalendar(1, 0, 03).getTime()));
311-
put(
312-
"japanese",
313-
List.of(
314-
new GregorianCalendar(1989, 0, 10).getTime(),
315-
new GregorianCalendar(2019, 4, 3).getTime()));
316-
put(
317-
"islamic",
318-
List.of(
319-
new GregorianCalendar(622, 6, 17).getTime(),
320-
new GregorianCalendar(622, 6, 12).getTime()));
321-
put("chinese", List.of(new GregorianCalendar(-2636, 0, 03).getTime()));
322-
put("hebrew", List.of(new GregorianCalendar(-3760, 9, 9).getTime()));
323-
put("buddhist", List.of(new GregorianCalendar(-542, 0, 03).getTime()));
324-
put(
325-
"coptic",
326-
List.of(
327-
new GregorianCalendar(284, 07, 26).getTime(),
328-
new GregorianCalendar(284, 07, 31).getTime()));
329-
put("persian", List.of(new GregorianCalendar(622, 0, 03).getTime()));
330-
put("dangi", List.of(new GregorianCalendar(-2332, 0, 03).getTime()));
331-
put(
332-
"ethiopic",
333-
List.of(
334-
new GregorianCalendar(8, 07, 26).getTime(),
335-
new GregorianCalendar(8, 07, 31).getTime()));
336-
put(
337-
"ethiopic-amete-alem",
338-
List.of(new GregorianCalendar(-5492, 07, 27).getTime()));
339-
put("indian", List.of(new GregorianCalendar(79, 0, 03).getTime()));
340-
put(
341-
"roc",
342-
List.of(
343-
new GregorianCalendar(1911, 11, 29).getTime(),
344-
new GregorianCalendar(1912, 0, 03).getTime()));
345-
}
346-
};
347-
348297
// map relativeTimePattern counts to possible numeric examples.
349298
// For few , many, and other there is not a single number that is in that category for
350299
// all locales, so we provide a list of values that might be good examples and use the
@@ -3151,30 +3100,87 @@ private void handleDateRangePattern(String value, List<String> examples) {
31513100
setBackground(dateFormat.format(DATE_SAMPLE2))));
31523101
}
31533102

3154-
/**
3155-
* Add examples for eras. First checks if there is info for this calendar type and this era type
3156-
* in the CALENDAR_ERAS map, then generates a sample date based on this info and formats it
3157-
*/
3103+
/** Add examples for eras. Generates a sample date based on this info and formats it */
31583104
private void handleEras(XPathParts parts, String value, List<String> examples) {
31593105
String calendarId = parts.getAttributeValue(3, "type");
31603106
String type = parts.getAttributeValue(-1, "type");
3161-
String id =
3162-
(calendarId.startsWith("islamic"))
3163-
? "islamic"
3164-
: calendarId; // islamic variations map to same sample
3165-
if (!CALENDAR_ERAS.containsKey(id)) {
3166-
return;
3107+
String id = calendarId;
3108+
if (id.equals("generic") || id.equals("iso8601")) {
3109+
id = "gregorian"; // use Gregorian eras, 'generic' is not in the data
31673110
}
3168-
int typeIndex = Integer.parseInt(type);
3169-
if (calendarId.equals("japanese")) {
3170-
if (typeIndex < 235) { // examples only for 2 most recent eras
3171-
return;
3172-
} else {
3173-
typeIndex %= 235; // map to length 2 list
3111+
final SupplementalCalendarData.CalendarData calendarData =
3112+
supplementalDataInfo.getCalendarData().get(id);
3113+
3114+
if (calendarData == null) {
3115+
throw new IllegalArgumentException("Could not load supplementalCalendarData for " + id);
3116+
}
3117+
final int typeIndex = Integer.parseInt(type);
3118+
3119+
final SupplementalCalendarData.EraData eraData = calendarData.get(typeIndex);
3120+
if (eraData == null) {
3121+
return; // no era data
3122+
}
3123+
GregorianCalendar startCal = eraData.getStartCalendar();
3124+
GregorianCalendar endCal = eraData.getEndCalendar();
3125+
3126+
final SupplementalCalendarData.EraData eminusone = calendarData.get(typeIndex - 1);
3127+
final SupplementalCalendarData.EraData eplusone = calendarData.get(typeIndex + 1);
3128+
3129+
SupplementalCalendarData.EraData prevEra = null;
3130+
SupplementalCalendarData.EraData nextEra = null;
3131+
3132+
// see if we can find the 'prev' and 'next' era by date
3133+
if (eminusone != null && eminusone.compareTo(eraData) < 0) {
3134+
prevEra = eminusone;
3135+
} else if (eplusone != null && eplusone.compareTo(eraData) < 0) {
3136+
prevEra = eplusone;
3137+
}
3138+
if (eminusone != null && eminusone.compareTo(eraData) > 0) {
3139+
nextEra = eminusone;
3140+
} else if (eplusone != null && eplusone.compareTo(eraData) > 0) {
3141+
nextEra = eplusone;
3142+
}
3143+
3144+
if (startCal == null && prevEra != null && prevEra.getEnd() != null) {
3145+
startCal = prevEra.getEndCalendar();
3146+
// shift forward so we are in the next era
3147+
startCal.setTimeInMillis(startCal.getTimeInMillis() + (DateConstants.MILLIS_PER_DAY));
3148+
}
3149+
if (endCal == null && nextEra != null && nextEra.getStart() != null) {
3150+
endCal = nextEra.getStartCalendar();
3151+
// shift backward so we are in the prev era
3152+
endCal.setTimeInMillis(endCal.getTimeInMillis() - (DateConstants.MILLIS_PER_DAY));
3153+
}
3154+
3155+
GregorianCalendar sampleDate = null;
3156+
3157+
if (startCal != null && endCal != null) {
3158+
// roll back a day to not hit the edge
3159+
sampleDate = endCal;
3160+
sampleDate.setTimeInMillis(
3161+
sampleDate.getTimeInMillis() - (DateConstants.MILLIS_PER_DAY));
3162+
} else if (startCal == null && endCal != null) {
3163+
// roll back a day to not hit the edge
3164+
sampleDate = endCal;
3165+
sampleDate.setTimeInMillis(
3166+
sampleDate.getTimeInMillis() - (DateConstants.MILLIS_PER_DAY));
3167+
} else if (startCal != null && endCal == null) {
3168+
sampleDate = new GregorianCalendar(2002, 6, 15); // CLDR repo root commit
3169+
if (sampleDate.before(startCal)) {
3170+
sampleDate = startCal;
3171+
sampleDate.setTimeInMillis(
3172+
sampleDate.getTimeInMillis() + (DateConstants.MILLIS_PER_DAY));
31743173
}
3174+
} else {
3175+
// System.err.println("No good date for " + eraData);
3176+
// TODO: should be an error in TestSupplementalDataInfo
3177+
sampleDate = null;
31753178
}
3176-
List<Date> eraDates = CALENDAR_ERAS.get(id);
3177-
Date sample = eraDates.get(typeIndex);
3179+
3180+
if (sampleDate == null) return; // could not find the time
3181+
3182+
final Date sample = sampleDate.getTime();
3183+
31783184
String skeleton = "Gy";
31793185
String checkPath =
31803186
"//ldml/dates/calendars/calendar[@type=\""

0 commit comments

Comments
 (0)