Source Code Cross Referenced for GregorianCalendar.java in  » 6.0-JDK-Modules » j2me » java » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * 
0003:         * @(#)GregorianCalendar.java	1.64 06/10/10
0004:         * 
0005:         * Portions Copyright  2000-2006 Sun Microsystems, Inc. All Rights
0006:         * Reserved.  Use is subject to license terms.
0007:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0008:         * 
0009:         * This program is free software; you can redistribute it and/or
0010:         * modify it under the terms of the GNU General Public License version
0011:         * 2 only, as published by the Free Software Foundation.
0012:         * 
0013:         * This program is distributed in the hope that it will be useful, but
0014:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0016:         * General Public License version 2 for more details (a copy is
0017:         * included at /legal/license.txt).
0018:         * 
0019:         * You should have received a copy of the GNU General Public License
0020:         * version 2 along with this work; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0022:         * 02110-1301 USA
0023:         * 
0024:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0025:         * Clara, CA 95054 or visit www.sun.com if you need additional
0026:         * information or have any questions.
0027:         */
0028:
0029:        /*
0030:         * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
0031:         * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
0032:         *
0033:         *   The original version of this source code and documentation is copyrighted
0034:         * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
0035:         * materials are provided under terms of a License Agreement between Taligent
0036:         * and Sun. This technology is protected by multiple US and International
0037:         * patents. This notice and attribution to Taligent may not be removed.
0038:         *   Taligent is a registered trademark of Taligent, Inc.
0039:         *
0040:         */
0041:
0042:        package java.util;
0043:
0044:        import java.io.IOException;
0045:        import java.io.ObjectInputStream;
0046:        import sun.util.calendar.ZoneInfo;
0047:
0048:        /**
0049:         * <code>GregorianCalendar</code> is a concrete subclass of
0050:         * {@link Calendar}
0051:         * and provides the standard calendar used by most of the world.
0052:         *
0053:         * <p>
0054:         * The standard (Gregorian) calendar has 2 eras, BC and AD.
0055:         *
0056:         * <p>
0057:         * This implementation handles a single discontinuity, which corresponds by
0058:         * default to the date the Gregorian calendar was instituted (October 15, 1582
0059:         * in some countries, later in others).  The cutover date may be changed by the
0060:         * caller by calling <code>setGregorianChange()</code>.
0061:         *
0062:         * <p>
0063:         * Historically, in those countries which adopted the Gregorian calendar first,
0064:         * October 4, 1582 was thus followed by October 15, 1582. This calendar models
0065:         * this correctly.  Before the Gregorian cutover, <code>GregorianCalendar</code>
0066:         * implements the Julian calendar.  The only difference between the Gregorian
0067:         * and the Julian calendar is the leap year rule. The Julian calendar specifies
0068:         * leap years every four years, whereas the Gregorian calendar omits century
0069:         * years which are not divisible by 400.
0070:         *
0071:         * <p>
0072:         * <code>GregorianCalendar</code> implements <em>proleptic</em> Gregorian and
0073:         * Julian calendars. That is, dates are computed by extrapolating the current
0074:         * rules indefinitely far backward and forward in time. As a result,
0075:         * <code>GregorianCalendar</code> may be used for all years to generate
0076:         * meaningful and consistent results. However, dates obtained using
0077:         * <code>GregorianCalendar</code> are historically accurate only from March 1, 4
0078:         * AD onward, when modern Julian calendar rules were adopted.  Before this date,
0079:         * leap year rules were applied irregularly, and before 45 BC the Julian
0080:         * calendar did not even exist.
0081:         *
0082:         * <p>
0083:         * Prior to the institution of the Gregorian calendar, New Year's Day was
0084:         * March 25. To avoid confusion, this calendar always uses January 1. A manual
0085:         * adjustment may be made if desired for dates that are prior to the Gregorian
0086:         * changeover and which fall between January 1 and March 24.
0087:         *
0088:         * <p>Values calculated for the <code>WEEK_OF_YEAR</code> field range from 1 to
0089:         * 53.  Week 1 for a year is the earliest seven day period starting on
0090:         * <code>getFirstDayOfWeek()</code> that contains at least
0091:         * <code>getMinimalDaysInFirstWeek()</code> days from that year.  It thus
0092:         * depends on the values of <code>getMinimalDaysInFirstWeek()</code>,
0093:         * <code>getFirstDayOfWeek()</code>, and the day of the week of January 1.
0094:         * Weeks between week 1 of one year and week 1 of the following year are
0095:         * numbered sequentially from 2 to 52 or 53 (as needed).
0096:
0097:         * <p>For example, January 1, 1998 was a Thursday.  If
0098:         * <code>getFirstDayOfWeek()</code> is <code>MONDAY</code> and
0099:         * <code>getMinimalDaysInFirstWeek()</code> is 4 (these are the values
0100:         * reflecting ISO 8601 and many national standards), then week 1 of 1998 starts
0101:         * on December 29, 1997, and ends on January 4, 1998.  If, however,
0102:         * <code>getFirstDayOfWeek()</code> is <code>SUNDAY</code>, then week 1 of 1998
0103:         * starts on January 4, 1998, and ends on January 10, 1998; the first three days
0104:         * of 1998 then are part of week 53 of 1997.
0105:         *
0106:         * <p>Values calculated for the <code>WEEK_OF_MONTH</code> field range from 0
0107:         * to 6.  Week 1 of a month (the days with <code>WEEK_OF_MONTH =
0108:         * 1</code>) is the earliest set of at least
0109:         * <code>getMinimalDaysInFirstWeek()</code> contiguous days in that month,
0110:         * ending on the day before <code>getFirstDayOfWeek()</code>.  Unlike
0111:         * week 1 of a year, week 1 of a month may be shorter than 7 days, need
0112:         * not start on <code>getFirstDayOfWeek()</code>, and will not include days of
0113:         * the previous month.  Days of a month before week 1 have a
0114:         * <code>WEEK_OF_MONTH</code> of 0.
0115:         *
0116:         * <p>For example, if <code>getFirstDayOfWeek()</code> is <code>SUNDAY</code>
0117:         * and <code>getMinimalDaysInFirstWeek()</code> is 4, then the first week of
0118:         * January 1998 is Sunday, January 4 through Saturday, January 10.  These days
0119:         * have a <code>WEEK_OF_MONTH</code> of 1.  Thursday, January 1 through
0120:         * Saturday, January 3 have a <code>WEEK_OF_MONTH</code> of 0.  If
0121:         * <code>getMinimalDaysInFirstWeek()</code> is changed to 3, then January 1
0122:         * through January 3 have a <code>WEEK_OF_MONTH</code> of 1.
0123:         *
0124:         * <p>
0125:         * <strong>Example:</strong>
0126:         * <blockquote>
0127:         * <pre>
0128:         * // get the supported ids for GMT-08:00 (Pacific Standard Time)
0129:         * String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
0130:         * // if no ids were returned, something is wrong. get out.
0131:         * if (ids.length == 0)
0132:         *     System.exit(0);
0133:         *
0134:         *  // begin output
0135:         * System.out.println("Current Time");
0136:         *
0137:         * // create a Pacific Standard Time time zone
0138:         * SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
0139:         *
0140:         * // set up rules for daylight savings time
0141:         * pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
0142:         * pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
0143:         *
0144:         * // create a GregorianCalendar with the Pacific Daylight time zone
0145:         * // and the current date and time
0146:         * Calendar calendar = new GregorianCalendar(pdt);
0147:         * Date trialTime = new Date();
0148:         * calendar.setTime(trialTime);
0149:         *
0150:         * // print out a bunch of interesting things
0151:         * System.out.println("ERA: " + calendar.get(Calendar.ERA));
0152:         * System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
0153:         * System.out.println("MONTH: " + calendar.get(Calendar.MONTH));
0154:         * System.out.println("WEEK_OF_YEAR: " + calendar.get(Calendar.WEEK_OF_YEAR));
0155:         * System.out.println("WEEK_OF_MONTH: " + calendar.get(Calendar.WEEK_OF_MONTH));
0156:         * System.out.println("DATE: " + calendar.get(Calendar.DATE));
0157:         * System.out.println("DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
0158:         * System.out.println("DAY_OF_YEAR: " + calendar.get(Calendar.DAY_OF_YEAR));
0159:         * System.out.println("DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK));
0160:         * System.out.println("DAY_OF_WEEK_IN_MONTH: "
0161:         *                    + calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));
0162:         * System.out.println("AM_PM: " + calendar.get(Calendar.AM_PM));
0163:         * System.out.println("HOUR: " + calendar.get(Calendar.HOUR));
0164:         * System.out.println("HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
0165:         * System.out.println("MINUTE: " + calendar.get(Calendar.MINUTE));
0166:         * System.out.println("SECOND: " + calendar.get(Calendar.SECOND));
0167:         * System.out.println("MILLISECOND: " + calendar.get(Calendar.MILLISECOND));
0168:         * System.out.println("ZONE_OFFSET: "
0169:         *                    + (calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000)));
0170:         * System.out.println("DST_OFFSET: "
0171:         *                    + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000)));
0172:
0173:         * System.out.println("Current Time, with hour reset to 3");
0174:         * calendar.clear(Calendar.HOUR_OF_DAY); // so doesn't override
0175:         * calendar.set(Calendar.HOUR, 3);
0176:         * System.out.println("ERA: " + calendar.get(Calendar.ERA));
0177:         * System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
0178:         * System.out.println("MONTH: " + calendar.get(Calendar.MONTH));
0179:         * System.out.println("WEEK_OF_YEAR: " + calendar.get(Calendar.WEEK_OF_YEAR));
0180:         * System.out.println("WEEK_OF_MONTH: " + calendar.get(Calendar.WEEK_OF_MONTH));
0181:         * System.out.println("DATE: " + calendar.get(Calendar.DATE));
0182:         * System.out.println("DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
0183:         * System.out.println("DAY_OF_YEAR: " + calendar.get(Calendar.DAY_OF_YEAR));
0184:         * System.out.println("DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK));
0185:         * System.out.println("DAY_OF_WEEK_IN_MONTH: "
0186:         *                    + calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));
0187:         * System.out.println("AM_PM: " + calendar.get(Calendar.AM_PM));
0188:         * System.out.println("HOUR: " + calendar.get(Calendar.HOUR));
0189:         * System.out.println("HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
0190:         * System.out.println("MINUTE: " + calendar.get(Calendar.MINUTE));
0191:         * System.out.println("SECOND: " + calendar.get(Calendar.SECOND));
0192:         * System.out.println("MILLISECOND: " + calendar.get(Calendar.MILLISECOND));
0193:         * System.out.println("ZONE_OFFSET: "
0194:         *        + (calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000))); // in hours
0195:         * System.out.println("DST_OFFSET: "
0196:         *        + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000))); // in hours
0197:         * </pre>
0198:         * </blockquote>
0199:         *
0200:         * @see          Calendar
0201:         * @see          TimeZone
0202:         * @version      1.64, 10/10/06
0203:         * @author David Goldsmith, Mark Davis, Chen-Lieh Huang, Alan Liu
0204:         * @since JDK1.1
0205:         */
0206:        public class GregorianCalendar extends Calendar {
0207:            /*
0208:             * Implementation Notes
0209:             *
0210:             * The Julian day number, as used here, is a modified number which has its
0211:             * onset at midnight, rather than noon.
0212:             *
0213:             * The epoch is the number of days or milliseconds from some defined
0214:             * starting point. The epoch for java.util.Date is used here; that is,
0215:             * milliseconds from January 1, 1970 (Gregorian), midnight UTC.  Other
0216:             * epochs which are used are January 1, year 1 (Gregorian), which is day 1
0217:             * of the Gregorian calendar, and December 30, year 0 (Gregorian), which is
0218:             * day 1 of the Julian calendar.
0219:             *
0220:             * We implement the proleptic Julian and Gregorian calendars.  This means we
0221:             * implement the modern definition of the calendar even though the
0222:             * historical usage differs.  For example, if the Gregorian change is set
0223:             * to new Date(Long.MIN_VALUE), we have a pure Gregorian calendar which
0224:             * labels dates preceding the invention of the Gregorian calendar in 1582 as
0225:             * if the calendar existed then.
0226:             *
0227:             * Likewise, with the Julian calendar, we assume a consistent 4-year leap
0228:             * rule, even though the historical pattern of leap years is irregular,
0229:             * being every 3 years from 45 BC through 9 BC, then every 4 years from 8 AD
0230:             * onwards, with no leap years in-between.  Thus date computations and
0231:             * functions such as isLeapYear() are not intended to be historically
0232:             * accurate.
0233:             *
0234:             * Given that milliseconds are a long, day numbers such as Julian day
0235:             * numbers, Gregorian or Julian calendar days, or epoch days, are also
0236:             * longs. Years can fit into an int.
0237:             */
0238:
0239:            //////////////////
0240:            // Class Variables
0241:            //////////////////
0242:            /**
0243:             * Value of the <code>ERA</code> field indicating
0244:             * the period before the common era (before Christ), also known as BCE.
0245:             * The sequence of years at the transition from <code>BC</code> to <code>AD</code> is
0246:             * ..., 2 BC, 1 BC, 1 AD, 2 AD,...
0247:             * @see Calendar#ERA
0248:             */
0249:            public static final int BC = 0;
0250:
0251:            /**
0252:             * Value of the <code>ERA</code> field indicating
0253:             * the common era (Anno Domini), also known as CE.
0254:             * The sequence of years at the transition from <code>BC</code> to <code>AD</code> is
0255:             * ..., 2 BC, 1 BC, 1 AD, 2 AD,...
0256:             * @see Calendar#ERA
0257:             */
0258:            public static final int AD = 1;
0259:
0260:            private static final int JAN_1_1_JULIAN_DAY = 1721426; // January 1, year 1 (Gregorian)
0261:            private static final int EPOCH_JULIAN_DAY = 2440588; // January 1, 1970 (Gregorian)
0262:            private static final int EPOCH_YEAR = 1970;
0263:
0264:            private static final int NUM_DAYS[] = { 0, 31, 59, 90, 120, 151,
0265:                    181, 212, 243, 273, 304, 334 }; // 0-based, for day-in-year
0266:            private static final int LEAP_NUM_DAYS[] = { 0, 31, 60, 91, 121,
0267:                    152, 182, 213, 244, 274, 305, 335 }; // 0-based, for day-in-year
0268:            private static final int MONTH_LENGTH[] = { 31, 28, 31, 30, 31, 30,
0269:                    31, 31, 30, 31, 30, 31 }; // 0-based
0270:            private static final int LEAP_MONTH_LENGTH[] = { 31, 29, 31, 30,
0271:                    31, 30, 31, 31, 30, 31, 30, 31 }; // 0-based
0272:
0273:            // Useful millisecond constants.  Although ONE_DAY and ONE_WEEK can fit
0274:            // into ints, they must be longs in order to prevent arithmetic overflow
0275:            // when performing (bug 4173516).
0276:            private static final int ONE_SECOND = 1000;
0277:            private static final int ONE_MINUTE = 60 * ONE_SECOND;
0278:            private static final int ONE_HOUR = 60 * ONE_MINUTE;
0279:            private static final long ONE_DAY = 24 * ONE_HOUR;
0280:            private static final long ONE_WEEK = 7 * ONE_DAY;
0281:
0282:            /*
0283:             * <pre>
0284:             *                            Greatest       Least 
0285:             * Field name        Minimum   Minimum     Maximum     Maximum
0286:             * ----------        -------   -------     -------     -------
0287:             * ERA                     0         0           1           1
0288:             * YEAR                    1         1   292269054   292278994
0289:             * MONTH                   0         0          11          11
0290:             * WEEK_OF_YEAR            1         1          52          53
0291:             * WEEK_OF_MONTH           0         0           4           6
0292:             * DAY_OF_MONTH            1         1          28          31
0293:             * DAY_OF_YEAR             1         1         365         366
0294:             * DAY_OF_WEEK             1         1           7           7
0295:             * DAY_OF_WEEK_IN_MONTH   -1        -1           4           6
0296:             * AM_PM                   0         0           1           1
0297:             * HOUR                    0         0          11          11
0298:             * HOUR_OF_DAY             0         0          23          23
0299:             * MINUTE                  0         0          59          59
0300:             * SECOND                  0         0          59          59
0301:             * MILLISECOND             0         0         999         999
0302:             * ZONE_OFFSET           -12*      -12*         12*         12*
0303:             * DST_OFFSET              0         0           1*          1*
0304:             * </pre>
0305:             * (*) In units of one-hour
0306:             */
0307:            private static final int MIN_VALUES[] = { 0, 1, 0, 1, 0, 1, 1, 1,
0308:                    -1, 0, 0, 0, 0, 0, 0, -12 * ONE_HOUR, 0 };
0309:            private static final int LEAST_MAX_VALUES[] = { 1, 292269054, 11,
0310:                    52, 4, 28, 365, 7, 4, 1, 11, 23, 59, 59, 999,
0311:                    12 * ONE_HOUR, 1 * ONE_HOUR };
0312:            private static final int MAX_VALUES[] = { 1, 292278994, 11, 53, 6,
0313:                    31, 366, 7, 6, 1, 11, 23, 59, 59, 999, 12 * ONE_HOUR,
0314:                    1 * ONE_HOUR };
0315:
0316:            /////////////////////
0317:            // Instance Variables
0318:            /////////////////////
0319:
0320:            /**
0321:             * The point at which the Gregorian calendar rules are used, measured in
0322:             * milliseconds from the standard epoch.  Default is October 15, 1582
0323:             * (Gregorian) 00:00:00 UTC or -12219292800000L.  For this value, October 4,
0324:             * 1582 (Julian) is followed by October 15, 1582 (Gregorian).  This
0325:             * corresponds to Julian day number 2299161.
0326:             * @serial
0327:             */
0328:            private long gregorianCutover = -12219292800000L;
0329:
0330:            /**
0331:             * Midnight, local time (using this Calendar's TimeZone) at or before the
0332:             * gregorianCutover. This is a pure date value with no time of day or
0333:             * timezone component.
0334:             */
0335:            private transient long normalizedGregorianCutover = gregorianCutover;
0336:
0337:            /**
0338:             * The year of the gregorianCutover, with 0 representing
0339:             * 1 BC, -1 representing 2 BC, etc.
0340:             */
0341:            private transient int gregorianCutoverYear = 1582;
0342:
0343:            // Proclaim serialization compatibility with JDK 1.1
0344:            static final long serialVersionUID = -8125100834729963327L;
0345:
0346:            ///////////////
0347:            // Constructors
0348:            ///////////////
0349:
0350:            /**
0351:             * Constructs a default GregorianCalendar using the current time
0352:             * in the default time zone with the default locale.
0353:             */
0354:            public GregorianCalendar() {
0355:                this (TimeZone.getDefault(), Locale.getDefault());
0356:            }
0357:
0358:            /**
0359:             * Constructs a GregorianCalendar based on the current time
0360:             * in the given time zone with the default locale.
0361:             * @param zone the given time zone.
0362:             */
0363:            public GregorianCalendar(TimeZone zone) {
0364:                this (zone, Locale.getDefault());
0365:            }
0366:
0367:            /**
0368:             * Constructs a GregorianCalendar based on the current time
0369:             * in the default time zone with the given locale.
0370:             * @param aLocale the given locale.
0371:             */
0372:            public GregorianCalendar(Locale aLocale) {
0373:                this (TimeZone.getDefault(), aLocale);
0374:            }
0375:
0376:            /**
0377:             * Constructs a GregorianCalendar based on the current time
0378:             * in the given time zone with the given locale.
0379:             * @param zone the given time zone.
0380:             * @param aLocale the given locale.
0381:             */
0382:            public GregorianCalendar(TimeZone zone, Locale aLocale) {
0383:                super (zone, aLocale);
0384:                setTimeInMillis(System.currentTimeMillis());
0385:            }
0386:
0387:            /**
0388:             * Constructs a GregorianCalendar with the given date set
0389:             * in the default time zone with the default locale.
0390:             * @param year the value used to set the YEAR time field in the calendar.
0391:             * @param month the value used to set the MONTH time field in the calendar.
0392:             * Month value is 0-based. e.g., 0 for January.
0393:             * @param date the value used to set the DATE time field in the calendar.
0394:             */
0395:            public GregorianCalendar(int year, int month, int date) {
0396:                super (TimeZone.getDefault(), Locale.getDefault());
0397:                this .set(YEAR, year);
0398:                this .set(MONTH, month);
0399:                this .set(DATE, date);
0400:            }
0401:
0402:            /**
0403:             * Constructs a GregorianCalendar with the given date
0404:             * and time set for the default time zone with the default locale.
0405:             * @param year the value used to set the YEAR time field in the calendar.
0406:             * @param month the value used to set the MONTH time field in the calendar.
0407:             * Month value is 0-based. e.g., 0 for January.
0408:             * @param date the value used to set the DATE time field in the calendar.
0409:             * @param hour the value used to set the HOUR_OF_DAY time field
0410:             * in the calendar.
0411:             * @param minute the value used to set the MINUTE time field
0412:             * in the calendar.
0413:             */
0414:            public GregorianCalendar(int year, int month, int date, int hour,
0415:                    int minute) {
0416:                super (TimeZone.getDefault(), Locale.getDefault());
0417:                this .set(YEAR, year);
0418:                this .set(MONTH, month);
0419:                this .set(DATE, date);
0420:                this .set(HOUR_OF_DAY, hour);
0421:                this .set(MINUTE, minute);
0422:            }
0423:
0424:            /**
0425:             * Constructs a GregorianCalendar with the given date
0426:             * and time set for the default time zone with the default locale.
0427:             * @param year the value used to set the YEAR time field in the calendar.
0428:             * @param month the value used to set the MONTH time field in the calendar.
0429:             * Month value is 0-based. e.g., 0 for January.
0430:             * @param date the value used to set the DATE time field in the calendar.
0431:             * @param hour the value used to set the HOUR_OF_DAY time field
0432:             * in the calendar.
0433:             * @param minute the value used to set the MINUTE time field
0434:             * in the calendar.
0435:             * @param second the value used to set the SECOND time field
0436:             * in the calendar.
0437:             */
0438:            public GregorianCalendar(int year, int month, int date, int hour,
0439:                    int minute, int second) {
0440:                super (TimeZone.getDefault(), Locale.getDefault());
0441:                this .set(YEAR, year);
0442:                this .set(MONTH, month);
0443:                this .set(DATE, date);
0444:                this .set(HOUR_OF_DAY, hour);
0445:                this .set(MINUTE, minute);
0446:                this .set(SECOND, second);
0447:            }
0448:
0449:            /////////////////
0450:            // Public methods
0451:            /////////////////
0452:
0453:            /**
0454:             * Sets the GregorianCalendar change date. This is the point when the switch
0455:             * from Julian dates to Gregorian dates occurred. Default is October 15,
0456:             * 1582. Previous to this, dates will be in the Julian calendar.
0457:             * <p>
0458:             * To obtain a pure Julian calendar, set the change date to
0459:             * <code>Date(Long.MAX_VALUE)</code>.  To obtain a pure Gregorian calendar,
0460:             * set the change date to <code>Date(Long.MIN_VALUE)</code>.
0461:             *
0462:             * @param date the given Gregorian cutover date.
0463:             */
0464:            public void setGregorianChange(Date date) {
0465:                gregorianCutover = date.getTime();
0466:
0467:                // Precompute two internal variables which we use to do the actual
0468:                // cutover computations.  These are the normalized cutover, which is the
0469:                // midnight at or before the cutover, and the cutover year.  The
0470:                // normalized cutover is in pure date milliseconds; it contains no time
0471:                // of day or timezone component, and it used to compare against other
0472:                // pure date values.
0473:                long cutoverDay = floorDivide(gregorianCutover, ONE_DAY);
0474:                normalizedGregorianCutover = cutoverDay * ONE_DAY;
0475:
0476:                // Handle the rare case of numeric overflow.  If the user specifies a
0477:                // change of Date(Long.MIN_VALUE), in order to get a pure Gregorian
0478:                // calendar, then the epoch day is -106751991168, which when multiplied
0479:                // by ONE_DAY gives 9223372036794351616 -- the negative value is too
0480:                // large for 64 bits, and overflows into a positive value.  We correct
0481:                // this by using the next day, which for all intents is semantically
0482:                // equivalent.
0483:                if (cutoverDay < 0 && normalizedGregorianCutover > 0) {
0484:                    normalizedGregorianCutover = (cutoverDay + 1) * ONE_DAY;
0485:                }
0486:
0487:                // Normalize the year so BC values are represented as 0 and negative
0488:                // values.
0489:                GregorianCalendar cal = new GregorianCalendar(getTimeZone());
0490:                cal.setTime(date);
0491:                gregorianCutoverYear = cal.get(YEAR);
0492:                if (cal.get(ERA) == BC) {
0493:                    gregorianCutoverYear = 1 - gregorianCutoverYear;
0494:                }
0495:            }
0496:
0497:            /**
0498:             * Gets the Gregorian Calendar change date.  This is the point when the
0499:             * switch from Julian dates to Gregorian dates occurred. Default is
0500:             * October 15, 1582. Previous to this, dates will be in the Julian
0501:             * calendar.
0502:             * @return the Gregorian cutover date for this calendar.
0503:             */
0504:            public final Date getGregorianChange() {
0505:                return new Date(gregorianCutover);
0506:            }
0507:
0508:            /**
0509:             * Determines if the given year is a leap year. Returns true if the
0510:             * given year is a leap year.
0511:             * @param year the given year.
0512:             * @return true if the given year is a leap year; false otherwise.
0513:             */
0514:            public boolean isLeapYear(int year) {
0515:                return year >= gregorianCutoverYear ? ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))
0516:                        : // Gregorian
0517:                        (year % 4 == 0); // Julian
0518:            }
0519:
0520:            /**
0521:             * Compares this GregorianCalendar to an object reference.
0522:             * @param obj the object reference with which to compare
0523:             * @return true if this object is equal to <code>obj</code>; false otherwise
0524:             */
0525:            public boolean equals(Object obj) {
0526:                return super .equals(obj)
0527:                        && obj instanceof  GregorianCalendar
0528:                        && gregorianCutover == ((GregorianCalendar) obj).gregorianCutover;
0529:            }
0530:
0531:            /**
0532:             * Override hashCode.
0533:             * Generates the hash code for the GregorianCalendar object
0534:             */
0535:            public int hashCode() {
0536:                return super .hashCode() ^ (int) gregorianCutover;
0537:            }
0538:
0539:            /**
0540:             * Adds the specified (signed) amount of time to the given time field,
0541:             * based on the calendar's rules.
0542:             * <p><em>Add rule 1</em>. The value of <code>field</code>
0543:             * after the call minus the value of <code>field</code> before the
0544:             * call is <code>amount</code>, modulo any overflow that has occurred in
0545:             * <code>field</code>. Overflow occurs when a field value exceeds its
0546:             * range and, as a result, the next larger field is incremented or
0547:             * decremented and the field value is adjusted back into its range.</p>
0548:             *
0549:             * <p><em>Add rule 2</em>. If a smaller field is expected to be
0550:             * invariant, but it is impossible for it to be equal to its
0551:             * prior value because of changes in its minimum or maximum after
0552:             * <code>field</code> is changed, then its value is adjusted to be as close
0553:             * as possible to its expected value. A smaller field represents a
0554:             * smaller unit of time. <code>HOUR</code> is a smaller field than
0555:             * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
0556:             * that are not expected to be invariant. The calendar system
0557:             * determines what fields are expected to be invariant.</p>
0558:             * @param field the time field.
0559:             * @param amount the amount of date or time to be added to the field.
0560:             * @exception IllegalArgumentException if an unknown field is given.
0561:             */
0562:            public void add(int field, int amount) {
0563:                if (amount == 0) {
0564:                    return; // Do nothing!
0565:                }
0566:                complete();
0567:
0568:                if (field == YEAR) {
0569:                    int year = this .internalGet(YEAR);
0570:                    if (this .internalGetEra() == AD) {
0571:                        year += amount;
0572:                        if (year > 0) {
0573:                            this .set(YEAR, year);
0574:                        } else { // year <= 0
0575:                            this .set(YEAR, 1 - year);
0576:                            // if year == 0, you get 1 BC
0577:                            this .set(ERA, BC);
0578:                        }
0579:                    } else { // era == BC
0580:                        year -= amount;
0581:                        if (year > 0) {
0582:                            this .set(YEAR, year);
0583:                        } else { // year <= 0
0584:                            this .set(YEAR, 1 - year);
0585:                            // if year == 0, you get 1 AD
0586:                            this .set(ERA, AD);
0587:                        }
0588:                    }
0589:                    pinDayOfMonth();
0590:                } else if (field == MONTH) {
0591:                    int month = this .internalGet(MONTH) + amount;
0592:                    int year = this .internalGet(YEAR);
0593:                    int y_amount;
0594:
0595:                    if (month >= 0) {
0596:                        y_amount = month / 12;
0597:                    } else {
0598:                        y_amount = (month + 1) / 12 - 1;
0599:                    }
0600:                    if (y_amount != 0) {
0601:                        if (this .internalGetEra() == AD) {
0602:                            year += y_amount;
0603:                            if (year > 0) {
0604:                                this .set(YEAR, year);
0605:                            } else { // year <= 0
0606:                                this .set(YEAR, 1 - year);
0607:                                // if year == 0, you get 1 BC
0608:                                this .set(ERA, BC);
0609:                            }
0610:                        } else { // era == BC
0611:                            year -= y_amount;
0612:                            if (year > 0) {
0613:                                this .set(YEAR, year);
0614:                            } else { // year <= 0
0615:                                this .set(YEAR, 1 - year);
0616:                                // if year == 0, you get 1 AD
0617:                                this .set(ERA, AD);
0618:                            }
0619:                        }
0620:                    }
0621:
0622:                    if (month >= 0) {
0623:                        set(MONTH, (int) (month % 12));
0624:                    } else {
0625:                        // month < 0
0626:                        month %= 12;
0627:                        if (month < 0) {
0628:                            month += 12;
0629:                        }
0630:                        set(MONTH, JANUARY + month);
0631:                    }
0632:                    pinDayOfMonth();
0633:                } else if (field == ERA) {
0634:                    int era = internalGet(ERA) + amount;
0635:                    if (era < 0) {
0636:                        era = 0;
0637:                    }
0638:                    if (era > 1) {
0639:                        era = 1;
0640:                    }
0641:                    set(ERA, era);
0642:                } else {
0643:                    // We handle most fields here.  The algorithm is to add a computed amount
0644:                    // of millis to the current millis.  The only wrinkle is with DST -- if
0645:                    // the result of the add operation is to move from DST to Standard, or vice
0646:                    // versa, we need to adjust by an hour forward or back, respectively.
0647:                    // Otherwise you get unusual effects in which the hour seems to shift when
0648:                    // you add to the DAY_OF_MONTH field, for instance.
0649:
0650:                    // We only adjust the DST for fields larger than an hour.  For fields
0651:                    // smaller than an hour, we cannot adjust for DST without causing problems.
0652:                    // for instance, if you add one hour to April 5, 1998, 1:00 AM, in PST,
0653:                    // the time becomes "2:00 AM PDT" (an illegal value), but then the adjustment
0654:                    // sees the change and compensates by subtracting an hour.  As a result the
0655:                    // time doesn't advance at all.
0656:
0657:                    long delta = amount;
0658:                    boolean adjustDST = true;
0659:
0660:                    switch (field) {
0661:                    case WEEK_OF_YEAR:
0662:                    case WEEK_OF_MONTH:
0663:                    case DAY_OF_WEEK_IN_MONTH:
0664:                        delta *= 7 * 24 * 60 * 60 * 1000; // 7 days
0665:                        break;
0666:
0667:                    case AM_PM:
0668:                        delta *= 12 * 60 * 60 * 1000; // 12 hrs
0669:                        break;
0670:
0671:                    case DATE: // synonym of DAY_OF_MONTH
0672:                    case DAY_OF_YEAR:
0673:                    case DAY_OF_WEEK:
0674:                        delta *= 24 * 60 * 60 * 1000; // 1 day
0675:                        break;
0676:
0677:                    case HOUR_OF_DAY:
0678:                    case HOUR:
0679:                        delta *= 60 * 60 * 1000; // 1 hour
0680:                        adjustDST = false;
0681:                        break;
0682:
0683:                    case MINUTE:
0684:                        delta *= 60 * 1000; // 1 minute
0685:                        adjustDST = false;
0686:                        break;
0687:
0688:                    case SECOND:
0689:                        delta *= 1000; // 1 second
0690:                        adjustDST = false;
0691:                        break;
0692:
0693:                    case MILLISECOND:
0694:                        adjustDST = false;
0695:                        break;
0696:
0697:                    case ZONE_OFFSET:
0698:                    case DST_OFFSET:
0699:                    default:
0700:                        throw new IllegalArgumentException();
0701:                    }
0702:
0703:                    // Save the current DST state.
0704:                    long dst = 0;
0705:                    if (adjustDST) {
0706:                        dst = internalGet(DST_OFFSET);
0707:                    }
0708:
0709:                    setTimeInMillis(time + delta); // Automatically computes fields if necessary
0710:
0711:                    if (adjustDST) {
0712:                        // Now do the DST adjustment alluded to above.
0713:                        // Only call setTimeInMillis if necessary, because it's an expensive call.
0714:                        dst -= internalGet(DST_OFFSET);
0715:                        if (dst != 0) {
0716:                            setTimeInMillis(time + dst);
0717:                        }
0718:                    }
0719:                }
0720:            }
0721:
0722:            /**
0723:             * Adds or subtracts (up/down) a single unit of time on the given time
0724:             * field without changing larger fields. 
0725:             * <p>
0726:             * <em>Example</em>: Consider a <code>GregorianCalendar</code>
0727:             * originally set to December 31, 1999. Calling <code>roll(Calendar.MONTH, true)</code>
0728:             * sets the calendar to January 31, 1999.  The <code>Year</code> field is unchanged
0729:             * because it is a larger field than <code>MONTH</code>.</p>
0730:             * @param up indicates if the value of the specified time field is to be
0731:             * rolled up or rolled down. Use true if rolling up, false otherwise.
0732:             * @exception IllegalArgumentException if an unknown field value is given.
0733:             * @see GregorianCalendar#add
0734:             * @see GregorianCalendar#set
0735:             */
0736:            public void roll(int field, boolean up) {
0737:                roll(field, up ? +1 : -1);
0738:            }
0739:
0740:            /**
0741:             * Add to field a signed amount without changing larger fields.
0742:             * A negative roll amount means to subtract from field without changing 
0743:             * larger fields.
0744:             * <p>
0745:             * <em>Example</em>: Consider a <code>GregorianCalendar</code>
0746:             * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
0747:             * 8)</code> sets the calendar to April 30, <strong>1999</strong>. Using a
0748:             * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> field cannot
0749:             * be 31 in the month April. <code>DAY_OF_MONTH</code> is set to the closest possible
0750:             * value, 30. The <code>YEAR</code> field maintains the value of 1999 because it
0751:             * is a larger field than <code>MONTH</code>.
0752:             * <p>
0753:             * <em>Example</em>: Consider a <code>GregorianCalendar</code>
0754:             * originally set to Sunday June 6, 1999. Calling
0755:             * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
0756:             * Tuesday June 1, 1999, whereas calling
0757:             * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
0758:             * Sunday May 30, 1999. This is because the roll rule imposes an
0759:             * additional constraint: The <code>MONTH</code> must not change when the
0760:             * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1,
0761:             * the resultant date must be between Tuesday June 1 and Saturday June
0762:             * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant
0763:             * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the
0764:             * closest possible value to Sunday (where Sunday is the first day of the
0765:             * week).</p>
0766:             * @param field the time field.
0767:             * @param amount the signed amount to add to <code>field</code>.
0768:             * @since 1.2
0769:             * @see GregorianCalendar#add
0770:             * @see GregorianCalendar#set
0771:             */
0772:            public void roll(int field, int amount) {
0773:                if (amount == 0) {
0774:                    return; // Nothing to do
0775:                }
0776:
0777:                int min = 0, max = 0, gap;
0778:                if (field >= 0 && field < FIELD_COUNT) {
0779:                    complete();
0780:                    min = getMinimum(field);
0781:                    max = getMaximum(field);
0782:                }
0783:
0784:                switch (field) {
0785:                case ERA:
0786:                case YEAR:
0787:                case AM_PM:
0788:                case MINUTE:
0789:                case SECOND:
0790:                case MILLISECOND:
0791:                    // These fields are handled simply, since they have fixed minima
0792:                    // and maxima.  The field DAY_OF_MONTH is almost as simple.  Other
0793:                    // fields are complicated, since the range within they must roll
0794:                    // varies depending on the date.
0795:                    break;
0796:
0797:                case HOUR:
0798:                case HOUR_OF_DAY:
0799:                    // Rolling the hour is difficult on the ONSET and CEASE days of
0800:                    // daylight savings.  For example, if the change occurs at
0801:                    // 2 AM, we have the following progression:
0802:                    // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
0803:                    // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
0804:                    // To get around this problem we don't use fields; we manipulate
0805:                    // the time in millis directly.
0806:                {
0807:                    // Assume min == 0 in calculations below
0808:                    Date start = getTime();
0809:                    int oldHour = internalGet(field);
0810:                    int newHour = (oldHour + amount) % (max + 1);
0811:                    if (newHour < 0) {
0812:                        newHour += max + 1;
0813:                    }
0814:                    setTime(new Date(start.getTime() + ONE_HOUR
0815:                            * (newHour - oldHour)));
0816:                    return;
0817:                }
0818:                case MONTH:
0819:                    // Rolling the month involves both pinning the final value to [0, 11]
0820:                    // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
0821:                    // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
0822:                    // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
0823:                {
0824:                    int mon = (internalGet(MONTH) + amount) % 12;
0825:                    if (mon < 0) {
0826:                        mon += 12;
0827:                    }
0828:                    set(MONTH, mon);
0829:
0830:                    // Keep the day of month in range.  We don't want to spill over
0831:                    // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
0832:                    // mar3.
0833:                    // NOTE: We could optimize this later by checking for dom <= 28
0834:                    // first.  Do this if there appears to be a need. [LIU]
0835:                    int monthLen = monthLength(mon);
0836:                    int dom = internalGet(DAY_OF_MONTH);
0837:                    if (dom > monthLen) {
0838:                        set(DAY_OF_MONTH, monthLen);
0839:                    }
0840:                    return;
0841:                }
0842:
0843:                case WEEK_OF_YEAR: {
0844:                    // Unlike WEEK_OF_MONTH, WEEK_OF_YEAR never shifts the day of the
0845:                    // week.  Also, rolling the week of the year can have seemingly
0846:                    // strange effects simply because the year of the week of year
0847:                    // may be different from the calendar year.  For example, the
0848:                    // date Dec 28, 1997 is the first day of week 1 of 1998 (if
0849:                    // weeks start on Sunday and the minimal days in first week is
0850:                    // <= 3).
0851:                    int woy = internalGet(WEEK_OF_YEAR);
0852:                    // Get the ISO year, which matches the week of year.  This
0853:                    // may be one year before or after the calendar year.
0854:                    int isoYear = internalGet(YEAR);
0855:                    int isoDoy = internalGet(DAY_OF_YEAR);
0856:                    if (internalGet(MONTH) == Calendar.JANUARY) {
0857:                        if (woy >= 52) {
0858:                            --isoYear;
0859:                            isoDoy += yearLength(isoYear);
0860:                        }
0861:                    } else {
0862:                        if (woy == 1) {
0863:                            isoDoy -= yearLength(isoYear);
0864:                            ++isoYear;
0865:                        }
0866:                    }
0867:                    woy += amount;
0868:                    // Do fast checks to avoid unnecessary computation:
0869:                    if (woy < 1 || woy > 52) {
0870:                        // Determine the last week of the ISO year.
0871:                        // First, we calculate the relative fractional days of the
0872:                        // last week of the year. (This doesn't include days in 
0873:                        // the year before or after the calendar year.)
0874:                        int lastDoy = yearLength(isoYear);
0875:                        int normalizedDayOfWeek = internalGet(DAY_OF_WEEK)
0876:                                - getFirstDayOfWeek();
0877:                        if (normalizedDayOfWeek < 0) {
0878:                            normalizedDayOfWeek += 7;
0879:                        }
0880:                        int lastRelDow = (lastDoy - isoDoy + normalizedDayOfWeek) % 7;
0881:                        if (lastRelDow < 0) {
0882:                            lastRelDow += 7;
0883:                        }
0884:
0885:                        // Next, calculate the minimal last week of year.
0886:                        // Now this value is just the total number of weeks in the
0887:                        // year all of which have 7 days a week. Need to check the
0888:                        // first and the last week of the year, which would have 
0889:                        // days fewer than 7.
0890:                        int lastWoy;
0891:                        lastDoy -= (lastRelDow + 1);
0892:                        lastWoy = lastDoy / 7;
0893:
0894:                        // If the relative fraction of the first week of the year
0895:                        // is more than MinimalDaysInFirstWeek, add 1 to the last
0896:                        // week // of the year.
0897:                        if ((lastDoy - (lastWoy * 7)) >= getMinimalDaysInFirstWeek()) {
0898:                            lastWoy++;
0899:                        }
0900:
0901:                        // If the relative fraction of the last week of the year 
0902:                        // is more than MinimalDaysInFirstWeek, add 1 to the last
0903:                        // week of the year.
0904:                        if ((6 - lastRelDow) < getMinimalDaysInFirstWeek()) {
0905:                            lastWoy++;
0906:                        }
0907:
0908:                        woy = ((woy + lastWoy - 1) % lastWoy) + 1;
0909:                    }
0910:                    set(WEEK_OF_YEAR, woy);
0911:                    set(YEAR, isoYear);
0912:                    return;
0913:                }
0914:                case WEEK_OF_MONTH: {
0915:                    // During the roll we may have to shift
0916:                    // to a different day of the week.  For example:
0917:
0918:                    //    s  m  t  w  r  f  s
0919:                    //          1  2  3  4  5
0920:                    //    6  7  8  9 10 11 12
0921:
0922:                    // When rolling from the 6th or 7th back one week, we go to the
0923:                    // 1st (assuming that the first partial week counts).  The same
0924:                    // thing happens at the end of the month.
0925:
0926:                    // The other thing is that we have to figure out whether
0927:                    // the first partial week actually counts or not, based on the
0928:                    // minimal first days in the week.  And we have to use the
0929:                    // correct first day of the week to delineate the week
0930:                    // boundaries.
0931:
0932:                    // Here's our algorithm.  First, we find the real boundaries of
0933:                    // the month.  Then we discard the first partial week if it
0934:                    // doesn't count in this locale.  Then we fill in the ends with
0935:                    // phantom days, so that the first partial week and the last
0936:                    // partial week are full weeks.  We then have a nice square
0937:                    // block of weeks.  We do the usual rolling within this block,
0938:                    // as is done elsewhere in this method.  If we wind up on one of
0939:                    // the phantom days that we added, we recognize this and pin to
0940:                    // the first or the last day of the month.  Easy, eh?
0941:
0942:                    // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
0943:                    // in this locale.  We have dow in 0..6.
0944:                    int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
0945:                    if (dow < 0) {
0946:                        dow += 7;
0947:                    }
0948:
0949:                    // Find the day of the week (normalized for locale) for the first
0950:                    // of the month.
0951:                    int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7;
0952:                    if (fdm < 0) {
0953:                        fdm += 7;
0954:                    }
0955:
0956:                    // Get the first day of the first full week of the month,
0957:                    // including phantom days, if any.  Figure out if the first week
0958:                    // counts or not; if it counts, then fill in phantom days.  If
0959:                    // not, advance to the first real full week (skip the partial week).
0960:                    int start;
0961:                    if ((7 - fdm) < getMinimalDaysInFirstWeek()) {
0962:                        start = 8 - fdm; // Skip the first partial week
0963:                    } else {
0964:                        start = 1 - fdm; // This may be zero or negative
0965:                    }
0966:
0967:                    // Get the day of the week (normalized for locale) for the last
0968:                    // day of the month.
0969:                    int monthLen = monthLength(internalGet(MONTH));
0970:                    int ldm = (monthLen - internalGet(DAY_OF_MONTH) + dow) % 7;
0971:                    // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.
0972:
0973:                    // Get the limit day for the blocked-off rectangular month; that
0974:                    // is, the day which is one past the last day of the month,
0975:                    // after the month has already been filled in with phantom days
0976:                    // to fill out the last week.  This day has a normalized DOW of 0.
0977:                    int limit = monthLen + 7 - ldm;
0978:
0979:                    // Now roll between start and (limit - 1).
0980:                    gap = limit - start;
0981:                    int day_of_month = (internalGet(DAY_OF_MONTH) + amount * 7 - start)
0982:                            % gap;
0983:                    if (day_of_month < 0) {
0984:                        day_of_month += gap;
0985:                    }
0986:                    day_of_month += start;
0987:
0988:                    // Finally, pin to the real start and end of the month.
0989:                    if (day_of_month < 1) {
0990:                        day_of_month = 1;
0991:                    }
0992:                    if (day_of_month > monthLen) {
0993:                        day_of_month = monthLen;
0994:                    }
0995:
0996:                    // Set the DAY_OF_MONTH.  We rely on the fact that this field
0997:                    // takes precedence over everything else (since all other fields
0998:                    // are also set at this point).  If this fact changes (if the
0999:                    // disambiguation algorithm changes) then we will have to unset
1000:                    // the appropriate fields here so that DAY_OF_MONTH is attended
1001:                    // to.
1002:                    set(DAY_OF_MONTH, day_of_month);
1003:                    return;
1004:                }
1005:
1006:                case DAY_OF_MONTH:
1007:                    max = monthLength(internalGet(MONTH));
1008:                    break;
1009:
1010:                case DAY_OF_YEAR: {
1011:                    // Roll the day of year using millis.  Compute the millis for
1012:                    // the start of the year, and get the length of the year.
1013:                    long delta = amount * ONE_DAY; // Scale up from days to millis
1014:                    long min2 = time - (internalGet(DAY_OF_YEAR) - 1) * ONE_DAY;
1015:                    int yearLength = yearLength();
1016:                    time = (time + delta - min2) % (yearLength * ONE_DAY);
1017:                    if (time < 0) {
1018:                        time += yearLength * ONE_DAY;
1019:                    }
1020:                    long dst = internalGet(DST_OFFSET);
1021:                    setTimeInMillis(time + min2);
1022:                    dst -= internalGet(DST_OFFSET);
1023:                    if (dst != 0) {
1024:                        setTimeInMillis(time + dst);
1025:                    }
1026:                    return;
1027:                }
1028:
1029:                case DAY_OF_WEEK: {
1030:                    // Roll the day of week using millis.  Compute the millis for
1031:                    // the start of the week, using the first day of week setting.
1032:                    // Restrict the millis to [start, start+7days).
1033:                    long delta = amount * ONE_DAY; // Scale up from days to millis
1034:                    // Compute the number of days before the current day in this
1035:                    // week.  This will be a value 0..6.
1036:                    int leadDays = internalGet(DAY_OF_WEEK)
1037:                            - getFirstDayOfWeek();
1038:                    if (leadDays < 0) {
1039:                        leadDays += 7;
1040:                    }
1041:                    long min2 = time - leadDays * ONE_DAY;
1042:                    time = (time + delta - min2) % ONE_WEEK;
1043:                    if (time < 0) {
1044:                        time += ONE_WEEK;
1045:                    }
1046:                    long dst = internalGet(DST_OFFSET);
1047:                    setTimeInMillis(time + min2);
1048:                    dst -= internalGet(DST_OFFSET);
1049:                    if (dst != 0) {
1050:                        setTimeInMillis(time + dst);
1051:                    }
1052:                    return;
1053:                }
1054:
1055:                case DAY_OF_WEEK_IN_MONTH: {
1056:                    // Roll the day of week in the month using millis.  Determine
1057:                    // the first day of the week in the month, and then the last,
1058:                    // and then roll within that range.
1059:                    long delta = amount * ONE_WEEK; // Scale up from weeks to millis
1060:                    // Find the number of same days of the week before this one
1061:                    // in this month.
1062:                    int preWeeks = (internalGet(DAY_OF_MONTH) - 1) / 7;
1063:                    // Find the number of same days of the week after this one
1064:                    // in this month.
1065:                    int postWeeks = (monthLength(internalGet(MONTH)) - internalGet(DAY_OF_MONTH)) / 7;
1066:                    // From these compute the min and gap millis for rolling.
1067:                    long min2 = time - preWeeks * ONE_WEEK;
1068:                    long gap2 = ONE_WEEK * (preWeeks + postWeeks + 1); // Must add 1!
1069:                    // Roll within this range
1070:                    time = (time + delta - min2) % gap2;
1071:                    if (time < 0) {
1072:                        time += gap2;
1073:                    }
1074:                    long dst = internalGet(DST_OFFSET);
1075:                    setTimeInMillis(time + min2);
1076:                    dst -= internalGet(DST_OFFSET);
1077:                    if (dst != 0) {
1078:                        setTimeInMillis(time + dst);
1079:                    }
1080:                    return;
1081:                }
1082:
1083:                case ZONE_OFFSET:
1084:                case DST_OFFSET:
1085:                default:
1086:                    // These fields cannot be rolled
1087:                    throw new IllegalArgumentException();
1088:                }
1089:
1090:                // These are the standard roll instructions.  These work for all
1091:                // simple cases, that is, cases in which the limits are fixed, such
1092:                // as the hour, the month, and the era.
1093:                gap = max - min + 1;
1094:                int value = internalGet(field) + amount;
1095:                value = (value - min) % gap;
1096:                if (value < 0) {
1097:                    value += gap;
1098:                }
1099:                value += min;
1100:
1101:                set(field, value);
1102:            }
1103:
1104:            /**
1105:             * Returns minimum value for the given field.
1106:             * e.g. for Gregorian DAY_OF_MONTH, 1
1107:             * Please see Calendar.getMinimum for descriptions on parameters and
1108:             * the return value.
1109:             */
1110:            public int getMinimum(int field) {
1111:                return MIN_VALUES[field];
1112:            }
1113:
1114:            /**
1115:             * Returns maximum value for the given field.
1116:             * e.g. for Gregorian DAY_OF_MONTH, 31
1117:             * Please see Calendar.getMaximum for descriptions on parameters and
1118:             * the return value.
1119:             */
1120:            public int getMaximum(int field) {
1121:                return MAX_VALUES[field];
1122:            }
1123:
1124:            /**
1125:             * Returns highest minimum value for the given field if varies.
1126:             * Otherwise same as getMinimum(). For Gregorian, no difference.
1127:             * Please see Calendar.getGreatestMinimum for descriptions on parameters
1128:             * and the return value.
1129:             */
1130:            public int getGreatestMinimum(int field) {
1131:                return MIN_VALUES[field];
1132:            }
1133:
1134:            /**
1135:             * Returns lowest maximum value for the given field if varies.
1136:             * Otherwise same as getMaximum(). For Gregorian DAY_OF_MONTH, 28
1137:             * Please see Calendar.getLeastMaximum for descriptions on parameters and
1138:             * the return value.
1139:             */
1140:            public int getLeastMaximum(int field) {
1141:                return LEAST_MAX_VALUES[field];
1142:            }
1143:
1144:            /**
1145:             * Return the minimum value that this field could have, given the current date.
1146:             * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
1147:             * @since 1.2
1148:             */
1149:            public int getActualMinimum(int field) {
1150:                return getMinimum(field);
1151:            }
1152:
1153:            /**
1154:             * Return the maximum value that this field could have, given the current date.
1155:             * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
1156:             * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
1157:             * for some years the actual maximum for MONTH is 12, and for others 13.
1158:             * @since 1.2
1159:             */
1160:            public int getActualMaximum(int field) {
1161:                /* It is a known limitation that the code here (and in getActualMinimum)
1162:                 * won't behave properly at the extreme limits of GregorianCalendar's
1163:                 * representable range (except for the code that handles the YEAR
1164:                 * field).  That's because the ends of the representable range are at
1165:                 * odd spots in the year.  For calendars with the default Gregorian
1166:                 * cutover, these limits are Sun Dec 02 16:47:04 GMT 292269055 BC to Sun
1167:                 * Aug 17 07:12:55 GMT 292278994 AD, somewhat different for non-GMT
1168:                 * zones.  As a result, if the calendar is set to Aug 1 292278994 AD,
1169:                 * the actual maximum of DAY_OF_MONTH is 17, not 30.  If the date is Mar
1170:                 * 31 in that year, the actual maximum month might be Jul, whereas is
1171:                 * the date is Mar 15, the actual maximum might be Aug -- depending on
1172:                 * the precise semantics that are desired.  Similar considerations
1173:                 * affect all fields.  Nonetheless, this effect is sufficiently arcane
1174:                 * that we permit it, rather than complicating the code to handle such
1175:                 * intricacies. - liu 8/20/98 */
1176:
1177:                switch (field) {
1178:                // we have functions that enable us to fast-path number of days in month
1179:                // of year
1180:                case DAY_OF_MONTH:
1181:                    return monthLength(get(MONTH));
1182:
1183:                case DAY_OF_YEAR:
1184:                    return yearLength();
1185:
1186:                    // for week of year, week of month, or day of week in month, we
1187:                    // just fall back on the default implementation in Calendar 
1188:                    // we could do better by having special calculations here)
1189:                case WEEK_OF_YEAR:
1190:                case WEEK_OF_MONTH:
1191:                case DAY_OF_WEEK_IN_MONTH:
1192:                    return super .getActualMaximum(field);
1193:
1194:                case YEAR:
1195:                    /* The year computation is no different, in principle, from the
1196:                     * others, however, the range of possible maxima is large.  In
1197:                     * addition, the way we know we've exceeded the range is different.
1198:                     * For these reasons, we use the special case code below to handle
1199:                     * this field.
1200:                     *
1201:                     * The actual maxima for YEAR depend on the type of calendar:
1202:                     *
1203:                     *     Gregorian = May 17, 292275056 BC - Aug 17, 292278994 AD
1204:                     *     Julian    = Dec  2, 292269055 BC - Jan  3, 292272993 AD
1205:                     *     Hybrid    = Dec  2, 292269055 BC - Aug 17, 292278994 AD
1206:                     *
1207:                     * We know we've exceeded the maximum when either the month, date,
1208:                     * time, or era changes in response to setting the year.  We don't
1209:                     * check for month, date, and time here because the year and era are
1210:                     * sufficient to detect an invalid year setting.  NOTE: If code is
1211:                     * added to check the month and date in the future for some reason,
1212:                     * Feb 29 must be allowed to shift to Mar 1 when setting the year.
1213:                     */
1214:                {
1215:                    Calendar cal = (Calendar) this .clone();
1216:                    cal.setLenient(true);
1217:
1218:                    int era = cal.get(ERA);
1219:                    Date d = cal.getTime();
1220:
1221:                    /* Perform a binary search, with the invariant that lowGood is a
1222:                     * valid year, and highBad is an out of range year.
1223:                     */
1224:                    int lowGood = LEAST_MAX_VALUES[YEAR];
1225:                    int highBad = MAX_VALUES[YEAR] + 1;
1226:                    while ((lowGood + 1) < highBad) {
1227:                        int y = (lowGood + highBad) / 2;
1228:                        cal.set(YEAR, y);
1229:                        if (cal.get(YEAR) == y && cal.get(ERA) == era) {
1230:                            lowGood = y;
1231:                        } else {
1232:                            highBad = y;
1233:                            cal.setTime(d); // Restore original fields
1234:                        }
1235:                    }
1236:
1237:                    return lowGood;
1238:                }
1239:
1240:                    // and we know none of the other fields have variable maxima in
1241:                    // GregorianCalendar, so we can just return the fixed maximum
1242:                default:
1243:                    return getMaximum(field);
1244:                }
1245:            }
1246:
1247:            //////////////////////
1248:            // Proposed public API
1249:            //////////////////////
1250:
1251:            /**
1252:             * Return true if the current time for this Calendar is in Daylignt
1253:             * Savings Time.
1254:             *
1255:             * Note -- MAKE THIS PUBLIC AT THE NEXT API CHANGE.  POSSIBLY DEPRECATE
1256:             * AND REMOVE TimeZone.inDaylightTime().
1257:             */
1258:            boolean inDaylightTime() {
1259:                if (!getTimeZone().useDaylightTime()) {
1260:                    return false;
1261:                }
1262:                complete(); // Force update of DST_OFFSET field
1263:                return internalGet(DST_OFFSET) != 0;
1264:            }
1265:
1266:            /**
1267:             * Return the year that corresponds to the <code>WEEK_OF_YEAR</code> field.
1268:             * This may be one year before or after the calendar year stored
1269:             * in the <code>YEAR</code> field.  For example, January 1, 1999 is considered
1270:             * Friday of week 53 of 1998 (if minimal days in first week is
1271:             * 2 or less, and the first day of the week is Sunday).  Given
1272:             * these same settings, the ISO year of January 1, 1999 is
1273:             * 1998.
1274:             * <p>
1275:             * Warning: This method will complete all fields.
1276:             * @return the year corresponding to the <code>WEEK_OF_YEAR</code> field, which
1277:             * may be one year before or after the <code>YEAR</code> field.
1278:             * @see #WEEK_OF_YEAR
1279:             */
1280:            int getISOYear() {
1281:                complete();
1282:                int woy = internalGet(WEEK_OF_YEAR);
1283:                // Get the ISO year, which matches the week of year.  This
1284:                // may be one year before or after the calendar year.
1285:                int isoYear = internalGet(YEAR);
1286:                if (internalGet(MONTH) == Calendar.JANUARY) {
1287:                    if (woy >= 52) {
1288:                        --isoYear;
1289:                    }
1290:                } else {
1291:                    if (woy == 1) {
1292:                        ++isoYear;
1293:                    }
1294:                }
1295:                return isoYear;
1296:            }
1297:
1298:            /////////////////////////////
1299:            // Time => Fields computation
1300:            /////////////////////////////
1301:
1302:            /**
1303:             * Converts UTC as milliseconds to time field values.
1304:             * The time is <em>not</em>
1305:             * recomputed first; to recompute the time, then the fields, call the
1306:             * <code>complete</code> method.
1307:             * @see Calendar#complete
1308:             */
1309:            protected void computeFields() {
1310:                computeFieldsImpl();
1311:
1312:                // Careful here: We are manually setting the time stamps[]
1313:                // flags to INTERNALLY_SET, so we must be sure that the
1314:                // computeFieldsImpl method actually does set all the fields.
1315:                for (int i = 0; i < FIELD_COUNT; ++i) {
1316:                    stamp[i] = INTERNALLY_SET;
1317:                    isSet[i] = true;
1318:                }
1319:            }
1320:
1321:            /**
1322:             * This computeFieldsImpl implements the conversion from UTC (a
1323:             * millisecond offset from 1970-01-01T00:00:00.000Z) to calendar
1324:             * field values.
1325:             */
1326:            private void computeFieldsImpl() {
1327:                TimeZone tz = getTimeZone();
1328:                int[] offsets = new int[2];
1329:                int offset;
1330:                if (tz instanceof  ZoneInfo) {
1331:                    offset = ((ZoneInfo) tz).getOffsets(time, offsets);
1332:                } else {
1333:                    offset = tz.getOffsets(time, offsets);
1334:                }
1335:                long localMillis = time + offset; // here localMillis is wall
1336:
1337:                /* Check for very extreme values -- millis near Long.MIN_VALUE or
1338:                 * Long.MAX_VALUE.  For these values, adding the zone offset can push
1339:                 * the millis past MAX_VALUE to MIN_VALUE, or vice versa.  This produces
1340:                 * the undesirable effect that the time can wrap around at the ends,
1341:                 * yielding, for example, a Date(Long.MAX_VALUE) with a big BC year
1342:                 * (should be AD).  Handle this by pinning such values to Long.MIN_VALUE
1343:                 * or Long.MAX_VALUE. - liu 8/11/98 bug 4149677 */
1344:                if (time > 0 && localMillis < 0 && offset > 0) {
1345:                    localMillis = Long.MAX_VALUE;
1346:                } else if (time < 0 && localMillis > 0 && offset < 0) {
1347:                    localMillis = Long.MIN_VALUE;
1348:                }
1349:
1350:                // Time to fields takes the wall millis (Standard or DST).
1351:                timeToFields(localMillis, false);
1352:
1353:                long days = floorDivide(localMillis, ONE_DAY);
1354:                int millisInDay = (int) (localMillis - (days * ONE_DAY));
1355:                if (millisInDay < 0) {
1356:                    millisInDay += ONE_DAY;
1357:                }
1358:
1359:                // Fill in all time-related fields based on millisInDay.  Call internalSet()
1360:                // so as not to perturb flags.
1361:                internalSet(MILLISECOND, millisInDay % 1000);
1362:                millisInDay /= 1000;
1363:                internalSet(SECOND, millisInDay % 60);
1364:                millisInDay /= 60;
1365:                internalSet(MINUTE, millisInDay % 60);
1366:                millisInDay /= 60;
1367:                internalSet(HOUR_OF_DAY, millisInDay);
1368:                internalSet(AM_PM, millisInDay / 12); // Assume AM == 0
1369:                internalSet(HOUR, millisInDay % 12);
1370:
1371:                internalSet(ZONE_OFFSET, offsets[0]);
1372:                internalSet(DST_OFFSET, offsets[1]);
1373:            }
1374:
1375:            /**
1376:             * Convert the time as milliseconds to the date fields.  Millis must be
1377:             * given as local wall millis to get the correct local day.  For example,
1378:             * if it is 11:30 pm Standard, and DST is in effect, the correct DST millis
1379:             * must be passed in to get the right date.
1380:             * <p>
1381:             * Fields that are completed by this method: ERA, YEAR, MONTH, DATE,
1382:             * DAY_OF_WEEK, DAY_OF_YEAR, WEEK_OF_YEAR, WEEK_OF_MONTH,
1383:             * DAY_OF_WEEK_IN_MONTH.
1384:             * @param theTime the wall-clock time in milliseconds (either Standard or DST),
1385:             * whichever is in effect
1386:             * @param quick if true, only compute the ERA, YEAR, MONTH, DATE,
1387:             * DAY_OF_WEEK, and DAY_OF_YEAR.
1388:             */
1389:            private final void timeToFields(long theTime, boolean quick) {
1390:                int rawYear, year, month, date, dayOfWeek, dayOfYear, weekCount, era;
1391:                boolean isLeap;
1392:
1393:                // Compute the year, month, and day of month from the given millis
1394:                if (theTime >= normalizedGregorianCutover) {
1395:                    // The Gregorian epoch day is zero for Monday January 1, year 1.
1396:                    long gregorianEpochDay = millisToJulianDay(theTime)
1397:                            - JAN_1_1_JULIAN_DAY;
1398:                    // Here we convert from the day number to the multiple radix
1399:                    // representation.  We use 400-year, 100-year, and 4-year cycles.
1400:                    // For example, the 4-year cycle has 4 years + 1 leap day; giving
1401:                    // 1461 == 365*4 + 1 days.
1402:                    int n400, n100, n4, n1;
1403:                    if (gregorianEpochDay > 0) {
1404:                        n400 = (int) (gregorianEpochDay / 146097);
1405:                        dayOfYear = (int) (gregorianEpochDay % 146097);
1406:                        n100 = dayOfYear / 36524;
1407:                        dayOfYear %= 36524;
1408:                        n4 = dayOfYear / 1461;
1409:                        dayOfYear %= 1461;
1410:                        n1 = dayOfYear / 365;
1411:                        dayOfYear %= 365; // zero-based day of year
1412:                    } else {
1413:                        int[] rem = new int[1];
1414:                        n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length
1415:                        n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length
1416:                        n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length
1417:                        n1 = floorDivide(rem[0], 365, rem);
1418:                        dayOfYear = rem[0]; // zero-based day of year
1419:                    }
1420:                    rawYear = 400 * n400 + 100 * n100 + 4 * n4 + n1;
1421:                    if (n100 == 4 || n1 == 4) {
1422:                        dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
1423:                    } else {
1424:                        ++rawYear;
1425:                    }
1426:
1427:                    isLeap = ((rawYear & 0x3) == 0) && // equiv. to (rawYear%4 == 0)
1428:                            (rawYear % 100 != 0 || rawYear % 400 == 0);
1429:
1430:                    // Gregorian day zero is a Monday
1431:                    dayOfWeek = (int) ((gregorianEpochDay + 1) % 7);
1432:                } else {
1433:                    // The Julian epoch day (not the same as Julian Day)
1434:                    // is zero on Saturday December 30, 0 (Gregorian).
1435:                    long julianEpochDay = millisToJulianDay(theTime)
1436:                            - (JAN_1_1_JULIAN_DAY - 2);
1437:                    rawYear = (int) floorDivide(4 * julianEpochDay + 1464, 1461);
1438:
1439:                    // Compute the Julian calendar day number for January 1, rawYear
1440:                    long january1 = 365 * (rawYear - 1)
1441:                            + floorDivide(rawYear - 1, 4);
1442:                    dayOfYear = (int) (julianEpochDay - january1); // 0-based
1443:
1444:                    // Julian leap years occurred historically every 4 years starting
1445:                    // with 8 AD.  Before 8 AD the spacing is irregular; every 3 years
1446:                    // from 45 BC to 9 BC, and then none until 8 AD.  However, we don't
1447:                    // implement this historical detail; instead, we implement the
1448:                    // computationally cleaner proleptic calendar, which assumes
1449:                    // consistent 4-year cycles throughout time.
1450:                    isLeap = ((rawYear & 0x3) == 0); // equiv. to (rawYear%4 == 0)
1451:
1452:                    // Julian calendar day zero is a Saturday
1453:                    dayOfWeek = (int) ((julianEpochDay - 1) % 7);
1454:                }
1455:
1456:                // Common Julian/Gregorian calculation
1457:                int correction = 0;
1458:                int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
1459:                if (dayOfYear >= march1) {
1460:                    correction = isLeap ? 1 : 2;
1461:                }
1462:                month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
1463:                date = dayOfYear
1464:                        - (isLeap ? LEAP_NUM_DAYS[month] : NUM_DAYS[month]) + 1; // one-based DOM
1465:
1466:                // Normalize day of week
1467:                dayOfWeek += (dayOfWeek < 0) ? (SUNDAY + 7) : SUNDAY;
1468:
1469:                era = AD;
1470:                year = rawYear;
1471:                if (year < 1) {
1472:                    era = BC;
1473:                    year = 1 - year;
1474:                }
1475:
1476:                internalSet(ERA, era);
1477:                internalSet(YEAR, year);
1478:                internalSet(MONTH, month + JANUARY); // 0-based
1479:                internalSet(DATE, date);
1480:                internalSet(DAY_OF_WEEK, dayOfWeek);
1481:                internalSet(DAY_OF_YEAR, ++dayOfYear); // Convert from 0-based to 1-based
1482:                if (quick) {
1483:                    return;
1484:                }
1485:
1486:                // WEEK_OF_YEAR start
1487:                // Compute the week of the year.  Valid week numbers run from 1 to 52
1488:                // or 53, depending on the year, the first day of the week, and the
1489:                // minimal days in the first week.  Days at the start of the year may
1490:                // fall into the last week of the previous year; days at the end of
1491:                // the year may fall into the first week of the next year.
1492:                int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
1493:                int relDowJan1 = (dayOfWeek - dayOfYear + 701 - getFirstDayOfWeek()) % 7; // 0..6
1494:                int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
1495:                if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
1496:                    ++woy;
1497:                }
1498:
1499:                // The calculation of dayOfYear does not take into account 
1500:                // Gregorian cut over date. The next if statement depends on that 
1501:                // assumption.
1502:                if (dayOfYear > 359) { // Fast check which eliminates most cases
1503:                    // Check to see if we are in the last week; if so, we need
1504:                    // to handle the case in which we are the first week of the
1505:                    // next year.
1506:                    int lastDoy = yearLength();
1507:                    int lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
1508:                    if (lastRelDow < 0) {
1509:                        lastRelDow += 7;
1510:                    }
1511:                    if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek())
1512:                            && ((dayOfYear + 7 - relDow) > lastDoy)) {
1513:                        woy = 1;
1514:                    }
1515:                } else if (woy == 0) {
1516:                    // We are the last week of the previous year.
1517:                    int prevDoy = dayOfYear + yearLength(rawYear - 1);
1518:                    woy = weekNumber(prevDoy, dayOfWeek);
1519:                }
1520:                internalSet(WEEK_OF_YEAR, woy);
1521:                // WEEK_OF_YEAR end
1522:
1523:                internalSet(WEEK_OF_MONTH, weekNumber(date, dayOfWeek));
1524:                internalSet(DAY_OF_WEEK_IN_MONTH, (date - 1) / 7 + 1);
1525:            }
1526:
1527:            /////////////////////////////
1528:            // Fields => Time computation
1529:            /////////////////////////////
1530:
1531:            /**
1532:             * Overrides Calendar
1533:             * Converts time field values to UTC as milliseconds.
1534:             * @exception IllegalArgumentException if any fields are invalid.
1535:             */
1536:            protected void computeTime() {
1537:                if (!isLenient() && !validateFields()) {
1538:                    throw new IllegalArgumentException();
1539:                }
1540:
1541:                // This function takes advantage of the fact that unset fields in
1542:                // the time field list have a value of zero.
1543:
1544:                // The year defaults to the epoch start.
1545:                int year = (stamp[YEAR] != UNSET) ? internalGet(YEAR)
1546:                        : EPOCH_YEAR;
1547:
1548:                // The YEAR field must always be used regardless of its SET
1549:                // state because YEAR is a mandatory field to determine the date
1550:                // and the default value (EPOCH_YEAR) may change through the
1551:                // normalization process.
1552:                int fieldMask = 1 << YEAR;
1553:
1554:                int era = AD;
1555:                if (stamp[ERA] != UNSET) {
1556:                    era = internalGet(ERA);
1557:                    fieldMask |= 1 << ERA;
1558:                    if (era == BC) {
1559:                        year = 1 - year;
1560:                    } else if (era != AD) {
1561:                        // Even in lenient mode we disallow ERA values other than AD & BC
1562:                        throw new IllegalArgumentException("Invalid era");
1563:                    }
1564:                }
1565:
1566:                int[] fieldMaskParam = { fieldMask };
1567:
1568:                // First, use the year to determine whether to use the Gregorian or the
1569:                // Julian calendar. If the year is not the year of the cutover, this
1570:                // computation will be correct. But if the year is the cutover year,
1571:                // this may be incorrect. In that case, assume the Gregorian calendar,
1572:                // make the computation, and then recompute if the resultant millis
1573:                // indicate the wrong calendar has been assumed.
1574:
1575:                // A date such as Oct. 10, 1582 does not exist in a Gregorian calendar
1576:                // with the default changeover of Oct. 15, 1582, since in such a
1577:                // calendar Oct. 4 (Julian) is followed by Oct. 15 (Gregorian).  This
1578:                // algorithm will interpret such a date using the Julian calendar,
1579:                // yielding Oct. 20, 1582 (Gregorian).
1580:                boolean isGregorian = year >= gregorianCutoverYear;
1581:                long julianDay = computeJulianDay(isGregorian, year,
1582:                        fieldMaskParam);
1583:                long millis = julianDayToMillis(julianDay);
1584:
1585:                // The following check handles portions of the cutover year BEFORE the
1586:                // cutover itself happens. The check for the julianDate number is for a
1587:                // rare case; it's a hard-coded number, but it's efficient.  The given
1588:                // Julian day number corresponds to Dec 3, 292269055 BC, which
1589:                // corresponds to millis near Long.MIN_VALUE.  The need for the check
1590:                // arises because for extremely negative Julian day numbers, the millis
1591:                // actually overflow to be positive values. Without the check, the
1592:                // initial date is interpreted with the Gregorian calendar, even when
1593:                // the cutover doesn't warrant it.
1594:                if (isGregorian != (millis >= normalizedGregorianCutover)
1595:                        && julianDay != -106749550580L) { // See above
1596:                    fieldMaskParam[0] = fieldMask;
1597:                    julianDay = computeJulianDay(!isGregorian, year,
1598:                            fieldMaskParam);
1599:                    millis = julianDayToMillis(julianDay);
1600:                }
1601:
1602:                fieldMask = fieldMaskParam[0];
1603:
1604:                // Do the time portion of the conversion.
1605:
1606:                int millisInDay = 0;
1607:
1608:                // Find the best set of fields specifying the time of day.  There
1609:                // are only two possibilities here; the HOUR_OF_DAY or the
1610:                // AM_PM and the HOUR.
1611:                int hourOfDayStamp = stamp[HOUR_OF_DAY];
1612:                int hourStamp = stamp[HOUR];
1613:                int bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp
1614:                        : hourOfDayStamp;
1615:
1616:                // Hours
1617:                if (bestStamp != UNSET) {
1618:                    if (bestStamp == hourOfDayStamp) {
1619:                        // Don't normalize here; let overflow bump into the next period.
1620:                        // This is consistent with how we handle other fields.
1621:                        millisInDay += internalGet(HOUR_OF_DAY);
1622:                        fieldMask |= 1 << HOUR_OF_DAY;
1623:                    } else {
1624:                        // Don't normalize here; let overflow bump into the next period.
1625:                        // This is consistent with how we handle other fields.
1626:                        millisInDay += internalGet(HOUR);
1627:                        fieldMask |= 1 << HOUR;
1628:
1629:                        // The default value of AM_PM is 0 which designates AM.
1630:                        if (stamp[AM_PM] != UNSET) {
1631:                            millisInDay += 12 * internalGet(AM_PM);
1632:                            fieldMask |= 1 << AM_PM;
1633:                        }
1634:                    }
1635:                }
1636:
1637:                millisInDay *= 60;
1638:                if (stamp[MINUTE] != UNSET) {
1639:                    millisInDay += internalGet(MINUTE); // now have minutes
1640:                    fieldMask |= 1 << MINUTE;
1641:                }
1642:                millisInDay *= 60;
1643:                if (stamp[SECOND] != UNSET) {
1644:                    millisInDay += internalGet(SECOND); // now have seconds
1645:                    fieldMask |= 1 << SECOND;
1646:                }
1647:                millisInDay *= 1000;
1648:                if (stamp[MILLISECOND] != UNSET) {
1649:                    millisInDay += internalGet(MILLISECOND); // now have millis
1650:                    fieldMask |= 1 << MILLISECOND;
1651:                }
1652:
1653:                // Now add date and millisInDay together, to make millis contain local wall
1654:                // millis, with no zone or DST adjustments
1655:                millis += millisInDay;
1656:
1657:                // Compute the time zone offset and DST offset.  There are two potential
1658:                // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
1659:                // for discussion purposes here.
1660:                // 1. The transition into DST.  Here, a designated time of 2:00 am - 2:59 am
1661:                //    can be in standard or in DST depending.  However, 2:00 am is an invalid
1662:                //    representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
1663:                //    We assume standard time.
1664:                // 2. The transition out of DST.  Here, a designated time of 1:00 am - 1:59 am
1665:                //    can be in standard or DST.  Both are valid representations (the rep
1666:                //    jumps from 1:59:59 DST to 1:00:00 Std).
1667:                //    Again, we assume standard time.
1668:                // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
1669:                // or DST_OFFSET fields; then we use those fields.
1670:                TimeZone zone = getTimeZone();
1671:                if (zone instanceof  ZoneInfo) {
1672:                    int[] offsets = new int[2];
1673:                    ((ZoneInfo) zone).getOffsetsByWall(millis, offsets);
1674:                    int zoneOffset = 0;
1675:                    if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) {
1676:                        zoneOffset = internalGet(ZONE_OFFSET);
1677:                        fieldMask |= 1 << ZONE_OFFSET;
1678:                    } else {
1679:                        zoneOffset = offsets[0];
1680:                    }
1681:                    if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
1682:                        zoneOffset += internalGet(DST_OFFSET);
1683:                        fieldMask |= 1 << DST_OFFSET;
1684:                    } else {
1685:                        zoneOffset += offsets[1];
1686:                    }
1687:                    time = millis - zoneOffset;
1688:                } else {
1689:                    int zoneOffset = 0;
1690:                    if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) {
1691:                        zoneOffset = internalGet(ZONE_OFFSET);
1692:                        fieldMask |= 1 << ZONE_OFFSET;
1693:                    } else {
1694:                        zoneOffset = zone.getRawOffset();
1695:                    }
1696:                    if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
1697:                        time = millis - (zoneOffset + internalGet(DST_OFFSET));
1698:                        fieldMask |= 1 << DST_OFFSET;
1699:                    } else {
1700:                        time = millis
1701:                                - zone.getOffsets(millis - (long) zoneOffset,
1702:                                        null);
1703:                    }
1704:                }
1705:
1706:                // In lenient mode, we need to normalize the fields that have
1707:                // any SET state (i.e., not UNSET) from the time value. First,
1708:                // we calculate all field values and then discard values of
1709:                // the UNSET fields. (4685354)
1710:                if (isLenient()) {
1711:                    computeFieldsImpl();
1712:                }
1713:
1714:                for (int i = 0; i < fields.length; i++) {
1715:                    if (isSet(i)) {
1716:                        int bitMask = 1 << i;
1717:                        if ((fieldMask & bitMask) != bitMask) {
1718:                            internalClear(i);
1719:                        } else {
1720:                            stamp[i] = INTERNALLY_SET;
1721:                            isSet[i] = true;
1722:                        }
1723:                    }
1724:                }
1725:            }
1726:
1727:            /**
1728:             * Compute the Julian day number under either the Gregorian or the
1729:             * Julian calendar, using the given year and the remaining fields.
1730:             * @param isGregorian if true, use the Gregorian calendar
1731:             * @param year the adjusted year number, with 0 indicating the
1732:             * year 1 BC, -1 indicating 2 BC, etc.
1733:             * @param fieldMaskParam fieldMaskParam[0] is a bit mask to
1734:             * specify which fields have been used to determine the date. The
1735:             * value is updated upon return.
1736:             * @return the Julian day number
1737:             */
1738:            private final long computeJulianDay(boolean isGregorian, int year,
1739:                    int[] fieldMaskParam) {
1740:                int month = 0, date = 0, y;
1741:                long millis = 0;
1742:
1743:                // bit masks to remember which fields have been used to
1744:                // determine the date
1745:                int fieldMask = fieldMaskParam[0];
1746:
1747:                // Find the most recent group of fields specifying the day within
1748:                // the year.  These may be any of the following combinations:
1749:                //   MONTH + DAY_OF_MONTH
1750:                //   MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
1751:                //   MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
1752:                //   DAY_OF_YEAR
1753:                //   WEEK_OF_YEAR + DAY_OF_WEEK
1754:                // We look for the most recent of the fields in each group to determine
1755:                // the age of the group.  For groups involving a week-related field such
1756:                // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the
1757:                // week-related field and the DAY_OF_WEEK must be set for the group as a
1758:                // whole to be considered.  (See bug 4153860 - liu 7/24/98.)
1759:                int dowStamp = stamp[DAY_OF_WEEK];
1760:                int monthStamp = stamp[MONTH];
1761:                int domStamp = stamp[DAY_OF_MONTH];
1762:                int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp);
1763:                int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH],
1764:                        dowStamp);
1765:                int doyStamp = stamp[DAY_OF_YEAR];
1766:                int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp);
1767:
1768:                int bestStamp = domStamp;
1769:                if (womStamp > bestStamp) {
1770:                    bestStamp = womStamp;
1771:                }
1772:                if (dowimStamp > bestStamp) {
1773:                    bestStamp = dowimStamp;
1774:                }
1775:                if (doyStamp > bestStamp) {
1776:                    bestStamp = doyStamp;
1777:                }
1778:                if (woyStamp > bestStamp) {
1779:                    bestStamp = woyStamp;
1780:                }
1781:
1782:                /* No complete combination exists.  Look for WEEK_OF_MONTH,
1783:                 * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone.  Treat DAY_OF_WEEK alone
1784:                 * as DAY_OF_WEEK_IN_MONTH.
1785:                 */
1786:                if (bestStamp == UNSET) {
1787:                    womStamp = stamp[WEEK_OF_MONTH];
1788:                    dowimStamp = Math
1789:                            .max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
1790:                    woyStamp = stamp[WEEK_OF_YEAR];
1791:                    bestStamp = Math.max(Math.max(womStamp, dowimStamp),
1792:                            woyStamp);
1793:
1794:                    /* Treat MONTH alone or no fields at all as DAY_OF_MONTH.  This may
1795:                     * result in bestStamp = domStamp = UNSET if no fields are set,
1796:                     * which indicates DAY_OF_MONTH.
1797:                     */
1798:                    if (bestStamp == UNSET) {
1799:                        bestStamp = domStamp = monthStamp;
1800:                    }
1801:                }
1802:
1803:                boolean useMonth = false;
1804:
1805:                if (bestStamp == domStamp
1806:                        || (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR])
1807:                        || (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) {
1808:                    useMonth = true;
1809:
1810:                    // We have the month specified. Make it 0-based for the algorithm.
1811:                    month = (monthStamp != UNSET) ? internalGet(MONTH)
1812:                            - JANUARY : 0;
1813:
1814:                    // If the month is out of range, adjust it into range
1815:                    if (month < 0 || month > 11) {
1816:                        int[] rem = new int[1];
1817:                        year += floorDivide(month, 12, rem);
1818:                        month = rem[0];
1819:                    }
1820:
1821:                    // Set the MONTH field mask because it's been determined
1822:                    // to use the MONTH field.
1823:                    fieldMask |= 1 << MONTH;
1824:                }
1825:
1826:                boolean isLeap = year % 4 == 0;
1827:                y = year - 1;
1828:                long julianDay = 365L * y + floorDivide(y, 4)
1829:                        + (JAN_1_1_JULIAN_DAY - 3);
1830:
1831:                if (isGregorian) {
1832:                    isLeap = isLeap && ((year % 100 != 0) || (year % 400 == 0));
1833:                    // Add 2 because Gregorian calendar starts 2 days after Julian calendar
1834:                    julianDay += floorDivide(y, 400) - floorDivide(y, 100) + 2;
1835:                }
1836:
1837:                // At this point julianDay is the 0-based day BEFORE the first day of
1838:                // January 1, year 1 of the given calendar.  If julianDay == 0, it
1839:                // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
1840:                // or Gregorian).
1841:
1842:                if (useMonth) {
1843:
1844:                    julianDay += isLeap ? LEAP_NUM_DAYS[month]
1845:                            : NUM_DAYS[month];
1846:
1847:                    if (bestStamp == domStamp) {
1848:                        if (stamp[DAY_OF_MONTH] != UNSET) {
1849:                            date = internalGet(DAY_OF_MONTH);
1850:                            fieldMask |= 1 << DAY_OF_MONTH;
1851:                        } else {
1852:                            date = 1;
1853:                        }
1854:                    } else { // assert(bestStamp == womStamp || bestStamp == dowimStamp)
1855:                        // Compute from day of week plus week number or from the day of
1856:                        // week plus the day of week in month.  The computations are
1857:                        // almost identical.
1858:
1859:                        // Find the day of the week for the first of this month.  This
1860:                        // is zero-based, with 0 being the locale-specific first day of
1861:                        // the week.  Add 1 to get the 1st day of month.  Subtract
1862:                        // getFirstDayOfWeek() to make 0-based.
1863:                        int fdm = julianDayToDayOfWeek(julianDay + 1)
1864:                                - getFirstDayOfWeek();
1865:                        if (fdm < 0) {
1866:                            fdm += 7;
1867:                        }
1868:
1869:                        // Find the start of the first week.  This will be a date from
1870:                        // 0..6.  It represents the locale-specific first day of the
1871:                        // week of the first day of the month, ignoring minimal days in
1872:                        // first week.
1873:                        int normalizedDayOfWeek = 0;
1874:                        if (dowStamp != UNSET) {
1875:                            normalizedDayOfWeek = internalGet(DAY_OF_WEEK)
1876:                                    - getFirstDayOfWeek();
1877:                            if (normalizedDayOfWeek < 0) {
1878:                                normalizedDayOfWeek += 7;
1879:                            }
1880:                            fieldMask |= 1 << DAY_OF_WEEK;
1881:                        }
1882:                        date = 1 - fdm + normalizedDayOfWeek;
1883:
1884:                        if (bestStamp == womStamp) {
1885:                            // Adjust for minimal days in first week.
1886:                            if ((7 - fdm) < getMinimalDaysInFirstWeek()) {
1887:                                date += 7;
1888:                            }
1889:
1890:                            // Now adjust for the week number.
1891:                            date += 7 * (internalGet(WEEK_OF_MONTH) - 1);
1892:                            fieldMask |= 1 << WEEK_OF_MONTH;
1893:                        } else { // assert(bestStamp == dowimStamp)
1894:                            // Adjust into the month, if needed.
1895:                            if (date < 1) {
1896:                                date += 7;
1897:                            }
1898:
1899:                            // We are basing this on the day-of-week-in-month.  The only
1900:                            // special case occurs if the day-of-week-in-month is
1901:                            // negative.
1902:                            int dim;
1903:                            if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) {
1904:                                dim = internalGet(DAY_OF_WEEK_IN_MONTH);
1905:                                fieldMask |= 1 << DAY_OF_WEEK_IN_MONTH;
1906:                            } else {
1907:                                dim = 1;
1908:                            }
1909:                            if (dim >= 0) {
1910:                                date += 7 * (dim - 1);
1911:                            } else {
1912:                                // Move date to the last of this day-of-week in this
1913:                                // month, then back up as needed.  If dim==-1, we don't
1914:                                // back up at all.  If dim==-2, we back up once, etc.
1915:                                // Don't back up past the first of the given day-of-week
1916:                                // in this month.  Note that we handle -2, -3,
1917:                                // etc. correctly, even though values < -1 are
1918:                                // technically disallowed.
1919:                                date += ((monthLength(month, year) - date) / 7
1920:                                        + dim + 1) * 7;
1921:                            }
1922:                        }
1923:                    }
1924:
1925:                    julianDay += date;
1926:                } else {
1927:                    // assert(bestStamp == doyStamp || bestStamp == woyStamp ||
1928:                    // bestStamp == UNSET).  In the last case we should use January 1.
1929:
1930:                    // No month, start with January 0 (day before Jan 1), then adjust.
1931:
1932:                    if (bestStamp == doyStamp) {
1933:                        julianDay += internalGet(DAY_OF_YEAR);
1934:                        fieldMask |= 1 << DAY_OF_YEAR;
1935:                    } else { // assert(bestStamp == woyStamp)
1936:                        // Compute from day of week plus week of year
1937:
1938:                        // Find the day of the week for the first of this year.  This
1939:                        // is zero-based, with 0 being the locale-specific first day of
1940:                        // the week.  Add 1 to get the 1st day of month.  Subtract
1941:                        // getFirstDayOfWeek() to make 0-based.
1942:                        int fdy = julianDayToDayOfWeek(julianDay + 1)
1943:                                - getFirstDayOfWeek();
1944:                        if (fdy < 0) {
1945:                            fdy += 7;
1946:                        }
1947:
1948:                        // Find the start of the first week.  This may be a valid date
1949:                        // from -5..7. It represents the locale-specific first day of
1950:                        // the week of the first day of the year.
1951:                        int normalizedDayOfWeek = 0;
1952:                        if (dowStamp != UNSET) {
1953:                            normalizedDayOfWeek = internalGet(DAY_OF_WEEK)
1954:                                    - getFirstDayOfWeek();
1955:                            if (normalizedDayOfWeek < 0) {
1956:                                normalizedDayOfWeek += 7;
1957:                            }
1958:                            fieldMask |= 1 << DAY_OF_WEEK;
1959:                        }
1960:                        date = 1 - fdy + normalizedDayOfWeek;
1961:
1962:                        // Adjust for minimal days in first week.
1963:                        if ((7 - fdy) < getMinimalDaysInFirstWeek()) {
1964:                            date += 7;
1965:                        }
1966:
1967:                        // Now adjust for the week number.
1968:                        date += 7 * (internalGet(WEEK_OF_YEAR) - 1);
1969:                        fieldMask |= 1 << WEEK_OF_YEAR;
1970:
1971:                        julianDay += date;
1972:                    }
1973:                }
1974:
1975:                fieldMaskParam[0] = fieldMask;
1976:                return julianDay;
1977:            }
1978:
1979:            /////////////////
1980:            // Implementation
1981:            /////////////////
1982:
1983:            /**
1984:             * Converts time as milliseconds to Julian day.
1985:             * @param millis the given milliseconds.
1986:             * @return the Julian day number.
1987:             */
1988:            private static final long millisToJulianDay(long millis) {
1989:                return EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY);
1990:            }
1991:
1992:            /**
1993:             * Converts Julian day to time as milliseconds.
1994:             * @param julian the given Julian day number.
1995:             * @return time as milliseconds.
1996:             */
1997:            private static final long julianDayToMillis(long julian) {
1998:                return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;
1999:            }
2000:
2001:            private static final int julianDayToDayOfWeek(long julian) {
2002:                // If julian is negative, then julian%7 will be negative, so we adjust
2003:                // accordingly.  We add 1 because Julian day 0 is Monday.
2004:                int dayOfWeek = (int) ((julian + 1) % 7);
2005:                return dayOfWeek + ((dayOfWeek < 0) ? (7 + SUNDAY) : SUNDAY);
2006:            }
2007:
2008:            /**
2009:             * Divide two long integers, returning the floor of the quotient.
2010:             * <p>
2011:             * Unlike the built-in division, this is mathematically well-behaved.
2012:             * E.g., <code>-1/4</code> => 0
2013:             * but <code>floorDivide(-1,4)</code> => -1.
2014:             * @param numerator the numerator
2015:             * @param denominator a divisor which must be > 0
2016:             * @return the floor of the quotient.
2017:             */
2018:            private static final long floorDivide(long numerator,
2019:                    long denominator) {
2020:                // We do this computation in order to handle
2021:                // a numerator of Long.MIN_VALUE correctly
2022:                return (numerator >= 0) ? numerator / denominator
2023:                        : ((numerator + 1) / denominator) - 1;
2024:            }
2025:
2026:            /**
2027:             * Divide two integers, returning the floor of the quotient.
2028:             * <p>
2029:             * Unlike the built-in division, this is mathematically well-behaved.
2030:             * E.g., <code>-1/4</code> => 0
2031:             * but <code>floorDivide(-1,4)</code> => -1.
2032:             * @param numerator the numerator
2033:             * @param denominator a divisor which must be > 0
2034:             * @return the floor of the quotient.
2035:             */
2036:            private static final int floorDivide(int numerator, int denominator) {
2037:                // We do this computation in order to handle
2038:                // a numerator of Integer.MIN_VALUE correctly
2039:                return (numerator >= 0) ? numerator / denominator
2040:                        : ((numerator + 1) / denominator) - 1;
2041:            }
2042:
2043:            /**
2044:             * Divide two integers, returning the floor of the quotient, and
2045:             * the modulus remainder.
2046:             * <p>
2047:             * Unlike the built-in division, this is mathematically well-behaved.
2048:             * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
2049:             * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
2050:             * @param numerator the numerator
2051:             * @param denominator a divisor which must be > 0
2052:             * @param remainder an array of at least one element in which the value
2053:             * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
2054:             * % denominator</code>, this will always be non-negative.
2055:             * @return the floor of the quotient.
2056:             */
2057:            private static final int floorDivide(int numerator,
2058:                    int denominator, int[] remainder) {
2059:                if (numerator >= 0) {
2060:                    remainder[0] = numerator % denominator;
2061:                    return numerator / denominator;
2062:                }
2063:                int quotient = ((numerator + 1) / denominator) - 1;
2064:                remainder[0] = numerator - (quotient * denominator);
2065:                return quotient;
2066:            }
2067:
2068:            /**
2069:             * Divide two integers, returning the floor of the quotient, and
2070:             * the modulus remainder.
2071:             * <p>
2072:             * Unlike the built-in division, this is mathematically well-behaved.
2073:             * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
2074:             * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
2075:             * @param numerator the numerator
2076:             * @param denominator a divisor which must be > 0
2077:             * @param remainder an array of at least one element in which the value
2078:             * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
2079:             * % denominator</code>, this will always be non-negative.
2080:             * @return the floor of the quotient.
2081:             */
2082:            private static final int floorDivide(long numerator,
2083:                    int denominator, int[] remainder) {
2084:                if (numerator >= 0) {
2085:                    remainder[0] = (int) (numerator % denominator);
2086:                    return (int) (numerator / denominator);
2087:                }
2088:                int quotient = (int) (((numerator + 1) / denominator) - 1);
2089:                remainder[0] = (int) (numerator - (quotient * denominator));
2090:                return quotient;
2091:            }
2092:
2093:            /**
2094:             * Return the pseudo-time-stamp for two fields, given their
2095:             * individual pseudo-time-stamps.  If either of the fields
2096:             * is unset, then the aggregate is unset.  Otherwise, the
2097:             * aggregate is the later of the two stamps.
2098:             */
2099:            private static final int aggregateStamp(int stamp_a, int stamp_b) {
2100:                return (stamp_a != UNSET && stamp_b != UNSET) ? Math.max(
2101:                        stamp_a, stamp_b) : UNSET;
2102:            }
2103:
2104:            /**
2105:             * Return the week number of a day, within a period. This may be the week number in
2106:             * a year, or the week number in a month. Usually this will be a value >= 1, but if
2107:             * some initial days of the period are excluded from week 1, because
2108:             * minimalDaysInFirstWeek is > 1, then the week number will be zero for those
2109:             * initial days. Requires the day of week for the given date in order to determine
2110:             * the day of week of the first day of the period.
2111:             *
2112:             * @param dayOfPeriod  Day-of-year or day-of-month. Should be 1 for first day of period.
2113:             * @param day   Day-of-week for given dayOfPeriod. 1-based with 1=Sunday.
2114:             * @return      Week number, one-based, or zero if the day falls in part of the
2115:             *              month before the first week, when there are days before the first
2116:             *              week because the minimum days in the first week is more than one.
2117:             */
2118:            private final int weekNumber(int dayOfPeriod, int dayOfWeek) {
2119:                // Determine the day of the week of the first day of the period
2120:                // in question (either a year or a month).  Zero represents the
2121:                // first day of the week on this calendar.
2122:                int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek()
2123:                        - dayOfPeriod + 1) % 7;
2124:                if (periodStartDayOfWeek < 0) {
2125:                    periodStartDayOfWeek += 7;
2126:                }
2127:
2128:                // Compute the week number.  Initially, ignore the first week, which
2129:                // may be fractional (or may not be).  We add periodStartDayOfWeek in
2130:                // order to fill out the first week, if it is fractional.
2131:                int weekNo = (dayOfPeriod + periodStartDayOfWeek - 1) / 7;
2132:
2133:                // If the first week is long enough, then count it.  If
2134:                // the minimal days in the first week is one, or if the period start
2135:                // is zero, we always increment weekNo.
2136:                if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) {
2137:                    ++weekNo;
2138:                }
2139:
2140:                return weekNo;
2141:            }
2142:
2143:            private final int monthLength(int month, int year) {
2144:                return isLeapYear(year) ? LEAP_MONTH_LENGTH[month]
2145:                        : MONTH_LENGTH[month];
2146:            }
2147:
2148:            private final int monthLength(int month) {
2149:                int year = internalGet(YEAR);
2150:                if (internalGetEra() == BC) {
2151:                    year = 1 - year;
2152:                }
2153:                return monthLength(month, year);
2154:            }
2155:
2156:            /**
2157:             * Returns the length of the previous month.  For January, returns the
2158:             * arbitrary value 31, which will not be used:  This value is passed to
2159:             * SimpleTimeZone.getOffset(), and if the month is -1 (the month before
2160:             * January), the day value will be ignored.
2161:             */
2162:            private final int prevMonthLength(int month) {
2163:                return (month > 1) ? monthLength(month - 1) : 31;
2164:            }
2165:
2166:            private final int yearLength(int year) {
2167:                return isLeapYear(year) ? 366 : 365;
2168:            }
2169:
2170:            private final int yearLength() {
2171:                return isLeapYear(internalGet(YEAR)) ? 366 : 365;
2172:            }
2173:
2174:            /**
2175:             * After adjustments such as add(MONTH), add(YEAR), we don't want the
2176:             * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
2177:             * 3, we want it to go to Feb 28.  Adjustments which might run into this
2178:             * problem call this method to retain the proper month.
2179:             */
2180:            private final void pinDayOfMonth() {
2181:                int monthLen = monthLength(internalGet(MONTH));
2182:                int dom = internalGet(DAY_OF_MONTH);
2183:                if (dom > monthLen) {
2184:                    set(DAY_OF_MONTH, monthLen);
2185:                }
2186:            }
2187:
2188:            /**
2189:             * Validates the values of the set time fields.
2190:             */
2191:            private boolean validateFields() {
2192:                for (int field = 0; field < FIELD_COUNT; field++) {
2193:                    // Ignore DATE and DAY_OF_YEAR which are handled below
2194:                    if (field != DATE && field != DAY_OF_YEAR && isSet(field)
2195:                            && !boundsCheck(internalGet(field), field)) {
2196:                        return false;
2197:                    }
2198:                }
2199:
2200:                // Values differ in Least-Maximum and Maximum should be handled
2201:                // specially.
2202:                if (stamp[DATE] >= MINIMUM_USER_STAMP) {
2203:                    int date = internalGet(DATE);
2204:                    if (date < getMinimum(DATE)
2205:                            || date > monthLength(internalGet(MONTH))) {
2206:                        return false;
2207:                    }
2208:                }
2209:
2210:                if (stamp[DAY_OF_YEAR] >= MINIMUM_USER_STAMP) {
2211:                    int days = internalGet(DAY_OF_YEAR);
2212:                    if (days < 1 || days > yearLength()) {
2213:                        return false;
2214:                    }
2215:                }
2216:
2217:                // Handle DAY_OF_WEEK_IN_MONTH, which must not have the value zero.
2218:                // We've checked against minimum and maximum above already.
2219:                if (isSet(DAY_OF_WEEK_IN_MONTH)
2220:                        && 0 == internalGet(DAY_OF_WEEK_IN_MONTH)) {
2221:                    return false;
2222:                }
2223:
2224:                return true;
2225:            }
2226:
2227:            /**
2228:             * Validates the value of the given time field.
2229:             */
2230:            private final boolean boundsCheck(int value, int field) {
2231:                return value >= getMinimum(field) && value <= getMaximum(field);
2232:            }
2233:
2234:            /**
2235:             * Return the day number with respect to the epoch.  January 1, 1970 (Gregorian)
2236:             * is day zero.
2237:             */
2238:            private final long getEpochDay() {
2239:                complete();
2240:                // Divide by 1000 (convert to seconds) in order to prevent overflow when
2241:                // dealing with Date(Long.MIN_VALUE) and Date(Long.MAX_VALUE).
2242:                long wallSec = time / 1000
2243:                        + (internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET))
2244:                        / 1000;
2245:                return floorDivide(wallSec, ONE_DAY / 1000);
2246:            }
2247:
2248:            /**
2249:             * Return the ERA.  We need a special method for this because the
2250:             * default ERA is AD, but a zero (unset) ERA is BC.
2251:             */
2252:            private final int internalGetEra() {
2253:                return isSet(ERA) ? internalGet(ERA) : AD;
2254:            }
2255:
2256:            /**
2257:             * Updates internal state.
2258:             */
2259:            private void readObject(ObjectInputStream stream)
2260:                    throws IOException, ClassNotFoundException {
2261:                stream.defaultReadObject();
2262:                setGregorianChange(new Date(gregorianCutover));
2263:            }
2264:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.