< prev index next >

src/share/classes/java/util/JapaneseImperialCalendar.java

Print this page
rev 8819 : 8202088: Japanese new era implementation
8207152: Placeholder for Japanese new era should be two characters
8206120: Add test cases for lenient Japanese era parsing
Reviewed-by: coffeys, naoto
Contributed-by: deepak.kejriwal@oracle.com
   1 /*
   2  * Copyright (c) 2005, 2006, 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


  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
  59  * supported because it doesn't make any sense to the Japanese
  60  * calendar systems used before Meiji. To represent the years before
  61  * Gregorian year 1, 0 and negative values are used. The Japanese
  62  * Imperial rescripts and government decrees don't specify how to deal
  63  * with time differences for applying the era transitions. This
  64  * calendar implementation assumes local time for all transitions.
  65  *
  66  * @author Masayoshi Okutsu
  67  * @since 1.6
  68  */
  69 class JapaneseImperialCalendar extends Calendar {
  70     /*
  71      * Implementation Notes
  72      *


  84     /**
  85      * The ERA constant designating the Meiji era.
  86      */
  87     public static final int MEIJI = 1;
  88 
  89     /**
  90      * The ERA constant designating the Taisho era.
  91      */
  92     public static final int TAISHO = 2;
  93 
  94     /**
  95      * The ERA constant designating the Showa era.
  96      */
  97     public static final int SHOWA = 3;
  98 
  99     /**
 100      * The ERA constant designating the Heisei era.
 101      */
 102     public static final int HEISEI = 4;
 103 





 104     private static final int EPOCH_OFFSET   = 719163; // Fixed date of January 1, 1970 (Gregorian)
 105     private static final int EPOCH_YEAR     = 1970;
 106 
 107     // Useful millisecond constants.  Although ONE_DAY and ONE_WEEK can fit
 108     // into ints, they must be longs in order to prevent arithmetic overflow
 109     // when performing (bug 4173516).
 110     private static final int  ONE_SECOND = 1000;
 111     private static final int  ONE_MINUTE = 60*ONE_SECOND;
 112     private static final int  ONE_HOUR   = 60*ONE_MINUTE;
 113     private static final long ONE_DAY    = 24*ONE_HOUR;
 114     private static final long ONE_WEEK   = 7*ONE_DAY;
 115 
 116     // Reference to the sun.util.calendar.LocalGregorianCalendar instance (singleton).
 117     private static final LocalGregorianCalendar jcal
 118         = (LocalGregorianCalendar) CalendarSystem.forName("japanese");
 119 
 120     // Gregorian calendar instance. This is required because era
 121     // transition dates are given in Gregorian dates.
 122     private static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
 123 
 124     // The Era instance representing "before Meiji".
 125     private static final Era BEFORE_MEIJI_ERA = new Era("BeforeMeiji", "BM", Long.MIN_VALUE, false);
 126 
 127     // Imperial eras. The sun.util.calendar.LocalGregorianCalendar
 128     // doesn't have an Era representing before Meiji, which is
 129     // inconvenient for a Calendar. So, era[0] is a reference to
 130     // BEFORE_MEIJI_ERA.
 131     private static final Era[] eras;
 132 
 133     // Fixed date of the first date of each era.
 134     private static final long[] sinceFixedDates;
 135 



 136     /*
 137      * <pre>
 138      *                                 Greatest       Least
 139      * Field name             Minimum   Minimum     Maximum     Maximum
 140      * ----------             -------   -------     -------     -------
 141      * ERA                          0         0           1           1
 142      * YEAR                -292275055         1           ?           ?
 143      * MONTH                        0         0          11          11
 144      * WEEK_OF_YEAR                 1         1          52*         53
 145      * WEEK_OF_MONTH                0         0           4*          6
 146      * DAY_OF_MONTH                 1         1          28*         31
 147      * DAY_OF_YEAR                  1         1         365*        366
 148      * DAY_OF_WEEK                  1         1           7           7
 149      * DAY_OF_WEEK_IN_MONTH        -1        -1           4*          6
 150      * AM_PM                        0         0           1           1
 151      * HOUR                         0         0          11          11
 152      * HOUR_OF_DAY                  0         0          23          23
 153      * MINUTE                       0         0          59          59
 154      * SECOND                       0         0          59          59
 155      * MILLISECOND                  0         0         999         999


 211         23,             // HOUR_OF_DAY
 212         59,             // MINUTE
 213         59,             // SECOND
 214         999,            // MILLISECOND
 215         14*ONE_HOUR,    // ZONE_OFFSET
 216         2*ONE_HOUR      // DST_OFFSET (double summer time)
 217     };
 218 
 219     // Proclaim serialization compatibility with JDK 1.6
 220     private static final long serialVersionUID = -3364572813905467929L;
 221 
 222     static {
 223         Era[] es = jcal.getEras();
 224         int length = es.length + 1;
 225         eras = new Era[length];
 226         sinceFixedDates = new long[length];
 227 
 228         // eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
 229         // same as Gregorian.
 230         int index = BEFORE_MEIJI;

 231         sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
 232         eras[index++] = BEFORE_MEIJI_ERA;
 233         for (Era e : es) {



 234             CalendarDate d = e.getSinceDate();
 235             sinceFixedDates[index] = gcal.getFixedDate(d);
 236             eras[index++] = e;
 237         }

 238 
 239         LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
 240 
 241         // Calculate the least maximum year and least day of Year
 242         // values. The following code assumes that there's at most one
 243         // era transition in a Gregorian year.
 244         int year = Integer.MAX_VALUE;
 245         int dayOfYear = Integer.MAX_VALUE;
 246         CalendarDate date = gcal.newCalendarDate(TimeZone.NO_TIMEZONE);
 247         for (int i = 1; i < eras.length; i++) {
 248             long fd = sinceFixedDates[i];
 249             CalendarDate transitionDate = eras[i].getSinceDate();
 250             date.setDate(transitionDate.getYear(), BaseCalendar.JANUARY, 1);
 251             long fdd = gcal.getFixedDate(date);
 252             dayOfYear = Math.min((int)(fdd - fd), dayOfYear);
 253             date.setDate(transitionDate.getYear(), BaseCalendar.DECEMBER, 31);
 254             fdd = gcal.getFixedDate(date) + 1;
 255             dayOfYear = Math.min((int)(fd - fdd), dayOfYear);
 256 
 257             LocalGregorianCalendar.Date lgd = getCalendarDate(fd - 1);


1727             // The spec is to calculate WEEK_OF_YEAR in the
1728             // ISO8601-style. This creates problems, though.
1729             if (weekOfYear == 0) {
1730                 // If the date belongs to the last week of the
1731                 // previous year, use the week number of "12/31" of
1732                 // the "previous" year. Again, if the previous year is
1733                 // a transition year, we need to take care of it.
1734                 // Usually the previous day of the first day of a year
1735                 // is December 31, which is not always true in the
1736                 // Japanese imperial calendar system.
1737                 long fixedDec31 = fixedDateJan1 - 1;
1738                 long prevJan1;
1739                 LocalGregorianCalendar.Date d = getCalendarDate(fixedDec31);
1740                 if (!(transitionYear || isTransitionYear(d.getNormalizedYear()))) {
1741                     prevJan1 = fixedDateJan1 - 365;
1742                     if (d.isLeapYear()) {
1743                         --prevJan1;
1744                     }
1745                 } else if (transitionYear) {
1746                     if (jdate.getYear() == 1) {
1747                         // As of Heisei (since Meiji) there's no case
1748                         // that there are multiple transitions in a
1749                         // year.  Historically there was such
1750                         // case. There might be such case again in the
1751                         // future.
1752                         if (era > HEISEI) {
1753                             CalendarDate pd = eras[era - 1].getSinceDate();
1754                             if (normalizedYear == pd.getYear()) {
1755                                 d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
1756                             }
1757                         } else {
1758                             d.setMonth(jcal.JANUARY).setDayOfMonth(1);
1759                         }
1760                         jcal.normalize(d);
1761                         prevJan1 = jcal.getFixedDate(d);
1762                     } else {
1763                         prevJan1 = fixedDateJan1 - 365;
1764                         if (d.isLeapYear()) {
1765                             --prevJan1;
1766                         }
1767                     }
1768                 } else {
1769                     CalendarDate cd = eras[getEraIndex(jdate)].getSinceDate();
1770                     d.setMonth(cd.getMonth()).setDayOfMonth(cd.getDayOfMonth());
1771                     jcal.normalize(d);
1772                     prevJan1 = jcal.getFixedDate(d);


1867                     if (value < getMinimum(field) || value > getMaximum(field)) {
1868                         throw new IllegalArgumentException(getFieldName(field));
1869                     }
1870                 }
1871                 originalFields[field] = value;
1872             }
1873         }
1874 
1875         // Let the super class determine which calendar fields to be
1876         // used to calculate the time.
1877         int fieldMask = selectFields();
1878 
1879         int year;
1880         int era;
1881 
1882         if (isSet(ERA)) {
1883             era = internalGet(ERA);
1884             year = isSet(YEAR) ? internalGet(YEAR) : 1;
1885         } else {
1886             if (isSet(YEAR)) {
1887                 era = eras.length - 1;
1888                 year = internalGet(YEAR);
1889             } else {
1890                 // Equivalent to 1970 (Gregorian)
1891                 era = SHOWA;
1892                 year = 45;
1893             }
1894         }
1895 
1896         // Calculate the time of day. We rely on the convention that
1897         // an UNSET field has 0.
1898         long timeOfDay = 0;
1899         if (isFieldSet(fieldMask, HOUR_OF_DAY)) {
1900             timeOfDay += (long) internalGet(HOUR_OF_DAY);
1901         } else {
1902             timeOfDay += internalGet(HOUR);
1903             // The default value of AM_PM is 0 which designates AM.
1904             if (isFieldSet(fieldMask, AM_PM)) {
1905                 timeOfDay += 12 * internalGet(AM_PM);
1906             }
1907         }


2349      */
2350     private static final int getRolledValue(int value, int amount, int min, int max) {
2351         assert value >= min && value <= max;
2352         int range = max - min + 1;
2353         amount %= range;
2354         int n = value + amount;
2355         if (n > max) {
2356             n -= range;
2357         } else if (n < min) {
2358             n += range;
2359         }
2360         assert n >= min && n <= max;
2361         return n;
2362     }
2363 
2364     /**
2365      * Returns the ERA.  We need a special method for this because the
2366      * default ERA is the current era, but a zero (unset) ERA means before Meiji.
2367      */
2368     private final int internalGetEra() {
2369         return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
2370     }
2371 
2372     /**
2373      * Updates internal state.
2374      */
2375     private void readObject(ObjectInputStream stream)
2376             throws IOException, ClassNotFoundException {
2377         stream.defaultReadObject();
2378         if (jdate == null) {
2379             jdate = jcal.newCalendarDate(getZone());
2380             cachedFixedDate = Long.MIN_VALUE;
2381         }
2382     }
2383 }
   1 /*
   2  * Copyright (c) 2005, 2019, 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


  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  *     5       NewEra      2019-05-01 midnight local time
  54  * ------------------------------------------------------
  55  * </tt></pre>
  56  *
  57  * <p><code>ERA</code> value 0 specifies the years before Meiji and
  58  * the Gregorian year values are used. Unlike {@link
  59  * GregorianCalendar}, the Julian to Gregorian transition is not
  60  * supported because it doesn't make any sense to the Japanese
  61  * calendar systems used before Meiji. To represent the years before
  62  * Gregorian year 1, 0 and negative values are used. The Japanese
  63  * Imperial rescripts and government decrees don't specify how to deal
  64  * with time differences for applying the era transitions. This
  65  * calendar implementation assumes local time for all transitions.
  66  *
  67  * @author Masayoshi Okutsu
  68  * @since 1.6
  69  */
  70 class JapaneseImperialCalendar extends Calendar {
  71     /*
  72      * Implementation Notes
  73      *


  85     /**
  86      * The ERA constant designating the Meiji era.
  87      */
  88     public static final int MEIJI = 1;
  89 
  90     /**
  91      * The ERA constant designating the Taisho era.
  92      */
  93     public static final int TAISHO = 2;
  94 
  95     /**
  96      * The ERA constant designating the Showa era.
  97      */
  98     public static final int SHOWA = 3;
  99 
 100     /**
 101      * The ERA constant designating the Heisei era.
 102      */
 103     public static final int HEISEI = 4;
 104 
 105     /**
 106      * The ERA constant designating the NewEra era.
 107      */
 108     private static final int NEWERA = 5;
 109 
 110     private static final int EPOCH_OFFSET   = 719163; // Fixed date of January 1, 1970 (Gregorian)
 111     private static final int EPOCH_YEAR     = 1970;
 112 
 113     // Useful millisecond constants.  Although ONE_DAY and ONE_WEEK can fit
 114     // into ints, they must be longs in order to prevent arithmetic overflow
 115     // when performing (bug 4173516).
 116     private static final int  ONE_SECOND = 1000;
 117     private static final int  ONE_MINUTE = 60*ONE_SECOND;
 118     private static final int  ONE_HOUR   = 60*ONE_MINUTE;
 119     private static final long ONE_DAY    = 24*ONE_HOUR;
 120     private static final long ONE_WEEK   = 7*ONE_DAY;
 121 
 122     // Reference to the sun.util.calendar.LocalGregorianCalendar instance (singleton).
 123     private static final LocalGregorianCalendar jcal
 124         = (LocalGregorianCalendar) CalendarSystem.forName("japanese");
 125 
 126     // Gregorian calendar instance. This is required because era
 127     // transition dates are given in Gregorian dates.
 128     private static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
 129 
 130     // The Era instance representing "before Meiji".
 131     private static final Era BEFORE_MEIJI_ERA = new Era("BeforeMeiji", "BM", Long.MIN_VALUE, false);
 132 
 133     // Imperial eras. The sun.util.calendar.LocalGregorianCalendar
 134     // doesn't have an Era representing before Meiji, which is
 135     // inconvenient for a Calendar. So, era[0] is a reference to
 136     // BEFORE_MEIJI_ERA.
 137     private static final Era[] eras;
 138 
 139     // Fixed date of the first date of each era.
 140     private static final long[] sinceFixedDates;
 141 
 142     // The current era
 143     private static final int currentEra;
 144 
 145     /*
 146      * <pre>
 147      *                                 Greatest       Least
 148      * Field name             Minimum   Minimum     Maximum     Maximum
 149      * ----------             -------   -------     -------     -------
 150      * ERA                          0         0           1           1
 151      * YEAR                -292275055         1           ?           ?
 152      * MONTH                        0         0          11          11
 153      * WEEK_OF_YEAR                 1         1          52*         53
 154      * WEEK_OF_MONTH                0         0           4*          6
 155      * DAY_OF_MONTH                 1         1          28*         31
 156      * DAY_OF_YEAR                  1         1         365*        366
 157      * DAY_OF_WEEK                  1         1           7           7
 158      * DAY_OF_WEEK_IN_MONTH        -1        -1           4*          6
 159      * AM_PM                        0         0           1           1
 160      * HOUR                         0         0          11          11
 161      * HOUR_OF_DAY                  0         0          23          23
 162      * MINUTE                       0         0          59          59
 163      * SECOND                       0         0          59          59
 164      * MILLISECOND                  0         0         999         999


 220         23,             // HOUR_OF_DAY
 221         59,             // MINUTE
 222         59,             // SECOND
 223         999,            // MILLISECOND
 224         14*ONE_HOUR,    // ZONE_OFFSET
 225         2*ONE_HOUR      // DST_OFFSET (double summer time)
 226     };
 227 
 228     // Proclaim serialization compatibility with JDK 1.6
 229     private static final long serialVersionUID = -3364572813905467929L;
 230 
 231     static {
 232         Era[] es = jcal.getEras();
 233         int length = es.length + 1;
 234         eras = new Era[length];
 235         sinceFixedDates = new long[length];
 236 
 237         // eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
 238         // same as Gregorian.
 239         int index = BEFORE_MEIJI;
 240         int current = index;
 241         sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
 242         eras[index++] = BEFORE_MEIJI_ERA;
 243         for (Era e : es) {
 244             if(e.getSince(TimeZone.NO_TIMEZONE) < System.currentTimeMillis()) {
 245                 current = index;
 246             }
 247             CalendarDate d = e.getSinceDate();
 248             sinceFixedDates[index] = gcal.getFixedDate(d);
 249             eras[index++] = e;
 250         }
 251         currentEra = current;
 252 
 253         LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
 254 
 255         // Calculate the least maximum year and least day of Year
 256         // values. The following code assumes that there's at most one
 257         // era transition in a Gregorian year.
 258         int year = Integer.MAX_VALUE;
 259         int dayOfYear = Integer.MAX_VALUE;
 260         CalendarDate date = gcal.newCalendarDate(TimeZone.NO_TIMEZONE);
 261         for (int i = 1; i < eras.length; i++) {
 262             long fd = sinceFixedDates[i];
 263             CalendarDate transitionDate = eras[i].getSinceDate();
 264             date.setDate(transitionDate.getYear(), BaseCalendar.JANUARY, 1);
 265             long fdd = gcal.getFixedDate(date);
 266             dayOfYear = Math.min((int)(fdd - fd), dayOfYear);
 267             date.setDate(transitionDate.getYear(), BaseCalendar.DECEMBER, 31);
 268             fdd = gcal.getFixedDate(date) + 1;
 269             dayOfYear = Math.min((int)(fd - fdd), dayOfYear);
 270 
 271             LocalGregorianCalendar.Date lgd = getCalendarDate(fd - 1);


1741             // The spec is to calculate WEEK_OF_YEAR in the
1742             // ISO8601-style. This creates problems, though.
1743             if (weekOfYear == 0) {
1744                 // If the date belongs to the last week of the
1745                 // previous year, use the week number of "12/31" of
1746                 // the "previous" year. Again, if the previous year is
1747                 // a transition year, we need to take care of it.
1748                 // Usually the previous day of the first day of a year
1749                 // is December 31, which is not always true in the
1750                 // Japanese imperial calendar system.
1751                 long fixedDec31 = fixedDateJan1 - 1;
1752                 long prevJan1;
1753                 LocalGregorianCalendar.Date d = getCalendarDate(fixedDec31);
1754                 if (!(transitionYear || isTransitionYear(d.getNormalizedYear()))) {
1755                     prevJan1 = fixedDateJan1 - 365;
1756                     if (d.isLeapYear()) {
1757                         --prevJan1;
1758                     }
1759                 } else if (transitionYear) {
1760                     if (jdate.getYear() == 1) {
1761                         // As of NewEra (since Meiji) there's no case
1762                         // that there are multiple transitions in a
1763                         // year.  Historically there was such
1764                         // case. There might be such case again in the
1765                         // future.
1766                         if (era > NEWERA) {
1767                             CalendarDate pd = eras[era - 1].getSinceDate();
1768                             if (normalizedYear == pd.getYear()) {
1769                                 d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
1770                             }
1771                         } else {
1772                             d.setMonth(jcal.JANUARY).setDayOfMonth(1);
1773                         }
1774                         jcal.normalize(d);
1775                         prevJan1 = jcal.getFixedDate(d);
1776                     } else {
1777                         prevJan1 = fixedDateJan1 - 365;
1778                         if (d.isLeapYear()) {
1779                             --prevJan1;
1780                         }
1781                     }
1782                 } else {
1783                     CalendarDate cd = eras[getEraIndex(jdate)].getSinceDate();
1784                     d.setMonth(cd.getMonth()).setDayOfMonth(cd.getDayOfMonth());
1785                     jcal.normalize(d);
1786                     prevJan1 = jcal.getFixedDate(d);


1881                     if (value < getMinimum(field) || value > getMaximum(field)) {
1882                         throw new IllegalArgumentException(getFieldName(field));
1883                     }
1884                 }
1885                 originalFields[field] = value;
1886             }
1887         }
1888 
1889         // Let the super class determine which calendar fields to be
1890         // used to calculate the time.
1891         int fieldMask = selectFields();
1892 
1893         int year;
1894         int era;
1895 
1896         if (isSet(ERA)) {
1897             era = internalGet(ERA);
1898             year = isSet(YEAR) ? internalGet(YEAR) : 1;
1899         } else {
1900             if (isSet(YEAR)) {
1901                 era = currentEra;
1902                 year = internalGet(YEAR);
1903             } else {
1904                 // Equivalent to 1970 (Gregorian)
1905                 era = SHOWA;
1906                 year = 45;
1907             }
1908         }
1909 
1910         // Calculate the time of day. We rely on the convention that
1911         // an UNSET field has 0.
1912         long timeOfDay = 0;
1913         if (isFieldSet(fieldMask, HOUR_OF_DAY)) {
1914             timeOfDay += (long) internalGet(HOUR_OF_DAY);
1915         } else {
1916             timeOfDay += internalGet(HOUR);
1917             // The default value of AM_PM is 0 which designates AM.
1918             if (isFieldSet(fieldMask, AM_PM)) {
1919                 timeOfDay += 12 * internalGet(AM_PM);
1920             }
1921         }


2363      */
2364     private static final int getRolledValue(int value, int amount, int min, int max) {
2365         assert value >= min && value <= max;
2366         int range = max - min + 1;
2367         amount %= range;
2368         int n = value + amount;
2369         if (n > max) {
2370             n -= range;
2371         } else if (n < min) {
2372             n += range;
2373         }
2374         assert n >= min && n <= max;
2375         return n;
2376     }
2377 
2378     /**
2379      * Returns the ERA.  We need a special method for this because the
2380      * default ERA is the current era, but a zero (unset) ERA means before Meiji.
2381      */
2382     private final int internalGetEra() {
2383         return isSet(ERA) ? internalGet(ERA) : currentEra;
2384     }
2385 
2386     /**
2387      * Updates internal state.
2388      */
2389     private void readObject(ObjectInputStream stream)
2390             throws IOException, ClassNotFoundException {
2391         stream.defaultReadObject();
2392         if (jdate == null) {
2393             jdate = jcal.newCalendarDate(getZone());
2394             cachedFixedDate = Long.MIN_VALUE;
2395         }
2396     }
2397 }
< prev index next >