1 /*
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import sun.util.calendar.BaseCalendar;
31 import sun.util.calendar.CalendarDate;
32 import sun.util.calendar.CalendarSystem;
33 import sun.util.calendar.CalendarUtils;
34 import sun.util.calendar.Era;
35 import sun.util.calendar.Gregorian;
36 import sun.util.calendar.LocalGregorianCalendar;
37 import sun.util.calendar.ZoneInfo;
38 import sun.util.resources.LocaleData;
39
40 /**
41 * <code>JapaneseImperialCalendar</code> implements a Japanese
42 * calendar system in which the imperial era-based year numbering is
43 * supported from the Meiji era. The following are the eras supported
44 * by this calendar system.
45 * <pre><tt>
46 * ERA value Era name Since (in Gregorian)
47 * ------------------------------------------------------
48 * 0 N/A N/A
49 * 1 Meiji 1868-01-01 midnight local time
50 * 2 Taisho 1912-07-30 midnight local time
51 * 3 Showa 1926-12-25 midnight local time
52 * 4 Heisei 1989-01-08 midnight local time
53 * ------------------------------------------------------
54 * </tt></pre>
55 *
56 * <p><code>ERA</code> value 0 specifies the years before Meiji and
57 * the Gregorian year values are used. Unlike {@link
58 * GregorianCalendar}, the Julian to Gregorian transition is not
285 /**
286 * Temporary storage for saving original fields[] values in
287 * non-lenient mode.
288 */
289 private transient int[] originalFields;
290
291 /**
292 * Constructs a <code>JapaneseImperialCalendar</code> based on the current time
293 * in the given time zone with the given locale.
294 *
295 * @param zone the given time zone.
296 * @param aLocale the given locale.
297 */
298 JapaneseImperialCalendar(TimeZone zone, Locale aLocale) {
299 super(zone, aLocale);
300 jdate = jcal.newCalendarDate(zone);
301 setTimeInMillis(System.currentTimeMillis());
302 }
303
304 /**
305 * Compares this <code>JapaneseImperialCalendar</code> to the specified
306 * <code>Object</code>. The result is <code>true</code> if and
307 * only if the argument is a <code>JapaneseImperialCalendar</code> object
308 * that represents the same time value (millisecond offset from
309 * the <a href="Calendar.html#Epoch">Epoch</a>) under the same
310 * <code>Calendar</code> parameters.
311 *
312 * @param obj the object to compare with.
313 * @return <code>true</code> if this object is equal to <code>obj</code>;
314 * <code>false</code> otherwise.
315 * @see Calendar#compareTo(Calendar)
316 */
317 public boolean equals(Object obj) {
318 return obj instanceof JapaneseImperialCalendar &&
319 super.equals(obj);
320 }
321
322 /**
323 * Generates the hash code for this
324 * <code>JapaneseImperialCalendar</code> object.
924 if (x < lastDays) {
925 max++;
926 }
927 int value = getRolledValue(internalGet(field), amount, min, max) - 1;
928 fd = month1 + value * 7 + x;
929 LocalGregorianCalendar.Date d = getCalendarDate(fd);
930 set(DAY_OF_MONTH, d.getDayOfMonth());
931 return;
932 }
933 }
934
935 set(field, getRolledValue(internalGet(field), amount, min, max));
936 }
937
938 public String getDisplayName(int field, int style, Locale locale) {
939 if (!checkDisplayNameParams(field, style, SHORT, LONG, locale,
940 ERA_MASK|YEAR_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
941 return null;
942 }
943
944 // "GanNen" is supported only in the LONG style.
945 if (field == YEAR
946 && (style == SHORT || get(YEAR) != 1 || get(ERA) == 0)) {
947 return null;
948 }
949
950 ResourceBundle rb = LocaleData.getDateFormatData(locale);
951 String name = null;
952 String key = getKey(field, style);
953 if (key != null) {
954 String[] strings = rb.getStringArray(key);
955 if (field == YEAR) {
956 if (strings.length > 0) {
957 name = strings[0];
958 }
959 } else {
960 int index = get(field);
961 // If the ERA value is out of range for strings, then
962 // try to get its name or abbreviation from the Era instance.
963 if (field == ERA && index >= strings.length && index < eras.length) {
964 Era era = eras[index];
965 name = (style == SHORT) ? era.getAbbreviation() : era.getName();
966 } else {
967 if (field == DAY_OF_WEEK) {
968 --index;
969 }
970 name = strings[index];
971 }
972 }
973 }
974 return name;
975 }
976
977 public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) {
978 if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
979 ERA_MASK|YEAR_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
980 return null;
981 }
982
983 if (style == ALL_STYLES) {
984 Map<String,Integer> shortNames = getDisplayNamesImpl(field, SHORT, locale);
985 if (field == AM_PM) {
986 return shortNames;
987 }
988 Map<String,Integer> longNames = getDisplayNamesImpl(field, LONG, locale);
989 if (shortNames == null) {
990 return longNames;
991 }
992 if (longNames != null) {
993 shortNames.putAll(longNames);
994 }
995 return shortNames;
996 }
997
998 // SHORT or LONG
999 return getDisplayNamesImpl(field, style, locale);
1000 }
1001
1002 private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) {
1003 ResourceBundle rb = LocaleData.getDateFormatData(locale);
1004 String key = getKey(field, style);
1005 Map<String,Integer> map = new HashMap<>();
1006 if (key != null) {
1007 String[] strings = rb.getStringArray(key);
1008 if (field == YEAR) {
1009 if (strings.length > 0) {
1010 map.put(strings[0], 1);
1011 }
1012 } else {
1013 int base = (field == DAY_OF_WEEK) ? 1 : 0;
1014 for (int i = 0; i < strings.length; i++) {
1015 map.put(strings[i], base + i);
1016 }
1017 // If strings[] has fewer than eras[], get more names from eras[].
1018 if (field == ERA && strings.length < eras.length) {
1019 for (int i = strings.length; i < eras.length; i++) {
1020 Era era = eras[i];
1021 String name = (style == SHORT) ? era.getAbbreviation() : era.getName();
1022 map.put(name, i);
1023 }
1024 }
1025 }
1026 }
1027 return map.size() > 0 ? map : null;
1028 }
1029
1030 private String getKey(int field, int style) {
1031 String className = JapaneseImperialCalendar.class.getName();
1032 StringBuilder key = new StringBuilder();
1033 switch (field) {
1034 case ERA:
1035 key.append(className);
1036 if (style == SHORT) {
1037 key.append(".short");
1038 }
1039 key.append(".Eras");
1040 break;
1041
1042 case YEAR:
1043 key.append(className).append(".FirstYear");
1044 break;
1045
1046 case MONTH:
1047 key.append(style == SHORT ? "MonthAbbreviations" : "MonthNames");
1048 break;
1049
1050 case DAY_OF_WEEK:
1051 key.append(style == SHORT ? "DayAbbreviations" : "DayNames");
1052 break;
1053
1054 case AM_PM:
1055 key.append("AmPmMarkers");
1056 break;
1057 }
1058 return key.length() > 0 ? key.toString() : null;
1059 }
1060
1061 /**
1062 * Returns the minimum value for the given calendar field of this
1063 * <code>Calendar</code> instance. The minimum value is
1064 * defined as the smallest value returned by the {@link
1065 * Calendar#get(int) get} method for any possible time value,
1066 * taking into consideration the current values of the
1067 * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1068 * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1069 * and {@link Calendar#getTimeZone() getTimeZone} methods.
1070 *
1071 * @param field the calendar field.
1072 * @return the minimum value for the given calendar field.
1073 * @see #getMaximum(int)
1074 * @see #getGreatestMinimum(int)
1075 * @see #getLeastMaximum(int)
1076 * @see #getActualMinimum(int)
1077 * @see #getActualMaximum(int)
1078 */
1079 public int getMinimum(int field) {
1080 return MIN_VALUES[field];
|
1 /*
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.util;
27
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import sun.util.locale.provider.CalendarDataUtility;
31 import sun.util.calendar.BaseCalendar;
32 import sun.util.calendar.CalendarDate;
33 import sun.util.calendar.CalendarSystem;
34 import sun.util.calendar.CalendarUtils;
35 import sun.util.calendar.Era;
36 import sun.util.calendar.Gregorian;
37 import sun.util.calendar.LocalGregorianCalendar;
38 import sun.util.calendar.ZoneInfo;
39
40 /**
41 * <code>JapaneseImperialCalendar</code> implements a Japanese
42 * calendar system in which the imperial era-based year numbering is
43 * supported from the Meiji era. The following are the eras supported
44 * by this calendar system.
45 * <pre><tt>
46 * ERA value Era name Since (in Gregorian)
47 * ------------------------------------------------------
48 * 0 N/A N/A
49 * 1 Meiji 1868-01-01 midnight local time
50 * 2 Taisho 1912-07-30 midnight local time
51 * 3 Showa 1926-12-25 midnight local time
52 * 4 Heisei 1989-01-08 midnight local time
53 * ------------------------------------------------------
54 * </tt></pre>
55 *
56 * <p><code>ERA</code> value 0 specifies the years before Meiji and
57 * the Gregorian year values are used. Unlike {@link
58 * GregorianCalendar}, the Julian to Gregorian transition is not
285 /**
286 * Temporary storage for saving original fields[] values in
287 * non-lenient mode.
288 */
289 private transient int[] originalFields;
290
291 /**
292 * Constructs a <code>JapaneseImperialCalendar</code> based on the current time
293 * in the given time zone with the given locale.
294 *
295 * @param zone the given time zone.
296 * @param aLocale the given locale.
297 */
298 JapaneseImperialCalendar(TimeZone zone, Locale aLocale) {
299 super(zone, aLocale);
300 jdate = jcal.newCalendarDate(zone);
301 setTimeInMillis(System.currentTimeMillis());
302 }
303
304 /**
305 * Returns {@code "japanese"} as the calendar type of this {@code
306 * JapaneseImperialCalendar}.
307 *
308 * @return {@code "japanese"}
309 */
310 @Override
311 public String getCalendarType() {
312 return "japanese";
313 }
314
315 /**
316 * Compares this <code>JapaneseImperialCalendar</code> to the specified
317 * <code>Object</code>. The result is <code>true</code> if and
318 * only if the argument is a <code>JapaneseImperialCalendar</code> object
319 * that represents the same time value (millisecond offset from
320 * the <a href="Calendar.html#Epoch">Epoch</a>) under the same
321 * <code>Calendar</code> parameters.
322 *
323 * @param obj the object to compare with.
324 * @return <code>true</code> if this object is equal to <code>obj</code>;
325 * <code>false</code> otherwise.
326 * @see Calendar#compareTo(Calendar)
327 */
328 public boolean equals(Object obj) {
329 return obj instanceof JapaneseImperialCalendar &&
330 super.equals(obj);
331 }
332
333 /**
334 * Generates the hash code for this
335 * <code>JapaneseImperialCalendar</code> object.
935 if (x < lastDays) {
936 max++;
937 }
938 int value = getRolledValue(internalGet(field), amount, min, max) - 1;
939 fd = month1 + value * 7 + x;
940 LocalGregorianCalendar.Date d = getCalendarDate(fd);
941 set(DAY_OF_MONTH, d.getDayOfMonth());
942 return;
943 }
944 }
945
946 set(field, getRolledValue(internalGet(field), amount, min, max));
947 }
948
949 public String getDisplayName(int field, int style, Locale locale) {
950 if (!checkDisplayNameParams(field, style, SHORT, LONG, locale,
951 ERA_MASK|YEAR_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
952 return null;
953 }
954
955 int fieldValue = get(field);
956
957 // "GanNen" is supported only in the LONG style.
958 if (field == YEAR
959 && (getBaseStyle(style) == SHORT || fieldValue != 1 || get(ERA) == 0)) {
960 return null;
961 }
962
963 String name = CalendarDataUtility.retrieveFieldValueName("japanese", field, fieldValue, style, locale);
964 // If the ERA value is null, then
965 // try to get its name or abbreviation from the Era instance.
966 if (name == null && field == ERA && fieldValue < eras.length) {
967 Era era = eras[fieldValue];
968 name = (style == SHORT) ? era.getAbbreviation() : era.getName();
969 }
970 return name;
971 }
972
973 public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) {
974 if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
975 ERA_MASK|YEAR_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
976 return null;
977 }
978 Map<String, Integer> names = CalendarDataUtility.retrieveFieldValueNames("japanese", field, style, locale);
979 // If strings[] has fewer than eras[], get more names from eras[].
980 if (field == ERA) {
981 int size = names.size();
982 if (style == ALL_STYLES) {
983 size /= 2; // SHORT and LONG
984 }
985 if (size < eras.length) {
986 int baseStyle = getBaseStyle(style);
987 for (int i = size; i < eras.length; i++) {
988 Era era = eras[i];
989 if (baseStyle == ALL_STYLES || baseStyle == SHORT) {
990 names.put(era.getAbbreviation(), i);
991 }
992 if (baseStyle == ALL_STYLES || baseStyle == LONG) {
993 names.put(era.getName(), i);
994 }
995 }
996 }
997 }
998 return names;
999 }
1000
1001 /**
1002 * Returns the minimum value for the given calendar field of this
1003 * <code>Calendar</code> instance. The minimum value is
1004 * defined as the smallest value returned by the {@link
1005 * Calendar#get(int) get} method for any possible time value,
1006 * taking into consideration the current values of the
1007 * {@link Calendar#getFirstDayOfWeek() getFirstDayOfWeek},
1008 * {@link Calendar#getMinimalDaysInFirstWeek() getMinimalDaysInFirstWeek},
1009 * and {@link Calendar#getTimeZone() getTimeZone} methods.
1010 *
1011 * @param field the calendar field.
1012 * @return the minimum value for the given calendar field.
1013 * @see #getMaximum(int)
1014 * @see #getGreatestMinimum(int)
1015 * @see #getLeastMaximum(int)
1016 * @see #getActualMinimum(int)
1017 * @see #getActualMaximum(int)
1018 */
1019 public int getMinimum(int field) {
1020 return MIN_VALUES[field];
|