Source Code Cross Referenced for Calendar.java in  » Internationalization-Localization » icu4j » com » ibm » icu » 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 » Internationalization Localization » icu4j » com.ibm.icu.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *   Copyright (C) 1996-2006, International Business Machines
0003:         *   Corporation and others.  All Rights Reserved.
0004:         */
0005:
0006:        package com.ibm.icu.util;
0007:
0008:        import com.ibm.icu.impl.ICULocaleService;
0009:        import com.ibm.icu.impl.ICULocaleService.LocaleKeyFactory;
0010:        import com.ibm.icu.impl.ICUResourceBundle;
0011:        import com.ibm.icu.impl.ICUService.Factory;
0012:        import com.ibm.icu.impl.CalendarData;
0013:        import com.ibm.icu.text.DateFormat;
0014:        import com.ibm.icu.text.DateFormatSymbols;
0015:        import com.ibm.icu.text.SimpleDateFormat;
0016:        import com.ibm.icu.util.TimeZone;
0017:        import com.ibm.icu.util.BuddhistCalendar;
0018:        import com.ibm.icu.util.ChineseCalendar;
0019:        import com.ibm.icu.util.CopticCalendar;
0020:        import com.ibm.icu.util.EthiopicCalendar;
0021:        import com.ibm.icu.util.GregorianCalendar;
0022:        import com.ibm.icu.util.HebrewCalendar;
0023:        import com.ibm.icu.util.IslamicCalendar;
0024:        import com.ibm.icu.util.JapaneseCalendar;
0025:
0026:        import java.io.IOException;
0027:        import java.io.ObjectInputStream;
0028:        import java.io.ObjectOutputStream;
0029:        import java.io.Serializable;
0030:        import java.text.MessageFormat;
0031:        import java.util.Collections;
0032:        import java.util.Date;
0033:        import java.util.Hashtable;
0034:        import java.util.HashMap;
0035:        import java.util.Locale;
0036:        import java.util.Map;
0037:        import java.util.MissingResourceException;
0038:        import java.util.ResourceBundle;
0039:        import java.util.Set;
0040:
0041:        /**
0042:         * <code>Calendar</code> is an abstract base class for converting between
0043:         * a <code>Date</code> object and a set of integer fields such as
0044:         * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
0045:         * and so on. (A <code>Date</code> object represents a specific instant in
0046:         * time with millisecond precision. See
0047:         * {@link Date}
0048:         * for information about the <code>Date</code> class.)
0049:         *
0050:         * <p><b>Note:</b>  This class is similar, but not identical, to the class
0051:         * <code>java.util.Calendar</code>.  Changes are detailed below.
0052:         *
0053:         * <p>
0054:         * Subclasses of <code>Calendar</code> interpret a <code>Date</code>
0055:         * according to the rules of a specific calendar system.  ICU4J contains
0056:         * several subclasses implementing different international calendar systems.
0057:         *
0058:         * <p>
0059:         * Like other locale-sensitive classes, <code>Calendar</code> provides a
0060:         * class method, <code>getInstance</code>, for getting a generally useful
0061:         * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
0062:         * returns a calendar of a type appropriate to the locale, whose
0063:         * time fields have been initialized with the current date and time:
0064:         * <blockquote>
0065:         * <pre>Calendar rightNow = Calendar.getInstance()</pre>
0066:         * </blockquote>
0067:         *
0068:         * <p>When a <code>ULocale</code> is used by <code>getInstance</code>, its
0069:         * '<code>calendar</code>' tag and value are retrieved if present.  If a recognized
0070:         * value is supplied, a calendar is provided and configured as appropriate.
0071:         * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic", 
0072:         * "gregorian", "hebrew", "islamic", "islamic-civil", and "japanese".  For
0073:         * example: <blockquote>
0074:         * <pre>Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));</pre>
0075:         * </blockquote> will return an instance of JapaneseCalendar (using en_US conventions for
0076:         * minimum days in first week, start day of week, et cetera).
0077:         *
0078:         * <p>A <code>Calendar</code> object can produce all the time field values
0079:         * needed to implement the date-time formatting for a particular language and
0080:         * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
0081:         * <code>Calendar</code> defines the range of values returned by certain fields,
0082:         * as well as their meaning.  For example, the first month of the year has value
0083:         * <code>MONTH</code> == <code>JANUARY</code> for all calendars.  Other values
0084:         * are defined by the concrete subclass, such as <code>ERA</code> and
0085:         * <code>YEAR</code>.  See individual field documentation and subclass
0086:         * documentation for details.
0087:         *
0088:         * <p>When a <code>Calendar</code> is <em>lenient</em>, it accepts a wider range
0089:         * of field values than it produces.  For example, a lenient
0090:         * <code>GregorianCalendar</code> interprets <code>MONTH</code> ==
0091:         * <code>JANUARY</code>, <code>DAY_OF_MONTH</code> == 32 as February 1.  A
0092:         * non-lenient <code>GregorianCalendar</code> throws an exception when given
0093:         * out-of-range field settings.  When calendars recompute field values for
0094:         * return by <code>get()</code>, they normalize them.  For example, a
0095:         * <code>GregorianCalendar</code> always produces <code>DAY_OF_MONTH</code>
0096:         * values between 1 and the length of the month.
0097:         *
0098:         * <p><code>Calendar</code> defines a locale-specific seven day week using two
0099:         * parameters: the first day of the week and the minimal days in first week
0100:         * (from 1 to 7).  These numbers are taken from the locale resource data when a
0101:         * <code>Calendar</code> is constructed.  They may also be specified explicitly
0102:         * through the API.
0103:         *
0104:         * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
0105:         * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
0106:         * first week of the month or year as a reference point.  The first week of a
0107:         * month or year is defined as the earliest seven day period beginning on
0108:         * <code>getFirstDayOfWeek()</code> and containing at least
0109:         * <code>getMinimalDaysInFirstWeek()</code> days of that month or year.  Weeks
0110:         * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
0111:         * it.  Note that the normalized numbering returned by <code>get()</code> may be
0112:         * different.  For example, a specific <code>Calendar</code> subclass may
0113:         * designate the week before week 1 of a year as week <em>n</em> of the previous
0114:         * year.
0115:         *
0116:         * <p> When computing a <code>Date</code> from time fields, two special
0117:         * circumstances may arise: there may be insufficient information to compute the
0118:         * <code>Date</code> (such as only year and month but no day in the month), or
0119:         * there may be inconsistent information (such as "Tuesday, July 15, 1996" --
0120:         * July 15, 1996 is actually a Monday).
0121:         *
0122:         * <p>
0123:         * <strong>Insufficient information.</strong> The calendar will use default
0124:         * information to specify the missing fields. This may vary by calendar; for
0125:         * the Gregorian calendar, the default for a field is the same as that of the
0126:         * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
0127:         *
0128:         * <p>
0129:         * <strong>Inconsistent information.</strong> If fields conflict, the calendar
0130:         * will give preference to fields set more recently. For example, when
0131:         * determining the day, the calendar will look for one of the following
0132:         * combinations of fields.  The most recent combination, as determined by the
0133:         * most recently set single field, will be used.
0134:         *
0135:         * <blockquote>
0136:         * <pre>
0137:         * MONTH + DAY_OF_MONTH
0138:         * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
0139:         * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
0140:         * DAY_OF_YEAR
0141:         * DAY_OF_WEEK + WEEK_OF_YEAR</pre>
0142:         * </blockquote>
0143:         *
0144:         * For the time of day:
0145:         *
0146:         * <blockquote>
0147:         * <pre>
0148:         * HOUR_OF_DAY
0149:         * AM_PM + HOUR</pre>
0150:         * </blockquote>
0151:         *
0152:         * <p>
0153:         * <strong>Note:</strong> for some non-Gregorian calendars, different
0154:         * fields may be necessary for complete disambiguation. For example, a full
0155:         * specification of the historial Arabic astronomical calendar requires year,
0156:         * month, day-of-month <em>and</em> day-of-week in some cases.
0157:         *
0158:         * <p>
0159:         * <strong>Note:</strong> There are certain possible ambiguities in
0160:         * interpretation of certain singular times, which are resolved in the
0161:         * following ways:
0162:         * <ol>
0163:         *     <li> 24:00:00 "belongs" to the following day. That is,
0164:         *          23:59 on Dec 31, 1969 &lt; 24:00 on Jan 1, 1970 &lt; 24:01:00 on Jan 1, 1970
0165:         *
0166:         *     <li> Although historically not precise, midnight also belongs to "am",
0167:         *          and noon belongs to "pm", so on the same day,
0168:         *          12:00 am (midnight) &lt; 12:01 am, and 12:00 pm (noon) &lt; 12:01 pm
0169:         * </ol>
0170:         *
0171:         * <p>
0172:         * The date or time format strings are not part of the definition of a
0173:         * calendar, as those must be modifiable or overridable by the user at
0174:         * runtime. Use {@link DateFormat}
0175:         * to format dates.
0176:         *
0177:         * <p><strong>Field manipulation methods</strong></p>
0178:         *
0179:         * <p><code>Calendar</code> fields can be changed using three methods:
0180:         * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
0181:         *
0182:         * <p><strong><code>set(f, value)</code></strong> changes field
0183:         * <code>f</code> to <code>value</code>.  In addition, it sets an
0184:         * internal member variable to indicate that field <code>f</code> has
0185:         * been changed. Although field <code>f</code> is changed immediately,
0186:         * the calendar's milliseconds is not recomputed until the next call to
0187:         * <code>get()</code>, <code>getTime()</code>, or
0188:         * <code>getTimeInMillis()</code> is made. Thus, multiple calls to
0189:         * <code>set()</code> do not trigger multiple, unnecessary
0190:         * computations. As a result of changing a field using
0191:         * <code>set()</code>, other fields may also change, depending on the
0192:         * field, the field value, and the calendar system. In addition,
0193:         * <code>get(f)</code> will not necessarily return <code>value</code>
0194:         * after the fields have been recomputed. The specifics are determined by
0195:         * the concrete calendar class.</p>
0196:         *
0197:         * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
0198:         * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
0199:         * Calendar.SEPTEMBER)</code> sets the calendar to September 31,
0200:         * 1999. This is a temporary internal representation that resolves to
0201:         * October 1, 1999 if <code>getTime()</code>is then called. However, a
0202:         * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
0203:         * <code>getTime()</code> sets the calendar to September 30, 1999, since
0204:         * no recomputation occurs after <code>set()</code> itself.</p>
0205:         *
0206:         * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
0207:         * to field <code>f</code>.  This is equivalent to calling <code>set(f,
0208:         * get(f) + delta)</code> with two adjustments:</p>
0209:         *
0210:         * <blockquote>
0211:         *   <p><strong>Add rule 1</strong>. The value of field <code>f</code>
0212:         *   after the call minus the value of field <code>f</code> before the
0213:         *   call is <code>delta</code>, modulo any overflow that has occurred in
0214:         *   field <code>f</code>. Overflow occurs when a field value exceeds its
0215:         *   range and, as a result, the next larger field is incremented or
0216:         *   decremented and the field value is adjusted back into its range.</p>
0217:         *
0218:         *   <p><strong>Add rule 2</strong>. If a smaller field is expected to be
0219:         *   invariant, but &nbsp; it is impossible for it to be equal to its
0220:         *   prior value because of changes in its minimum or maximum after field
0221:         *   <code>f</code> is changed, then its value is adjusted to be as close
0222:         *   as possible to its expected value. A smaller field represents a
0223:         *   smaller unit of time. <code>HOUR</code> is a smaller field than
0224:         *   <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
0225:         *   that are not expected to be invariant. The calendar system
0226:         *   determines what fields are expected to be invariant.</p>
0227:         * </blockquote>
0228:         *
0229:         * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
0230:         * an immediate recomputation of the calendar's milliseconds and all
0231:         * fields.</p>
0232:         *
0233:         * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
0234:         * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
0235:         * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
0236:         * 1</strong> sets the <code>MONTH</code> field to September, since
0237:         * adding 13 months to August gives September of the next year. Since
0238:         * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
0239:         * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
0240:         * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
0241:         * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
0242:         * rule 2, since it is expected to change when the month changes in a
0243:         * <code>GregorianCalendar</code>.</p>
0244:         *
0245:         * <p><strong><code>roll(f, delta)</code></strong> adds
0246:         * <code>delta</code> to field <code>f</code> without changing larger
0247:         * fields. This is equivalent to calling <code>add(f, delta)</code> with
0248:         * the following adjustment:</p>
0249:         *
0250:         * <blockquote>
0251:         *   <p><strong>Roll rule</strong>. Larger fields are unchanged after the
0252:         *   call. A larger field represents a larger unit of
0253:         *   time. <code>DAY_OF_MONTH</code> is a larger field than
0254:         *   <code>HOUR</code>.</p>
0255:         * </blockquote>
0256:         *
0257:         * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
0258:         * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
0259:         * 8)</code> sets the calendar to April 30, <strong>1999</strong>.  Add
0260:         * rule 1 sets the <code>MONTH</code> field to April. Using a
0261:         * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> cannot
0262:         * be 31 in the month April. Add rule 2 sets it to the closest possible
0263:         * value, 30. Finally, the <strong>roll rule</strong> maintains the
0264:         * <code>YEAR</code> field value of 1999.</p>
0265:         *
0266:         * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
0267:         * originally set to Sunday June 6, 1999. Calling
0268:         * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
0269:         * Tuesday June 1, 1999, whereas calling
0270:         * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
0271:         * Sunday May 30, 1999. This is because the roll rule imposes an
0272:         * additional constraint: The <code>MONTH</code> must not change when the
0273:         * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1,
0274:         * the resultant date must be between Tuesday June 1 and Saturday June
0275:         * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant
0276:         * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the
0277:         * closest possible value to Sunday (where Sunday is the first day of the
0278:         * week).</p>
0279:         *
0280:         * <p><strong>Usage model</strong>. To motivate the behavior of
0281:         * <code>add()</code> and <code>roll()</code>, consider a user interface
0282:         * component with increment and decrement buttons for the month, day, and
0283:         * year, and an underlying <code>GregorianCalendar</code>. If the
0284:         * interface reads January 31, 1999 and the user presses the month
0285:         * increment button, what should it read? If the underlying
0286:         * implementation uses <code>set()</code>, it might read March 3, 1999. A
0287:         * better result would be February 28, 1999. Furthermore, if the user
0288:         * presses the month increment button again, it should read March 31,
0289:         * 1999, not March 28, 1999. By saving the original date and using either
0290:         * <code>add()</code> or <code>roll()</code>, depending on whether larger
0291:         * fields should be affected, the user interface can behave as most users
0292:         * will intuitively expect.</p>
0293:         *
0294:         * <p><b>Note:</b> You should always use {@link #roll roll} and {@link #add add} rather
0295:         * than attempting to perform arithmetic operations directly on the fields
0296:         * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
0297:         * to have fields with non-linear behavior, for example missing months
0298:         * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
0299:         * methods will take this into account, while simple arithmetic manipulations
0300:         * may give invalid results.
0301:         *
0302:         * <p><big><big><b>Calendar Architecture in ICU4J</b></big></big></p>
0303:         *
0304:         * <p>Recently the implementation of <code>Calendar</code> has changed
0305:         * significantly in order to better support subclassing. The original
0306:         * <code>Calendar</code> class was designed to support subclassing, but
0307:         * it had only one implemented subclass, <code>GregorianCalendar</code>.
0308:         * With the implementation of several new calendar subclasses, including
0309:         * the <code>BuddhistCalendar</code>, <code>ChineseCalendar</code>,
0310:         * <code>HebrewCalendar</code>, <code>IslamicCalendar</code>, and
0311:         * <code>JapaneseCalendar</code>, the subclassing API has been reworked
0312:         * thoroughly. This section details the new subclassing API and other
0313:         * ways in which <code>com.ibm.icu.util.Calendar</code> differs from
0314:         * <code>java.util.Calendar</code>.
0315:         * </p>
0316:         *
0317:         * <p><big><b>Changes</b></big></p>
0318:         *
0319:         * <p>Overview of changes between the classic <code>Calendar</code>
0320:         * architecture and the new architecture.
0321:         *
0322:         * <ul>
0323:         *
0324:         *   <li>The <code>fields[]</code> array is <code>private</code> now
0325:         *     instead of <code>protected</code>.  Subclasses must access it
0326:         *     using the methods {@link #internalSet} and
0327:         *     {@link #internalGet}.  <b>Motivation:</b> Subclasses should
0328:         *     not directly access data members.</li>
0329:         *
0330:         *   <li>The <code>time</code> long word is <code>private</code> now
0331:         *     instead of <code>protected</code>.  Subclasses may access it using
0332:         *     the method {@link #internalGetTimeInMillis}, which does not
0333:         *     provoke an update. <b>Motivation:</b> Subclasses should not
0334:         *     directly access data members.</li>
0335:         *
0336:         *   <li>The scope of responsibility of subclasses has been drastically
0337:         *     reduced. As much functionality as possible is implemented in the
0338:         *     <code>Calendar</code> base class. As a result, it is much easier
0339:         *     to subclass <code>Calendar</code>. <b>Motivation:</b> Subclasses
0340:         *     should not have to reimplement common code. Certain behaviors are
0341:         *     common across calendar systems: The definition and behavior of
0342:         *     week-related fields and time fields, the arithmetic
0343:         *     ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many
0344:         *     fields, and the field validation system.</li>
0345:         *
0346:         *   <li>The subclassing API has been completely redesigned.</li>
0347:         *
0348:         *   <li>The <code>Calendar</code> base class contains some Gregorian
0349:         *     calendar algorithmic support that subclasses can use (specifically
0350:         *     in {@link #handleComputeFields}).  Subclasses can use the
0351:         *     methods <code>getGregorianXxx()</code> to obtain precomputed
0352:         *     values. <b>Motivation:</b> This is required by all
0353:         *     <code>Calendar</code> subclasses in order to implement consistent
0354:         *     time zone behavior, and Gregorian-derived systems can use the
0355:         *     already computed data.</li>
0356:         *
0357:         *   <li>The <code>FIELD_COUNT</code> constant has been removed. Use
0358:         *     {@link #getFieldCount}.  In addition, framework API has been
0359:         *     added to allow subclasses to define additional fields.
0360:         *     <b>Motivation: </b>The number of fields is not constant across
0361:         *     calendar systems.</li>
0362:         *
0363:         *   <li>The range of handled dates has been narrowed from +/-
0364:         *     ~300,000,000 years to +/- ~5,000,000 years. In practical terms
0365:         *     this should not affect clients. However, it does mean that client
0366:         *     code cannot be guaranteed well-behaved results with dates such as
0367:         *     <code>Date(Long.MIN_VALUE)</code> or
0368:         *     <code>Date(Long.MAX_VALUE)</code>. Instead, the
0369:         *     <code>Calendar</code> constants {@link #MIN_DATE},
0370:         *     {@link #MAX_DATE}, {@link #MIN_MILLIS},
0371:         *     {@link #MAX_MILLIS}, {@link #MIN_JULIAN}, and
0372:         *     {@link #MAX_JULIAN} should be used. <b>Motivation:</b> With
0373:         *     the addition of the {@link #JULIAN_DAY} field, Julian day
0374:         *     numbers must be restricted to a 32-bit <code>int</code>.  This
0375:         *     restricts the overall supported range. Furthermore, restricting
0376:         *     the supported range simplifies the computations by removing
0377:         *     special case code that was used to accomodate arithmetic overflow
0378:         *     at millis near <code>Long.MIN_VALUE</code> and
0379:         *     <code>Long.MAX_VALUE</code>.</li>
0380:         *
0381:         *   <li>New fields are implemented: {@link #JULIAN_DAY} defines
0382:         *     single-field specification of the
0383:         *     date. {@link #MILLISECONDS_IN_DAY} defines a single-field
0384:         *     specification of the wall time. {@link #DOW_LOCAL} and
0385:         *     {@link #YEAR_WOY} implement localized day-of-week and
0386:         *     week-of-year behavior.</li>
0387:         *
0388:         *   <li>Subclasses can access millisecond constants
0389:         *     {@link #ONE_SECOND}, {@link #ONE_MINUTE},
0390:         *     {@link #ONE_HOUR}, {@link #ONE_DAY}, and
0391:         *     {@link #ONE_WEEK} defined in <code>Calendar</code>.</li>
0392:         *
0393:         *   <li>New API has been added to suport calendar-specific subclasses
0394:         *     of <code>DateFormat</code>.</li>
0395:         *
0396:         *   <li>Several subclasses have been implemented, representing
0397:         *     various international calendar systems.</li>
0398:         *
0399:         * </ul>
0400:         *
0401:         * <p><big><b>Subclass API</b></big></p>
0402:         *
0403:         * <p>The original <code>Calendar</code> API was based on the experience
0404:         * of implementing a only a single subclass,
0405:         * <code>GregorianCalendar</code>. As a result, all of the subclassing
0406:         * kinks had not been worked out. The new subclassing API has been
0407:         * refined based on several implemented subclasses. This includes methods
0408:         * that must be overridden and methods for subclasses to call. Subclasses
0409:         * no longer have direct access to <code>fields</code> and
0410:         * <code>stamp</code>. Instead, they have new API to access
0411:         * these. Subclasses are able to allocate the <code>fields</code> array
0412:         * through a protected framework method; this allows subclasses to
0413:         * specify additional fields. </p>
0414:         *
0415:         * <p>More functionality has been moved into the base class. The base
0416:         * class now contains much of the computational machinery to support the
0417:         * Gregorian calendar. This is based on two things: (1) Many calendars
0418:         * are based on the Gregorian calendar (such as the Buddhist and Japanese
0419:         * imperial calendars). (2) <em>All</em> calendars require basic
0420:         * Gregorian support in order to handle timezone computations. </p>
0421:         *
0422:         * <p>Common computations have been moved into
0423:         * <code>Calendar</code>. Subclasses no longer compute the week related
0424:         * fields and the time related fields. These are commonly handled for all
0425:         * calendars by the base class. </p>
0426:         *
0427:         * <p><b>Subclass computation of time <tt>=&gt;</tt> fields</b>
0428:         *
0429:         * <p>The {@link #ERA}, {@link #YEAR},
0430:         * {@link #EXTENDED_YEAR}, {@link #MONTH},
0431:         * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are
0432:         * computed by the subclass, based on the Julian day. All other fields
0433:         * are computed by <code>Calendar</code>.
0434:         *
0435:         * <ul>
0436:         *
0437:         *   <li>Subclasses should implement {@link #handleComputeFields}
0438:         *     to compute the {@link #ERA}, {@link #YEAR},
0439:         *     {@link #EXTENDED_YEAR}, {@link #MONTH},
0440:         *     {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields,
0441:         *     based on the value of the {@link #JULIAN_DAY} field. If there
0442:         *     are calendar-specific fields not defined by <code>Calendar</code>,
0443:         *     they must also be computed. These are the only fields that the
0444:         *     subclass should compute. All other fields are computed by the base
0445:         *     class, so time and week fields behave in a consistent way across
0446:         *     all calendars. The default version of this method in
0447:         *     <code>Calendar</code> implements a proleptic Gregorian
0448:         *     calendar. Within this method, subclasses may call
0449:         *     <code>getGregorianXxx()</code> to obtain the Gregorian calendar
0450:         *     month, day of month, and extended year for the given date.</li>
0451:         *
0452:         * </ul>
0453:         *
0454:         * <p><b>Subclass computation of fields <tt>=&gt;</tt> time</b>
0455:         *
0456:         * <p>The interpretation of most field values is handled entirely by
0457:         * <code>Calendar</code>. <code>Calendar</code> determines which fields
0458:         * are set, which are not, which are set more recently, and so on. In
0459:         * addition, <code>Calendar</code> handles the computation of the time
0460:         * from the time fields and handles the week-related fields. The only
0461:         * thing the subclass must do is determine the extended year, based on
0462:         * the year fields, and then, given an extended year and a month, it must
0463:         * return a Julian day number.
0464:         *
0465:         * <ul>
0466:         *
0467:         *   <li>Subclasses should implement {@link #handleGetExtendedYear}
0468:         *     to return the extended year for this calendar system, based on the
0469:         *     {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that
0470:         *     the calendar system uses that are larger than a year, such as
0471:         *     {@link #ERA}.</li>
0472:         *
0473:         *   <li>Subclasses should implement {@link #handleComputeMonthStart}
0474:         *     to return the Julian day number
0475:         *     associated with a month and extended year. This is the Julian day
0476:         *     number of the day before the first day of the month. The month
0477:         *     number is zero-based. This computation should not depend on any
0478:         *     field values.</li>
0479:         *
0480:         * </ul>
0481:         *
0482:         * <p><b>Other methods</b>
0483:         *
0484:         * <ul>
0485:         *
0486:         *   <li>Subclasses should implement {@link #handleGetMonthLength}
0487:         *     to return the number of days in a
0488:         *     given month of a given extended year. The month number, as always,
0489:         *     is zero-based.</li>
0490:         *
0491:         *   <li>Subclasses should implement {@link #handleGetYearLength}
0492:         *     to return the number of days in the given
0493:         *     extended year. This method is used by
0494:         *     <tt>computeWeekFields</tt> to compute the
0495:         *     {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.</li>
0496:         *
0497:         *   <li>Subclasses should implement {@link #handleGetLimit}
0498:         *     to return the {@link #MINIMUM},
0499:         *     {@link #GREATEST_MINIMUM}, {@link #LEAST_MAXIMUM}, or
0500:         *     {@link #MAXIMUM} of a field, depending on the value of
0501:         *     <code>limitType</code>. This method only needs to handle the
0502:         *     fields {@link #ERA}, {@link #YEAR}, {@link #MONTH},
0503:         *     {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH},
0504:         *     {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR},
0505:         *     {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and
0506:         *     {@link #EXTENDED_YEAR}.  Other fields are invariant (with
0507:         *     respect to calendar system) and are handled by the base
0508:         *     class.</li>
0509:         *
0510:         *   <li>Optionally, subclasses may override {@link #validateField}
0511:         *     to check any subclass-specific fields. If the
0512:         *     field's value is out of range, the method should throw an
0513:         *     <code>IllegalArgumentException</code>. The method may call
0514:         *     <code>super.validateField(field)</code> to handle fields in a
0515:         *     generic way, that is, to compare them to the range
0516:         *     <code>getMinimum(field)</code>..<code>getMaximum(field)</code>.</li>
0517:         *
0518:         *   <li>Optionally, subclasses may override
0519:         *     {@link #handleCreateFields} to create an <code>int[]</code>
0520:         *     array large enough to hold the calendar's fields. This is only
0521:         *     necessary if the calendar defines additional fields beyond those
0522:         *     defined by <code>Calendar</code>. The length of the result must be
0523:         *     at least {@link #BASE_FIELD_COUNT} and no more than
0524:         *     {@link #MAX_FIELD_COUNT}.</li>
0525:         *
0526:         *   <li>Optionally, subclasses may override
0527:         *     {@link #handleGetDateFormat} to create a
0528:         *     <code>DateFormat</code> appropriate to this calendar. This is only
0529:         *     required if a calendar subclass redefines the use of a field (for
0530:         *     example, changes the {@link #ERA} field from a symbolic field
0531:         *     to a numeric one) or defines an additional field.</li>
0532:         *
0533:         *   <li>Optionally, subclasses may override {@link #roll roll} and
0534:         *     {@link #add add} to handle fields that are discontinuous. For
0535:         *     example, in the Hebrew calendar the month &quot;Adar I&quot; only
0536:         *     occurs in leap years; in other years the calendar jumps from
0537:         *     Shevat (month #4) to Adar (month #6). The {@link
0538:         *     HebrewCalendar#add HebrewCalendar.add} and {@link
0539:         *     HebrewCalendar#roll HebrewCalendar.roll} methods take this into
0540:         *     account, so that adding 1 month to Shevat gives the proper result
0541:         *     (Adar) in a non-leap year. The protected utility method {@link
0542:         *     #pinField pinField} is often useful when implementing these two
0543:         *     methods. </li>
0544:         *
0545:         * </ul>
0546:         *
0547:         * <p><big><b>Normalized behavior</b></big>
0548:         *
0549:         * <p>The behavior of certain fields has been made consistent across all
0550:         * calendar systems and implemented in <code>Calendar</code>.
0551:         *
0552:         * <ul>
0553:         *
0554:         *   <li>Time is normalized. Even though some calendar systems transition
0555:         *     between days at sunset or at other times, all ICU4J calendars
0556:         *     transition between days at <em>local zone midnight</em>.  This
0557:         *     allows ICU4J to centralize the time computations in
0558:         *     <code>Calendar</code> and to maintain basic correpsondences
0559:         *     between calendar systems. Affected fields: {@link #AM_PM},
0560:         *     {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE},
0561:         *     {@link #SECOND}, {@link #MILLISECOND},
0562:         *     {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.</li>
0563:         *
0564:         *   <li>DST behavior is normalized. Daylight savings time behavior is
0565:         *     computed the same for all calendar systems, and depends on the
0566:         *     value of several <code>GregorianCalendar</code> fields: the
0567:         *     {@link #YEAR}, {@link #MONTH}, and
0568:         *     {@link #DAY_OF_MONTH}. As a result, <code>Calendar</code>
0569:         *     always computes these fields, even for non-Gregorian calendar
0570:         *     systems. These fields are available to subclasses.</li>
0571:         *
0572:         *   <li>Weeks are normalized. Although locales define the week
0573:         *     differently, in terms of the day on which it starts, and the
0574:         *     designation of week number one of a month or year, they all use a
0575:         *     common mechanism. Furthermore, the day of the week has a simple
0576:         *     and consistent definition throughout history. For example,
0577:         *     although the Gregorian calendar introduced a discontinuity when
0578:         *     first instituted, the day of week was not disrupted. For this
0579:         *     reason, the fields {@link #DAY_OF_WEEK}, <code>WEEK_OF_YEAR,
0580:         *     WEEK_OF_MONTH</code>, {@link #DAY_OF_WEEK_IN_MONTH},
0581:         *     {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in
0582:         *     a consistent way in the base class, based on the
0583:         *     {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR},
0584:         *     {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are
0585:         *     computed by the subclass.</li>
0586:         *
0587:         * </ul>
0588:         *
0589:         * <p><big><b>Supported range</b></big>
0590:         *
0591:         * <p>The allowable range of <code>Calendar</code> has been
0592:         * narrowed. <code>GregorianCalendar</code> used to attempt to support
0593:         * the range of dates with millisecond values from
0594:         * <code>Long.MIN_VALUE</code> to <code>Long.MAX_VALUE</code>. This
0595:         * introduced awkward constructions (hacks) which slowed down
0596:         * performance. It also introduced non-uniform behavior at the
0597:         * boundaries. The new <code>Calendar</code> protocol specifies the
0598:         * maximum range of supportable dates as those having Julian day numbers
0599:         * of <code>-0x7F000000</code> to <code>+0x7F000000</code>. This
0600:         * corresponds to years from ~5,000,000 BCE to ~5,000,000 CE. Programmers
0601:         * should use the constants {@link #MIN_DATE} (or
0602:         * {@link #MIN_MILLIS} or {@link #MIN_JULIAN}) and
0603:         * {@link #MAX_DATE} (or {@link #MAX_MILLIS} or
0604:         * {@link #MAX_JULIAN}) in <code>Calendar</code> to specify an
0605:         * extremely early or extremely late date.</p>
0606:         *
0607:         * <p><big><b>General notes</b></big>
0608:         *
0609:         * <ul>
0610:         *
0611:         *   <li>Calendars implementations are <em>proleptic</em>. For example,
0612:         *     even though the Gregorian calendar was not instituted until the
0613:         *     16th century, the <code>GregorianCalendar</code> class supports
0614:         *     dates before the historical onset of the calendar by extending the
0615:         *     calendar system backward in time. Similarly, the
0616:         *     <code>HebrewCalendar</code> extends backward before the start of
0617:         *     its epoch into zero and negative years. Subclasses do not throw
0618:         *     exceptions because a date precedes the historical start of a
0619:         *     calendar system. Instead, they implement
0620:         *     {@link #handleGetLimit} to return appropriate limits on
0621:         *     {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the
0622:         *     calendar is set to not be lenient, out-of-range field values will
0623:         *     trigger an exception.</li>
0624:         *
0625:         *   <li>Calendar system subclasses compute a <em>extended
0626:         *     year</em>. This differs from the {@link #YEAR} field in that
0627:         *     it ranges over all integer values, including zero and negative
0628:         *     values, and it encapsulates the information of the
0629:         *     {@link #YEAR} field and all larger fields.  Thus, for the
0630:         *     Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as
0631:         *     <code>ERA==AD ? YEAR : 1-YEAR</code>. Another example is the Mayan
0632:         *     long count, which has years (<code>KUN</code>) and nested cycles
0633:         *     of years (<code>KATUN</code> and <code>BAKTUN</code>). The Mayan
0634:         *     {@link #EXTENDED_YEAR} is computed as <code>TUN + 20 * (KATUN
0635:         *     + 20 * BAKTUN)</code>. The <code>Calendar</code> base class uses
0636:         *     the {@link #EXTENDED_YEAR} field to compute the week-related
0637:         *     fields.</li>
0638:         *
0639:         * </ul>
0640:         *
0641:         * @see          Date
0642:         * @see          GregorianCalendar
0643:         * @see          TimeZone
0644:         * @see          DateFormat
0645:         * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner
0646:         * @stable ICU 2.0
0647:         */
0648:        public abstract class Calendar implements  Serializable, Cloneable,
0649:                Comparable {
0650:
0651:            // Data flow in Calendar
0652:            // ---------------------
0653:
0654:            // The current time is represented in two ways by Calendar: as UTC
0655:            // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
0656:            // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
0657:            // millis from the fields, and vice versa.  The data needed to do this
0658:            // conversion is encapsulated by a TimeZone object owned by the Calendar.
0659:            // The data provided by the TimeZone object may also be overridden if the
0660:            // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
0661:            // keeps track of what information was most recently set by the caller, and
0662:            // uses that to compute any other information as needed.
0663:
0664:            // If the user sets the fields using set(), the data flow is as follows.
0665:            // This is implemented by the Calendar subclass's computeTime() method.
0666:            // During this process, certain fields may be ignored.  The disambiguation
0667:            // algorithm for resolving which fields to pay attention to is described
0668:            // above.
0669:
0670:            //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
0671:            //           |
0672:            //           | Using Calendar-specific algorithm
0673:            //           V
0674:            //   local standard millis
0675:            //           |
0676:            //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
0677:            //           V
0678:            //   UTC millis (in time data member)
0679:
0680:            // If the user sets the UTC millis using setTime(), the data flow is as
0681:            // follows.  This is implemented by the Calendar subclass's computeFields()
0682:            // method.
0683:
0684:            //   UTC millis (in time data member)
0685:            //           |
0686:            //           | Using TimeZone getOffset()
0687:            //           V
0688:            //   local standard millis
0689:            //           |
0690:            //           | Using Calendar-specific algorithm
0691:            //           V
0692:            //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
0693:
0694:            // In general, a round trip from fields, through local and UTC millis, and
0695:            // back out to fields is made when necessary.  This is implemented by the
0696:            // complete() method.  Resolving a partial set of fields into a UTC millis
0697:            // value allows all remaining fields to be generated from that value.  If
0698:            // the Calendar is lenient, the fields are also renormalized to standard
0699:            // ranges when they are regenerated.
0700:
0701:            /**
0702:             * Field number for <code>get</code> and <code>set</code> indicating the
0703:             * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
0704:             * value; see subclass documentation.
0705:             * @see GregorianCalendar#AD
0706:             * @see GregorianCalendar#BC
0707:             * @stable ICU 2.0
0708:             */
0709:            public final static int ERA = 0;
0710:
0711:            /**
0712:             * Field number for <code>get</code> and <code>set</code> indicating the
0713:             * year. This is a calendar-specific value; see subclass documentation.
0714:             * @stable ICU 2.0
0715:             */
0716:            public final static int YEAR = 1;
0717:
0718:            /**
0719:             * Field number for <code>get</code> and <code>set</code> indicating the
0720:             * month. This is a calendar-specific value. The first month of the year is
0721:             * <code>JANUARY</code>; the last depends on the number of months in a year.
0722:             * @see #JANUARY
0723:             * @see #FEBRUARY
0724:             * @see #MARCH
0725:             * @see #APRIL
0726:             * @see #MAY
0727:             * @see #JUNE
0728:             * @see #JULY
0729:             * @see #AUGUST
0730:             * @see #SEPTEMBER
0731:             * @see #OCTOBER
0732:             * @see #NOVEMBER
0733:             * @see #DECEMBER
0734:             * @see #UNDECIMBER
0735:             * @stable ICU 2.0
0736:             */
0737:            public final static int MONTH = 2;
0738:
0739:            /**
0740:             * Field number for <code>get</code> and <code>set</code> indicating the
0741:             * week number within the current year.  The first week of the year, as
0742:             * defined by <code>getFirstDayOfWeek()</code> and
0743:             * <code>getMinimalDaysInFirstWeek()</code>, has value 1.  Subclasses define
0744:             * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
0745:             * the year.
0746:             * @see #getFirstDayOfWeek
0747:             * @see #getMinimalDaysInFirstWeek
0748:             * @stable ICU 2.0
0749:             */
0750:            public final static int WEEK_OF_YEAR = 3;
0751:
0752:            /**
0753:             * Field number for <code>get</code> and <code>set</code> indicating the
0754:             * week number within the current month.  The first week of the month, as
0755:             * defined by <code>getFirstDayOfWeek()</code> and
0756:             * <code>getMinimalDaysInFirstWeek()</code>, has value 1.  Subclasses define
0757:             * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
0758:             * the month.
0759:             * @see #getFirstDayOfWeek
0760:             * @see #getMinimalDaysInFirstWeek
0761:             * @stable ICU 2.0
0762:             */
0763:            public final static int WEEK_OF_MONTH = 4;
0764:
0765:            /**
0766:             * Field number for <code>get</code> and <code>set</code> indicating the
0767:             * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
0768:             * The first day of the month has value 1.
0769:             * @see #DAY_OF_MONTH
0770:             * @stable ICU 2.0
0771:             */
0772:            public final static int DATE = 5;
0773:
0774:            /**
0775:             * Field number for <code>get</code> and <code>set</code> indicating the
0776:             * day of the month. This is a synonym for <code>DATE</code>.
0777:             * The first day of the month has value 1.
0778:             * @see #DATE
0779:             * @stable ICU 2.0
0780:             */
0781:            public final static int DAY_OF_MONTH = 5;
0782:
0783:            /**
0784:             * Field number for <code>get</code> and <code>set</code> indicating the day
0785:             * number within the current year.  The first day of the year has value 1.
0786:             * @stable ICU 2.0
0787:             */
0788:            public final static int DAY_OF_YEAR = 6;
0789:
0790:            /**
0791:             * Field number for <code>get</code> and <code>set</code> indicating the day
0792:             * of the week.  This field takes values <code>SUNDAY</code>,
0793:             * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
0794:             * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
0795:             * @see #SUNDAY
0796:             * @see #MONDAY
0797:             * @see #TUESDAY
0798:             * @see #WEDNESDAY
0799:             * @see #THURSDAY
0800:             * @see #FRIDAY
0801:             * @see #SATURDAY
0802:             * @stable ICU 2.0
0803:             */
0804:            public final static int DAY_OF_WEEK = 7;
0805:
0806:            /**
0807:             * Field number for <code>get</code> and <code>set</code> indicating the
0808:             * ordinal number of the day of the week within the current month. Together
0809:             * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
0810:             * within a month.  Unlike <code>WEEK_OF_MONTH</code> and
0811:             * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
0812:             * <code>getFirstDayOfWeek()</code> or
0813:             * <code>getMinimalDaysInFirstWeek()</code>.  <code>DAY_OF_MONTH 1</code>
0814:             * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
0815:             * 1</code>; <code>8</code> through <code>15</code> correspond to
0816:             * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
0817:             * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
0818:             * <code>DAY_OF_WEEK_IN_MONTH 1</code>.  Negative values count back from the
0819:             * end of the month, so the last Sunday of a month is specified as
0820:             * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>.  Because
0821:             * negative values count backward they will usually be aligned differently
0822:             * within the month than positive values.  For example, if a month has 31
0823:             * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
0824:             * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
0825:             * @see #DAY_OF_WEEK
0826:             * @see #WEEK_OF_MONTH
0827:             * @stable ICU 2.0
0828:             */
0829:            public final static int DAY_OF_WEEK_IN_MONTH = 8;
0830:
0831:            /**
0832:             * Field number for <code>get</code> and <code>set</code> indicating
0833:             * whether the <code>HOUR</code> is before or after noon.
0834:             * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
0835:             * @see #AM
0836:             * @see #PM
0837:             * @see #HOUR
0838:             * @stable ICU 2.0
0839:             */
0840:            public final static int AM_PM = 9;
0841:
0842:            /**
0843:             * Field number for <code>get</code> and <code>set</code> indicating the
0844:             * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour
0845:             * clock.
0846:             * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
0847:             * @see #AM_PM
0848:             * @see #HOUR_OF_DAY
0849:             * @stable ICU 2.0
0850:             */
0851:            public final static int HOUR = 10;
0852:
0853:            /**
0854:             * Field number for <code>get</code> and <code>set</code> indicating the
0855:             * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
0856:             * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
0857:             * @see #HOUR
0858:             * @stable ICU 2.0
0859:             */
0860:            public final static int HOUR_OF_DAY = 11;
0861:
0862:            /**
0863:             * Field number for <code>get</code> and <code>set</code> indicating the
0864:             * minute within the hour.
0865:             * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
0866:             * @stable ICU 2.0
0867:             */
0868:            public final static int MINUTE = 12;
0869:
0870:            /**
0871:             * Field number for <code>get</code> and <code>set</code> indicating the
0872:             * second within the minute.
0873:             * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
0874:             * @stable ICU 2.0
0875:             */
0876:            public final static int SECOND = 13;
0877:
0878:            /**
0879:             * Field number for <code>get</code> and <code>set</code> indicating the
0880:             * millisecond within the second.
0881:             * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
0882:             * @stable ICU 2.0
0883:             */
0884:            public final static int MILLISECOND = 14;
0885:
0886:            /**
0887:             * Field number for <code>get</code> and <code>set</code> indicating the
0888:             * raw offset from GMT in milliseconds.
0889:             * @stable ICU 2.0
0890:             */
0891:            public final static int ZONE_OFFSET = 15;
0892:
0893:            /**
0894:             * Field number for <code>get</code> and <code>set</code> indicating the
0895:             * daylight savings offset in milliseconds.
0896:             * @stable ICU 2.0
0897:             */
0898:            public final static int DST_OFFSET = 16;
0899:
0900:            /**
0901:             * Field number for <code>get()</code> and <code>set()</code>
0902:             * indicating the extended year corresponding to the
0903:             * <code>WEEK_OF_YEAR</code> field.  This may be one greater or less
0904:             * than the value of <code>EXTENDED_YEAR</code>.
0905:             * @stable ICU 2.0
0906:             */
0907:            public static final int YEAR_WOY = 17;
0908:
0909:            /**
0910:             * Field number for <code>get()</code> and <code>set()</code>
0911:             * indicating the localized day of week.  This will be a value from 1
0912:             * to 7 inclusive, with 1 being the localized first day of the week.
0913:             * @stable ICU 2.0
0914:             */
0915:            public static final int DOW_LOCAL = 18;
0916:
0917:            /**
0918:             * Field number for <code>get()</code> and <code>set()</code>
0919:             * indicating the extended year.  This is a single number designating
0920:             * the year of this calendar system, encompassing all supra-year
0921:             * fields.  For example, for the Julian calendar system, year numbers
0922:             * are positive, with an era of BCE or CE.  An extended year value for
0923:             * the Julian calendar system assigns positive values to CE years and
0924:             * negative values to BCE years, with 1 BCE being year 0.
0925:             * @stable ICU 2.0
0926:             */
0927:            public static final int EXTENDED_YEAR = 19;
0928:
0929:            /**
0930:             * Field number for <code>get()</code> and <code>set()</code>
0931:             * indicating the modified Julian day number.  This is different from
0932:             * the conventional Julian day number in two regards.  First, it
0933:             * demarcates days at local zone midnight, rather than noon GMT.
0934:             * Second, it is a local number; that is, it depends on the local time
0935:             * zone.  It can be thought of as a single number that encompasses all
0936:             * the date-related fields.
0937:             * @stable ICU 2.0
0938:             */
0939:            public static final int JULIAN_DAY = 20;
0940:
0941:            /**
0942:             * Field number for <code>get()</code> and <code>set()</code>
0943:             * indicating the milliseconds in the day.  This ranges from 0 to
0944:             * 23:59:59.999 (regardless of DST).  This field behaves
0945:             * <em>exactly</em> like a composite of all time-related fields, not
0946:             * including the zone fields.  As such, it also reflects
0947:             * discontinuities of those fields on DST transition days.  On a day of
0948:             * DST onset, it will jump forward.  On a day of DST cessation, it will
0949:             * jump backward.  This reflects the fact that is must be combined with
0950:             * the DST_OFFSET field to obtain a unique local time value.
0951:             * @stable ICU 2.0
0952:             */
0953:            public static final int MILLISECONDS_IN_DAY = 21;
0954:
0955:            /**
0956:             * The number of fields defined by this class.  Subclasses may define
0957:             * addition fields starting with this number.
0958:             * @stable ICU 2.0
0959:             */
0960:            protected static final int BASE_FIELD_COUNT = 22;
0961:
0962:            /**
0963:             * The maximum number of fields possible.  Subclasses must not define
0964:             * more total fields than this number.
0965:             * @stable ICU 2.0
0966:             */
0967:            protected static final int MAX_FIELD_COUNT = 32;
0968:
0969:            /**
0970:             * Value of the <code>DAY_OF_WEEK</code> field indicating
0971:             * Sunday.
0972:             * @stable ICU 2.0
0973:             */
0974:            public final static int SUNDAY = 1;
0975:
0976:            /**
0977:             * Value of the <code>DAY_OF_WEEK</code> field indicating
0978:             * Monday.
0979:             * @stable ICU 2.0
0980:             */
0981:            public final static int MONDAY = 2;
0982:
0983:            /**
0984:             * Value of the <code>DAY_OF_WEEK</code> field indicating
0985:             * Tuesday.
0986:             * @stable ICU 2.0
0987:             */
0988:            public final static int TUESDAY = 3;
0989:
0990:            /**
0991:             * Value of the <code>DAY_OF_WEEK</code> field indicating
0992:             * Wednesday.
0993:             * @stable ICU 2.0
0994:             */
0995:            public final static int WEDNESDAY = 4;
0996:
0997:            /**
0998:             * Value of the <code>DAY_OF_WEEK</code> field indicating
0999:             * Thursday.
1000:             * @stable ICU 2.0
1001:             */
1002:            public final static int THURSDAY = 5;
1003:
1004:            /**
1005:             * Value of the <code>DAY_OF_WEEK</code> field indicating
1006:             * Friday.
1007:             * @stable ICU 2.0
1008:             */
1009:            public final static int FRIDAY = 6;
1010:
1011:            /**
1012:             * Value of the <code>DAY_OF_WEEK</code> field indicating
1013:             * Saturday.
1014:             * @stable ICU 2.0
1015:             */
1016:            public final static int SATURDAY = 7;
1017:
1018:            /**
1019:             * Value of the <code>MONTH</code> field indicating the
1020:             * first month of the year.
1021:             * @stable ICU 2.0
1022:             */
1023:            public final static int JANUARY = 0;
1024:
1025:            /**
1026:             * Value of the <code>MONTH</code> field indicating the
1027:             * second month of the year.
1028:             * @stable ICU 2.0
1029:             */
1030:            public final static int FEBRUARY = 1;
1031:
1032:            /**
1033:             * Value of the <code>MONTH</code> field indicating the
1034:             * third month of the year.
1035:             * @stable ICU 2.0
1036:             */
1037:            public final static int MARCH = 2;
1038:
1039:            /**
1040:             * Value of the <code>MONTH</code> field indicating the
1041:             * fourth month of the year.
1042:             * @stable ICU 2.0
1043:             */
1044:            public final static int APRIL = 3;
1045:
1046:            /**
1047:             * Value of the <code>MONTH</code> field indicating the
1048:             * fifth month of the year.
1049:             * @stable ICU 2.0
1050:             */
1051:            public final static int MAY = 4;
1052:
1053:            /**
1054:             * Value of the <code>MONTH</code> field indicating the
1055:             * sixth month of the year.
1056:             * @stable ICU 2.0
1057:             */
1058:            public final static int JUNE = 5;
1059:
1060:            /**
1061:             * Value of the <code>MONTH</code> field indicating the
1062:             * seventh month of the year.
1063:             * @stable ICU 2.0
1064:             */
1065:            public final static int JULY = 6;
1066:
1067:            /**
1068:             * Value of the <code>MONTH</code> field indicating the
1069:             * eighth month of the year.
1070:             * @stable ICU 2.0
1071:             */
1072:            public final static int AUGUST = 7;
1073:
1074:            /**
1075:             * Value of the <code>MONTH</code> field indicating the
1076:             * ninth month of the year.
1077:             * @stable ICU 2.0
1078:             */
1079:            public final static int SEPTEMBER = 8;
1080:
1081:            /**
1082:             * Value of the <code>MONTH</code> field indicating the
1083:             * tenth month of the year.
1084:             * @stable ICU 2.0
1085:             */
1086:            public final static int OCTOBER = 9;
1087:
1088:            /**
1089:             * Value of the <code>MONTH</code> field indicating the
1090:             * eleventh month of the year.
1091:             * @stable ICU 2.0
1092:             */
1093:            public final static int NOVEMBER = 10;
1094:
1095:            /**
1096:             * Value of the <code>MONTH</code> field indicating the
1097:             * twelfth month of the year.
1098:             * @stable ICU 2.0
1099:             */
1100:            public final static int DECEMBER = 11;
1101:
1102:            /**
1103:             * Value of the <code>MONTH</code> field indicating the
1104:             * thirteenth month of the year. Although <code>GregorianCalendar</code>
1105:             * does not use this value, lunar calendars do.
1106:             * @stable ICU 2.0
1107:             */
1108:            public final static int UNDECIMBER = 12;
1109:
1110:            /**
1111:             * Value of the <code>AM_PM</code> field indicating the
1112:             * period of the day from midnight to just before noon.
1113:             * @stable ICU 2.0
1114:             */
1115:            public final static int AM = 0;
1116:
1117:            /**
1118:             * Value of the <code>AM_PM</code> field indicating the
1119:             * period of the day from noon to just before midnight.
1120:             * @stable ICU 2.0
1121:             */
1122:            public final static int PM = 1;
1123:
1124:            /**
1125:             * Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
1126:             * weekday.
1127:             * @see #WEEKEND
1128:             * @see #WEEKEND_ONSET
1129:             * @see #WEEKEND_CEASE
1130:             * @see #getDayOfWeekType
1131:             * @stable ICU 2.0
1132:             */
1133:            public static final int WEEKDAY = 0;
1134:
1135:            /**
1136:             * Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
1137:             * weekend day.
1138:             * @see #WEEKDAY
1139:             * @see #WEEKEND_ONSET
1140:             * @see #WEEKEND_CEASE
1141:             * @see #getDayOfWeekType
1142:             * @stable ICU 2.0
1143:             */
1144:            public static final int WEEKEND = 1;
1145:
1146:            /**
1147:             * Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
1148:             * day that starts as a weekday and transitions to the weekend.
1149:             * Call getWeekendTransition() to get the point of transition.
1150:             * @see #WEEKDAY
1151:             * @see #WEEKEND
1152:             * @see #WEEKEND_CEASE
1153:             * @see #getDayOfWeekType
1154:             * @stable ICU 2.0
1155:             */
1156:            public static final int WEEKEND_ONSET = 2;
1157:
1158:            /**
1159:             * Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
1160:             * day that starts as the weekend and transitions to a weekday.
1161:             * Call getWeekendTransition() to get the point of transition.
1162:             * @see #WEEKDAY
1163:             * @see #WEEKEND
1164:             * @see #WEEKEND_ONSET
1165:             * @see #getDayOfWeekType
1166:             * @stable ICU 2.0
1167:             */
1168:            public static final int WEEKEND_CEASE = 3;
1169:
1170:            /**
1171:             * The number of milliseconds in one second.
1172:             * @stable ICU 2.0
1173:             */
1174:            protected static final int ONE_SECOND = 1000;
1175:
1176:            /**
1177:             * The number of milliseconds in one minute.
1178:             * @stable ICU 2.0
1179:             */
1180:            protected static final int ONE_MINUTE = 60 * ONE_SECOND;
1181:
1182:            /**
1183:             * The number of milliseconds in one hour.
1184:             * @stable ICU 2.0
1185:             */
1186:            protected static final int ONE_HOUR = 60 * ONE_MINUTE;
1187:
1188:            /**
1189:             * The number of milliseconds in one day.  Although ONE_DAY and
1190:             * ONE_WEEK can fit into ints, they must be longs in order to prevent
1191:             * arithmetic overflow when performing (bug 4173516).
1192:             * @stable ICU 2.0
1193:             */
1194:            protected static final long ONE_DAY = 24 * ONE_HOUR;
1195:
1196:            /**
1197:             * The number of milliseconds in one week.  Although ONE_DAY and
1198:             * ONE_WEEK can fit into ints, they must be longs in order to prevent
1199:             * arithmetic overflow when performing (bug 4173516).
1200:             * @stable ICU 2.0
1201:             */
1202:            protected static final long ONE_WEEK = 7 * ONE_DAY;
1203:
1204:            /**
1205:             * The Julian day of the Gregorian epoch, that is, January 1, 1 on the
1206:             * Gregorian calendar.
1207:             * @stable ICU 2.0
1208:             */
1209:            protected static final int JAN_1_1_JULIAN_DAY = 1721426;
1210:
1211:            /**
1212:             * The Julian day of the epoch, that is, January 1, 1970 on the
1213:             * Gregorian calendar.
1214:             * @stable ICU 2.0
1215:             */
1216:            protected static final int EPOCH_JULIAN_DAY = 2440588;
1217:
1218:            /**
1219:             * The minimum supported Julian day.  This value is equivalent to
1220:             * <code>MIN_MILLIS</code> and <code>MIN_DATE</code>.
1221:             * @see #JULIAN_DAY
1222:             * @stable ICU 2.0
1223:             */
1224:            protected static final int MIN_JULIAN = -0x7F000000;
1225:
1226:            /**
1227:             * The minimum supported epoch milliseconds.  This value is equivalent
1228:             * to <code>MIN_JULIAN</code> and <code>MIN_DATE</code>.
1229:             * @stable ICU 2.0
1230:             */
1231:            protected static final long MIN_MILLIS = -184303902528000000L;
1232:
1233:            // Get around bug in jikes 1.12 for now.  Later, use:
1234:            //protected static final long MIN_MILLIS = (MIN_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY;
1235:
1236:            /**
1237:             * The minimum supported <code>Date</code>.  This value is equivalent
1238:             * to <code>MIN_JULIAN</code> and <code>MIN_MILLIS</code>.
1239:             * @stable ICU 2.0
1240:             */
1241:            protected static final Date MIN_DATE = new Date(MIN_MILLIS);
1242:
1243:            /**
1244:             * The maximum supported Julian day.  This value is equivalent to
1245:             * <code>MAX_MILLIS</code> and <code>MAX_DATE</code>.
1246:             * @see #JULIAN_DAY
1247:             * @stable ICU 2.0
1248:             */
1249:            protected static final int MAX_JULIAN = +0x7F000000;
1250:
1251:            /**
1252:             * The maximum supported epoch milliseconds.  This value is equivalent
1253:             * to <code>MAX_JULIAN</code> and <code>MAX_DATE</code>.
1254:             * @stable ICU 2.0
1255:             */
1256:            protected static final long MAX_MILLIS = (MAX_JULIAN - EPOCH_JULIAN_DAY)
1257:                    * ONE_DAY;
1258:
1259:            /**
1260:             * The maximum supported <code>Date</code>.  This value is equivalent
1261:             * to <code>MAX_JULIAN</code> and <code>MAX_MILLIS</code>.
1262:             * @stable ICU 2.0
1263:             */
1264:            protected static final Date MAX_DATE = new Date(MAX_MILLIS);
1265:
1266:            // Internal notes:
1267:            // Calendar contains two kinds of time representations: current "time" in
1268:            // milliseconds, and a set of time "fields" representing the current time.
1269:            // The two representations are usually in sync, but can get out of sync
1270:            // as follows.
1271:            // 1. Initially, no fields are set, and the time is invalid.
1272:            // 2. If the time is set, all fields are computed and in sync.
1273:            // 3. If a single field is set, the time is invalid.
1274:            // Recomputation of the time and fields happens when the object needs
1275:            // to return a result to the user, or use a result for a computation.
1276:
1277:            /**
1278:             * The field values for the currently set time for this calendar.
1279:             * This is an array of at least <code>BASE_FIELD_COUNT</code> integers.
1280:             * @see #handleCreateFields
1281:             * @serial
1282:             */
1283:            private transient int fields[];
1284:
1285:            /**
1286:             * Pseudo-time-stamps which specify when each field was set. There
1287:             * are two special values, UNSET and INTERNALLY_SET. Values from
1288:             * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
1289:             */
1290:            private transient int stamp[];
1291:
1292:            /**
1293:             * The currently set time for this calendar, expressed in milliseconds after
1294:             * January 1, 1970, 0:00:00 GMT.
1295:             * @see <tt>isTimeSet</tt>
1296:             * @serial
1297:             */
1298:            private long time;
1299:
1300:            /**
1301:             * True if then the value of <code>time</code> is valid.
1302:             * The time is made invalid by a change to an item of <code>field[]</code>.
1303:             * @see #time
1304:             * @serial
1305:             */
1306:            private transient boolean isTimeSet;
1307:
1308:            /**
1309:             * True if <code>fields[]</code> are in sync with the currently set time.
1310:             * If false, then the next attempt to get the value of a field will
1311:             * force a recomputation of all fields from the current value of
1312:             * <code>time</code>.
1313:             * @serial
1314:             */
1315:            private transient boolean areFieldsSet;
1316:
1317:            /**
1318:             * True if all fields have been set.  This is only false in a few
1319:             * situations: In a newly created, partially constructed object.  After
1320:             * a call to clear().  In an object just read from a stream using
1321:             * readObject().  Once computeFields() has been called this is set to
1322:             * true and stays true until one of the above situations recurs.
1323:             * @serial
1324:             */
1325:            private transient boolean areAllFieldsSet;
1326:
1327:            /**
1328:             * True if all fields have been virtually set, but have not yet been
1329:             * computed.  This occurs only in setTimeInMillis().  A calendar set
1330:             * to this state will compute all fields from the time if it becomes
1331:             * necessary, but otherwise will delay such computation.
1332:             */
1333:            private transient boolean areFieldsVirtuallySet;
1334:
1335:            /**
1336:             * True if this calendar allows out-of-range field values during computation
1337:             * of <code>time</code> from <code>fields[]</code>.
1338:             * @see #setLenient
1339:             * @serial
1340:             */
1341:            private boolean lenient = true;
1342:
1343:            /**
1344:             * The <code>TimeZone</code> used by this calendar. </code>Calendar</code>
1345:             * uses the time zone data to translate between locale and GMT time.
1346:             * @serial
1347:             */
1348:            private TimeZone zone;
1349:
1350:            /**
1351:             * The first day of the week, with possible values <code>SUNDAY</code>,
1352:             * <code>MONDAY</code>, etc.  This is a locale-dependent value.
1353:             * @serial
1354:             */
1355:            private int firstDayOfWeek;
1356:
1357:            /**
1358:             * The number of days required for the first week in a month or year,
1359:             * with possible values from 1 to 7.  This is a locale-dependent value.
1360:             * @serial
1361:             */
1362:            private int minimalDaysInFirstWeek;
1363:
1364:            /**
1365:             * First day of the weekend in this calendar's locale.  Must be in
1366:             * the range SUNDAY...SATURDAY (1..7).  The weekend starts at
1367:             * weekendOnsetMillis milliseconds after midnight on that day of
1368:             * the week.  This value is taken from locale resource data.
1369:             */
1370:            private int weekendOnset;
1371:
1372:            /**
1373:             * Milliseconds after midnight at which the weekend starts on the
1374:             * day of the week weekendOnset.  Times that are greater than or
1375:             * equal to weekendOnsetMillis are considered part of the weekend.
1376:             * Must be in the range 0..24*60*60*1000-1.  This value is taken
1377:             * from locale resource data.
1378:             */
1379:            private int weekendOnsetMillis;
1380:
1381:            /**
1382:             * Day of the week when the weekend stops in this calendar's
1383:             * locale.  Must be in the range SUNDAY...SATURDAY (1..7).  The
1384:             * weekend stops at weekendCeaseMillis milliseconds after midnight
1385:             * on that day of the week.  This value is taken from locale
1386:             * resource data.
1387:             */
1388:            private int weekendCease;
1389:
1390:            /**
1391:             * Milliseconds after midnight at which the weekend stops on the
1392:             * day of the week weekendCease.  Times that are greater than or
1393:             * equal to weekendCeaseMillis are considered not to be the
1394:             * weekend.  Must be in the range 0..24*60*60*1000-1.  This value
1395:             * is taken from locale resource data.
1396:             */
1397:            private int weekendCeaseMillis;
1398:
1399:            /**
1400:             * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
1401:             * of a Locale.
1402:             */
1403:            private static Hashtable cachedLocaleData = new Hashtable(3);
1404:
1405:            /**
1406:             * Value of the time stamp <code>stamp[]</code> indicating that
1407:             * a field has not been set since the last call to <code>clear()</code>.
1408:             * @see #INTERNALLY_SET
1409:             * @see #MINIMUM_USER_STAMP
1410:             * @stable ICU 2.0
1411:             */
1412:            protected static final int UNSET = 0;
1413:
1414:            /**
1415:             * Value of the time stamp <code>stamp[]</code> indicating that a field
1416:             * has been set via computations from the time or from other fields.
1417:             * @see #UNSET
1418:             * @see #MINIMUM_USER_STAMP
1419:             * @stable ICU 2.0
1420:             */
1421:            protected static final int INTERNALLY_SET = 1;
1422:
1423:            /**
1424:             * If the time stamp <code>stamp[]</code> has a value greater than or
1425:             * equal to <code>MINIMUM_USER_SET</code> then it has been set by the
1426:             * user via a call to <code>set()</code>.
1427:             * @see #UNSET
1428:             * @see #INTERNALLY_SET
1429:             * @stable ICU 2.0
1430:             */
1431:            protected static final int MINIMUM_USER_STAMP = 2;
1432:
1433:            /**
1434:             * The next available value for <code>stamp[]</code>, an internal array.
1435:             * This actually should not be written out to the stream, and will probably
1436:             * be removed from the stream in the near future.  In the meantime,
1437:             * a value of <code>MINIMUM_USER_STAMP</code> should be used.
1438:             * @serial
1439:             */
1440:            private transient int nextStamp = MINIMUM_USER_STAMP;
1441:
1442:            // the internal serial version which says which version was written
1443:            // - 0 (default) for version up to JDK 1.1.5
1444:            // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
1445:            //     as well as compatible values for other fields.  This is a
1446:            //     transitional format.
1447:            // - 2 (not implemented yet) a future version, in which fields[],
1448:            //     areFieldsSet, and isTimeSet become transient, and isSet[] is
1449:            //     removed. In JDK 1.1.6 we write a format compatible with version 2.
1450:            // static final int        currentSerialVersion = 1;
1451:
1452:            /**
1453:             * The version of the serialized data on the stream.  Possible values:
1454:             * <dl>
1455:             * <dt><b>0</b> or not present on stream</dt>
1456:             * <dd>
1457:             * JDK 1.1.5 or earlier.
1458:             * </dd>
1459:             * <dt><b>1</b></dt>
1460:             * <dd>
1461:             * JDK 1.1.6 or later.  Writes a correct 'time' value
1462:             * as well as compatible values for other fields.  This is a
1463:             * transitional format.
1464:             * </dd>
1465:             * </dl>
1466:             * When streaming out this class, the most recent format
1467:             * and the highest allowable <code>serialVersionOnStream</code>
1468:             * is written.
1469:             * @serial
1470:             * @since JDK1.1.6
1471:             */
1472:            // private int             serialVersionOnStream = currentSerialVersion;
1473:            // Proclaim serialization compatibility with JDK 1.1
1474:            // static final long       serialVersionUID = -1807547505821590642L;
1475:            // haven't been compatible for awhile, no longer try
1476:            // jdk1.4.2 serialver
1477:            private static final long serialVersionUID = 6222646104888790989L;
1478:
1479:            /**
1480:             * Bitmask for internalSet() defining which fields may legally be set
1481:             * by subclasses.  Any attempt to set a field not in this bitmask
1482:             * results in an exception, because such fields must be set by the base
1483:             * class.
1484:             */
1485:            private transient int internalSetMask;
1486:
1487:            /**
1488:             * The Gregorian year, as computed by computeGregorianFields() and
1489:             * returned by getGregorianYear().
1490:             */
1491:            private transient int gregorianYear;
1492:
1493:            /**
1494:             * The Gregorian month, as computed by computeGregorianFields() and
1495:             * returned by getGregorianMonth().
1496:             */
1497:            private transient int gregorianMonth;
1498:
1499:            /**
1500:             * The Gregorian day of the year, as computed by
1501:             * computeGregorianFields() and returned by getGregorianDayOfYear().
1502:             */
1503:            private transient int gregorianDayOfYear;
1504:
1505:            /**
1506:             * The Gregorian day of the month, as computed by
1507:             * computeGregorianFields() and returned by getGregorianDayOfMonth().
1508:             */
1509:            private transient int gregorianDayOfMonth;
1510:
1511:            /**
1512:             * Constructs a Calendar with the default time zone
1513:             * and locale.
1514:             * @see     TimeZone#getDefault
1515:             * @stable ICU 2.0
1516:             */
1517:            protected Calendar() {
1518:                this (TimeZone.getDefault(), ULocale.getDefault());
1519:            }
1520:
1521:            /**
1522:             * Constructs a calendar with the specified time zone and locale.
1523:             * @param zone the time zone to use
1524:             * @param aLocale the locale for the week data
1525:             * @stable ICU 2.0
1526:             */
1527:            protected Calendar(TimeZone zone, Locale aLocale) {
1528:                this (zone, ULocale.forLocale(aLocale));
1529:            }
1530:
1531:            /**
1532:             * Constructs a calendar with the specified time zone and locale.
1533:             * @param zone the time zone to use
1534:             * @param locale the ulocale for the week data
1535:             * @draft ICU 3.2
1536:             * @provisional This API might change or be removed in a future release.
1537:             */
1538:            protected Calendar(TimeZone zone, ULocale locale) {
1539:                this .zone = zone;
1540:                setWeekData(locale);
1541:                initInternal();
1542:            }
1543:
1544:            private void initInternal() {
1545:                // Allocate fields through the framework method.  Subclasses
1546:                // may override this to define additional fields.
1547:                fields = handleCreateFields();
1548:                ///CLOVER:OFF
1549:                // todo: fix, difficult to test without subclassing
1550:                if (fields == null || fields.length < BASE_FIELD_COUNT
1551:                        || fields.length > MAX_FIELD_COUNT) {
1552:                    throw new IllegalStateException("Invalid fields[]");
1553:                }
1554:                ///CLOVER:ON
1555:                stamp = new int[fields.length];
1556:                int mask = (1 << ERA) | (1 << YEAR) | (1 << MONTH)
1557:                        | (1 << DAY_OF_MONTH) | (1 << DAY_OF_YEAR)
1558:                        | (1 << EXTENDED_YEAR);
1559:                for (int i = BASE_FIELD_COUNT; i < fields.length; ++i) {
1560:                    mask |= (1 << i);
1561:                }
1562:                internalSetMask = mask;
1563:            }
1564:
1565:            /**
1566:             * Gets a calendar using the default time zone and locale.
1567:             * @return a Calendar.
1568:             * @stable ICU 2.0
1569:             */
1570:            public static synchronized Calendar getInstance() {
1571:                return getInstance(TimeZone.getDefault(), ULocale.getDefault(),
1572:                        null);
1573:            }
1574:
1575:            /**
1576:             * Gets a calendar using the specified time zone and default locale.
1577:             * @param zone the time zone to use
1578:             * @return a Calendar.
1579:             * @stable ICU 2.0
1580:             */
1581:            public static synchronized Calendar getInstance(TimeZone zone) {
1582:                return getInstance(zone, ULocale.getDefault(), null);
1583:            }
1584:
1585:            /**
1586:             * Gets a calendar using the default time zone and specified locale.
1587:             * @param aLocale the locale for the week data
1588:             * @return a Calendar.
1589:             * @stable ICU 2.0
1590:             */
1591:            public static synchronized Calendar getInstance(Locale aLocale) {
1592:                return getInstance(TimeZone.getDefault(), ULocale
1593:                        .forLocale(aLocale), null);
1594:            }
1595:
1596:            /**
1597:             * Gets a calendar using the default time zone and specified locale.  
1598:             * @param locale the ulocale for the week data
1599:             * @return a Calendar.
1600:             * @draft ICU 3.2
1601:             * @provisional This API might change or be removed in a future release.
1602:             */
1603:            public static synchronized Calendar getInstance(ULocale locale) {
1604:                return getInstance(TimeZone.getDefault(), locale, null);
1605:            }
1606:
1607:            /**
1608:             * Gets a calendar with the specified time zone and locale.
1609:             * @param zone the time zone to use
1610:             * @param aLocale the locale for the week data
1611:             * @return a Calendar.
1612:             * @stable ICU 2.0
1613:             */
1614:            public static synchronized Calendar getInstance(TimeZone zone,
1615:                    Locale aLocale) {
1616:                return getInstance(zone, ULocale.forLocale(aLocale), null);
1617:            }
1618:
1619:            /**
1620:             * Gets a calendar with the specified time zone and locale.
1621:             * @param zone the time zone to use
1622:             * @param locale the ulocale for the week data
1623:             * @return a Calendar.
1624:             * @draft ICU 3.2
1625:             * @provisional This API might change or be removed in a future release.
1626:             */
1627:            public static synchronized Calendar getInstance(TimeZone zone,
1628:                    ULocale locale) {
1629:                return getInstance(zone, locale, null);
1630:            }
1631:
1632:            // ==== Factory Stuff ====
1633:            ///CLOVER:OFF
1634:            /**
1635:             * Return a calendar of for the TimeZone and locale.  If factoryName is
1636:             * not null, looks in the collection of CalendarFactories for a match
1637:             * and uses that factory to instantiate the calendar.  Otherwise, it
1638:             * uses the default factory that has been registered for the locale.
1639:             * @prototype
1640:             */
1641:            /* public */static synchronized Calendar getInstance(
1642:                    TimeZone zone, ULocale locale, String factoryName) {
1643:                CalendarFactory factory = null;
1644:                if (factoryName != null) {
1645:                    factory = (CalendarFactory) getFactoryMap()
1646:                            .get(factoryName);
1647:                }
1648:
1649:                ULocale[] actualReturn = new ULocale[1];
1650:                if (factory == null && service != null) {
1651:                    factory = (CalendarFactory) service.get(locale,
1652:                            actualReturn);
1653:                }
1654:
1655:                if (factory == null) {
1656:                    int calType = getCalendarType(locale);
1657:                    switch (calType) {
1658:                    case BUDDHIST:
1659:                        return new BuddhistCalendar(zone, locale);
1660:                    case CHINESE:
1661:                        return new ChineseCalendar(zone, locale);
1662:                    case COPTIC:
1663:                        return new CopticCalendar(zone, locale);
1664:                    case ETHIOPIC:
1665:                        return new EthiopicCalendar(zone, locale);
1666:                    case GREGORIAN:
1667:                        return new GregorianCalendar(zone, locale);
1668:                    case HEBREW:
1669:                        return new HebrewCalendar(zone, locale);
1670:                    case ISLAMIC:
1671:                    case ISLAMIC_CIVIL: {
1672:                        IslamicCalendar result = new IslamicCalendar(zone,
1673:                                locale);
1674:                        result.setCivil(calType == ISLAMIC_CIVIL);
1675:                        return result;
1676:                    }
1677:                    case JAPANESE:
1678:                        return new JapaneseCalendar(zone, locale);
1679:                    default:
1680:                        throw new IllegalStateException();
1681:                    }
1682:                } else {
1683:                    Calendar result = factory.create(zone, locale);
1684:
1685:                    // TODO: get the actual/valid locale properly
1686:                    ULocale uloc = actualReturn[0];
1687:                    result.setLocale(uloc, uloc);
1688:
1689:                    return result;
1690:                }
1691:            }
1692:
1693:            private static final int BUDDHIST = 0;
1694:            private static final int CHINESE = 1;
1695:            private static final int COPTIC = 2;
1696:            private static final int ETHIOPIC = 3;
1697:            private static final int GREGORIAN = 4;
1698:            private static final int HEBREW = 5;
1699:            private static final int ISLAMIC = 6;
1700:            private static final int ISLAMIC_CIVIL = 7;
1701:            private static final int JAPANESE = 8;
1702:
1703:            private static final String[] calTypes = { "buddhist", "chinese",
1704:                    "coptic", "ethiopic", "gregorian", "hebrew", "islamic",
1705:                    "islamic-civil", "japanese", };
1706:
1707:            private static int getCalendarType(ULocale l) {
1708:                String s = l.getKeywordValue("calendar");
1709:                if (s == null) {
1710:                    l = ICUResourceBundle.getFunctionalEquivalent(
1711:                            ICUResourceBundle.ICU_BASE_NAME, "calendar",
1712:                            "calendar", l, null);
1713:                    s = l.getKeywordValue("calendar");
1714:                }
1715:                return getCalendarType(s);
1716:            }
1717:
1718:            private static int getCalendarType(String s) {
1719:                if (s != null) {
1720:                    s = s.toLowerCase();
1721:                    for (int i = 0; i < calTypes.length; ++i) {
1722:                        if (s.equals(calTypes[i])) {
1723:                            return i;
1724:                        }
1725:                    }
1726:                }
1727:                return GREGORIAN;
1728:            }
1729:
1730:            ///CLOVER:ON
1731:            /**
1732:             * Gets the list of locales for which Calendars are installed.
1733:             * @return the list of locales for which Calendars are installed.
1734:             * @stable ICU 2.0
1735:             */
1736:            public static Locale[] getAvailableLocales() {
1737:                return service == null ? ICUResourceBundle
1738:                        .getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME)
1739:                        : service.getAvailableLocales();
1740:            }
1741:
1742:            /**
1743:             * Gets the list of locales for which Calendars are installed.
1744:             * @return the list of locales for which Calendars are installed.
1745:             * @draft ICU 3.2
1746:             * @provisional This API might change or be removed in a future release.
1747:             */
1748:            public static ULocale[] getAvailableULocales() {
1749:                return service == null ? ICUResourceBundle
1750:                        .getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME)
1751:                        : service.getAvailableULocales();
1752:            }
1753:
1754:            ///CLOVER:OFF
1755:            private static Map factoryMap;
1756:
1757:            private static Map getFactoryMap() {
1758:                if (factoryMap == null) {
1759:                    Map m = new HashMap(5);
1760:                    /*
1761:                    addFactory(m, BuddhistCalendar.factory());
1762:                    addFactory(m, ChineseCalendar.factory());
1763:                    addFactory(m, GregorianCalendar.factory());
1764:                    addFactory(m, HebrewCalendar.factory());
1765:                    addFactory(m, IslamicCalendar.factory());
1766:                    addFactory(m, JapaneseCalendar.factory());
1767:                     */
1768:                    factoryMap = m;
1769:                }
1770:                return factoryMap;
1771:            }
1772:
1773:            // Never used -- why is this here? Alan 2003-05
1774:            //    private static void addFactory(Map m, CalendarFactory f) {
1775:            //        m.put(f.factoryName(), f);
1776:            //    }
1777:
1778:            /**
1779:             * Return a set of all the registered calendar factory names.
1780:             * @prototype
1781:             */
1782:            /* public */static Set getCalendarFactoryNames() {
1783:                return Collections.unmodifiableSet(getFactoryMap().keySet());
1784:            }
1785:
1786:            /**
1787:             * Register a new CalendarFactory.  getInstance(TimeZone, ULocale, String) will
1788:             * try to locate a registered factories matching the factoryName.  Only registered
1789:             * factories will be found.
1790:             * @prototype
1791:             */
1792:            private static void registerFactory(CalendarFactory factory) {
1793:                if (factory == null) {
1794:                    throw new IllegalArgumentException(
1795:                            "Factory must not be null");
1796:                }
1797:                getFactoryMap().put(factory.factoryName(), factory);
1798:            }
1799:
1800:            /**
1801:             * Convenience override of register(CalendarFactory, ULocale, boolean);
1802:             * @prototype
1803:             */
1804:            /* public */static Object register(CalendarFactory factory,
1805:                    ULocale locale) {
1806:                return register(factory, locale, true);
1807:            }
1808:
1809:            /**
1810:             * Registers a default CalendarFactory for the provided locale.
1811:             * If the factory has not already been registered with
1812:             * registerFactory, it will be.
1813:             * @prototype
1814:             */
1815:            /* public */static Object register(CalendarFactory factory,
1816:                    ULocale locale, boolean visible) {
1817:                if (factory == null) {
1818:                    throw new IllegalArgumentException(
1819:                            "calendar must not be null");
1820:                }
1821:                registerFactory(factory);
1822:                return getService().registerObject(factory, locale, visible);
1823:            }
1824:
1825:            /**
1826:             * Unregister the CalendarFactory associated with this key
1827:             * (obtained from register).
1828:             * @prototype
1829:             */
1830:            /* public */static boolean unregister(Object registryKey) {
1831:                return service == null ? false : service
1832:                        .unregisterFactory((Factory) registryKey);
1833:            }
1834:
1835:            private static ICULocaleService service = null;
1836:
1837:            private static ICULocaleService getService() {
1838:                synchronized (Calendar.class) {
1839:                    if (service == null) {
1840:                        service = new ICULocaleService("Calendar");
1841:                    }
1842:                }
1843:                return service;
1844:            }
1845:
1846:            ///CLOVER:ON
1847:            // ==== End of factory Stuff ====
1848:
1849:            /**
1850:             * Gets this Calendar's current time.
1851:             * @return the current time.
1852:             * @stable ICU 2.0
1853:             */
1854:            public final Date getTime() {
1855:                return new Date(getTimeInMillis());
1856:            }
1857:
1858:            /**
1859:             * Sets this Calendar's current time with the given Date.
1860:             * <p>
1861:             * Note: Calling <code>setTime()</code> with
1862:             * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
1863:             * may yield incorrect field values from <code>get()</code>.
1864:             * @param date the given Date.
1865:             * @stable ICU 2.0
1866:             */
1867:            public final void setTime(Date date) {
1868:                setTimeInMillis(date.getTime());
1869:            }
1870:
1871:            /**
1872:             * Gets this Calendar's current time as a long.
1873:             * @return the current time as UTC milliseconds from the epoch.
1874:             * @stable ICU 2.0
1875:             */
1876:            public long getTimeInMillis() {
1877:                if (!isTimeSet)
1878:                    updateTime();
1879:                return time;
1880:            }
1881:
1882:            /**
1883:             * Sets this Calendar's current time from the given long value.
1884:             * @param millis the new time in UTC milliseconds from the epoch.
1885:             * @stable ICU 2.0
1886:             */
1887:            public void setTimeInMillis(long millis) {
1888:                if (millis > MAX_MILLIS) {
1889:                    millis = MAX_MILLIS;
1890:                } else if (millis < MIN_MILLIS) {
1891:                    millis = MIN_MILLIS;
1892:                }
1893:                time = millis;
1894:                areFieldsSet = areAllFieldsSet = false;
1895:                isTimeSet = areFieldsVirtuallySet = true;
1896:            }
1897:
1898:            /**
1899:             * Gets the value for a given time field.
1900:             * @param field the given time field.
1901:             * @return the value for the given time field.
1902:             * @stable ICU 2.0
1903:             */
1904:            public final int get(int field) {
1905:                complete();
1906:                return fields[field];
1907:            }
1908:
1909:            /**
1910:             * Gets the value for a given time field.  This is an internal method
1911:             * for subclasses that does <em>not</em> trigger any calculations.
1912:             * @param field the given time field.
1913:             * @return the value for the given time field.
1914:             * @stable ICU 2.0
1915:             */
1916:            protected final int internalGet(int field) {
1917:                return fields[field];
1918:            }
1919:
1920:            /**
1921:             * Get the value for a given time field, or return the given default
1922:             * value if the field is not set.  This is an internal method for
1923:             * subclasses that does <em>not</em> trigger any calculations.
1924:             * @param field the given time field.
1925:             * @param defaultValue value to return if field is not set
1926:             * @return the value for the given time field of defaultValue if the
1927:             * field is unset
1928:             * @stable ICU 2.0
1929:             */
1930:            protected final int internalGet(int field, int defaultValue) {
1931:                return (stamp[field] > UNSET) ? fields[field] : defaultValue;
1932:            }
1933:
1934:            /**
1935:             * Sets the time field with the given value.
1936:             * @param field the given time field.
1937:             * @param value the value to be set for the given time field.
1938:             * @stable ICU 2.0
1939:             */
1940:            public final void set(int field, int value) {
1941:                if (areFieldsVirtuallySet) {
1942:                    computeFields();
1943:                }
1944:                fields[field] = value;
1945:                stamp[field] = nextStamp++;
1946:                isTimeSet = areFieldsSet = areFieldsVirtuallySet = false;
1947:            }
1948:
1949:            /**
1950:             * Sets the values for the fields year, month, and date.
1951:             * Previous values of other fields are retained.  If this is not desired,
1952:             * call <code>clear</code> first.
1953:             * @param year the value used to set the YEAR time field.
1954:             * @param month the value used to set the MONTH time field.
1955:             * Month value is 0-based. e.g., 0 for January.
1956:             * @param date the value used to set the DATE time field.
1957:             * @stable ICU 2.0
1958:             */
1959:            public final void set(int year, int month, int date) {
1960:                set(YEAR, year);
1961:                set(MONTH, month);
1962:                set(DATE, date);
1963:            }
1964:
1965:            /**
1966:             * Sets the values for the fields year, month, date, hour, and minute.
1967:             * Previous values of other fields are retained.  If this is not desired,
1968:             * call <code>clear</code> first.
1969:             * @param year the value used to set the YEAR time field.
1970:             * @param month the value used to set the MONTH time field.
1971:             * Month value is 0-based. e.g., 0 for January.
1972:             * @param date the value used to set the DATE time field.
1973:             * @param hour the value used to set the HOUR_OF_DAY time field.
1974:             * @param minute the value used to set the MINUTE time field.
1975:             * @stable ICU 2.0
1976:             */
1977:            public final void set(int year, int month, int date, int hour,
1978:                    int minute) {
1979:                set(YEAR, year);
1980:                set(MONTH, month);
1981:                set(DATE, date);
1982:                set(HOUR_OF_DAY, hour);
1983:                set(MINUTE, minute);
1984:            }
1985:
1986:            /**
1987:             * Sets the values for the fields year, month, date, hour, minute, and second.
1988:             * Previous values of other fields are retained.  If this is not desired,
1989:             * call <code>clear</code> first.
1990:             * @param year the value used to set the YEAR time field.
1991:             * @param month the value used to set the MONTH time field.
1992:             * Month value is 0-based. e.g., 0 for January.
1993:             * @param date the value used to set the DATE time field.
1994:             * @param hour the value used to set the HOUR_OF_DAY time field.
1995:             * @param minute the value used to set the MINUTE time field.
1996:             * @param second the value used to set the SECOND time field.
1997:             * @stable ICU 2.0
1998:             */
1999:            public final void set(int year, int month, int date, int hour,
2000:                    int minute, int second) {
2001:                set(YEAR, year);
2002:                set(MONTH, month);
2003:                set(DATE, date);
2004:                set(HOUR_OF_DAY, hour);
2005:                set(MINUTE, minute);
2006:                set(SECOND, second);
2007:            }
2008:
2009:            /**
2010:             * Clears the values of all the time fields.
2011:             * @stable ICU 2.0
2012:             */
2013:            public final void clear() {
2014:                for (int i = 0; i < fields.length; ++i) {
2015:                    fields[i] = stamp[i] = 0; // UNSET == 0
2016:                }
2017:                isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
2018:            }
2019:
2020:            /**
2021:             * Clears the value in the given time field.
2022:             * @param field the time field to be cleared.
2023:             * @stable ICU 2.0
2024:             */
2025:            public final void clear(int field) {
2026:                if (areFieldsVirtuallySet) {
2027:                    computeFields();
2028:                }
2029:                fields[field] = 0;
2030:                stamp[field] = UNSET;
2031:                isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
2032:            }
2033:
2034:            /**
2035:             * Determines if the given time field has a value set.
2036:             * @return true if the given time field has a value set; false otherwise.
2037:             * @stable ICU 2.0
2038:             */
2039:            public final boolean isSet(int field) {
2040:                return areFieldsVirtuallySet || (stamp[field] != UNSET);
2041:            }
2042:
2043:            /**
2044:             * Fills in any unset fields in the time field list.
2045:             * @stable ICU 2.0
2046:             */
2047:            protected void complete() {
2048:                if (!isTimeSet)
2049:                    updateTime();
2050:                if (!areFieldsSet) {
2051:                    computeFields(); // fills in unset fields
2052:                    areFieldsSet = true;
2053:                    areAllFieldsSet = true;
2054:                }
2055:            }
2056:
2057:            /**
2058:             * Compares this calendar to the specified object.
2059:             * The result is <code>true</code> if and only if the argument is
2060:             * not <code>null</code> and is a <code>Calendar</code> object that
2061:             * represents the same calendar as this object.
2062:             * @param obj the object to compare with.
2063:             * @return <code>true</code> if the objects are the same;
2064:             * <code>false</code> otherwise.
2065:             * @stable ICU 2.0
2066:             */
2067:            public boolean equals(Object obj) {
2068:                if (this  == obj) {
2069:                    return true;
2070:                }
2071:                if (this .getClass() != obj.getClass()) {
2072:                    return false;
2073:                }
2074:
2075:                Calendar that = (Calendar) obj;
2076:
2077:                return isEquivalentTo(that)
2078:                        && getTimeInMillis() == that.getTime().getTime();
2079:            }
2080:
2081:            /**
2082:             * Returns true if the given Calendar object is equivalent to this
2083:             * one.  An equivalent Calendar will behave exactly as this one
2084:             * does, but it may be set to a different time.  By contrast, for
2085:             * the equals() method to return true, the other Calendar must
2086:             * be set to the same time.
2087:             *
2088:             * @param other the Calendar to be compared with this Calendar
2089:             * @stable ICU 2.4
2090:             */
2091:            public boolean isEquivalentTo(Calendar other) {
2092:                return this .getClass() == other.getClass()
2093:                        && isLenient() == other.isLenient()
2094:                        && getFirstDayOfWeek() == other.getFirstDayOfWeek()
2095:                        && getMinimalDaysInFirstWeek() == other
2096:                                .getMinimalDaysInFirstWeek()
2097:                        && getTimeZone().equals(other.getTimeZone());
2098:            }
2099:
2100:            /**
2101:             * Returns a hash code for this calendar.
2102:             * @return a hash code value for this object.
2103:             * @stable ICU 2.0
2104:             */
2105:            public int hashCode() {
2106:                /* Don't include the time because (a) we don't want the hash value to
2107:                 * move around just because a calendar is set to different times, and
2108:                 * (b) we don't want to trigger a time computation just to get a hash.
2109:                 * Note that it is not necessary for unequal objects to always have
2110:                 * unequal hashes, but equal objects must have equal hashes.  */
2111:                return (lenient ? 1 : 0) | (firstDayOfWeek << 1)
2112:                        | (minimalDaysInFirstWeek << 4)
2113:                        | (zone.hashCode() << 7);
2114:            }
2115:
2116:            /**
2117:             * Return the difference in milliseconds between the moment this
2118:             * calendar is set to and the moment the given calendar or Date object
2119:             * is set to.
2120:             */
2121:            private long compare(Object that) {
2122:                long thatMs;
2123:                if (that instanceof  Calendar) {
2124:                    thatMs = ((Calendar) that).getTimeInMillis();
2125:                } else if (that instanceof  Date) {
2126:                    thatMs = ((Date) that).getTime();
2127:                } else {
2128:                    throw new IllegalArgumentException(that
2129:                            + "is not a Calendar or Date");
2130:                }
2131:                return getTimeInMillis() - thatMs;
2132:            }
2133:
2134:            /**
2135:             * Compares the time field records.
2136:             * Equivalent to comparing result of conversion to UTC.
2137:             * @param when the Calendar to be compared with this Calendar.
2138:             * @return true if the current time of this Calendar is before
2139:             * the time of Calendar when; false otherwise.
2140:             * @stable ICU 2.0
2141:             */
2142:            public boolean before(Object when) {
2143:                return compare(when) < 0;
2144:            }
2145:
2146:            /**
2147:             * Compares the time field records.
2148:             * Equivalent to comparing result of conversion to UTC.
2149:             * @param when the Calendar to be compared with this Calendar.
2150:             * @return true if the current time of this Calendar is after
2151:             * the time of Calendar when; false otherwise.
2152:             * @stable ICU 2.0
2153:             */
2154:            public boolean after(Object when) {
2155:                return compare(when) > 0;
2156:            }
2157:
2158:            /**
2159:             * Return the maximum value that this field could have, given the
2160:             * current date.  For example, with the Gregorian date February 3, 1997
2161:             * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum
2162:             * is 28; for February 3, 1996 it is 29.
2163:             *
2164:             * <p>The actual maximum computation ignores smaller fields and the
2165:             * current value of like-sized fields.  For example, the actual maximum
2166:             * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year
2167:             * fields.  The actual maximum of the DAY_OF_MONTH depends, in
2168:             * addition, on the MONTH field and any other fields at that
2169:             * granularity (such as ChineseCalendar.IS_LEAP_MONTH).  The
2170:             * DAY_OF_WEEK_IN_MONTH field does not depend on the current
2171:             * DAY_OF_WEEK; it returns the maximum for any day of week in the
2172:             * current month.  Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR
2173:             * fields.
2174:             *
2175:             * @param field the field whose maximum is desired
2176:             * @return the maximum of the given field for the current date of this calendar
2177:             * @see #getMaximum
2178:             * @see #getLeastMaximum
2179:             * @stable ICU 2.0
2180:             */
2181:            public int getActualMaximum(int field) {
2182:                int result;
2183:
2184:                switch (field) {
2185:                case DAY_OF_MONTH: {
2186:                    Calendar cal = (Calendar) clone();
2187:                    cal.prepareGetActual(field, false);
2188:                    result = handleGetMonthLength(cal.get(EXTENDED_YEAR), cal
2189:                            .get(MONTH));
2190:                }
2191:                    break;
2192:
2193:                case DAY_OF_YEAR: {
2194:                    Calendar cal = (Calendar) clone();
2195:                    cal.prepareGetActual(field, false);
2196:                    result = handleGetYearLength(cal.get(EXTENDED_YEAR));
2197:                }
2198:                    break;
2199:
2200:                case DAY_OF_WEEK:
2201:                case AM_PM:
2202:                case HOUR:
2203:                case HOUR_OF_DAY:
2204:                case MINUTE:
2205:                case SECOND:
2206:                case MILLISECOND:
2207:                case ZONE_OFFSET:
2208:                case DST_OFFSET:
2209:                case DOW_LOCAL:
2210:                case JULIAN_DAY:
2211:                case MILLISECONDS_IN_DAY:
2212:                    // These fields all have fixed minima/maxima
2213:                    result = getMaximum(field);
2214:                    break;
2215:
2216:                default:
2217:                    // For all other fields, do it the hard way....
2218:                    result = getActualHelper(field, getLeastMaximum(field),
2219:                            getMaximum(field));
2220:                    break;
2221:                }
2222:                return result;
2223:            }
2224:
2225:            /**
2226:             * Return the minimum value that this field could have, given the current date.
2227:             * For most fields, this is the same as {@link #getMinimum getMinimum}
2228:             * and {@link #getGreatestMinimum getGreatestMinimum}.  However, some fields,
2229:             * especially those related to week number, are more complicated.
2230:             * <p>
2231:             * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
2232:             * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY.
2233:             * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday
2234:             * there will be four or more days in the first week, so it will be week number 1,
2235:             * and <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 1.  However,
2236:             * if the first of the month is a Thursday, Friday, or Saturday, there are
2237:             * <em>not</em> four days in that week, so it is week number 0, and
2238:             * <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 0.
2239:             * <p>
2240:             * @param field the field whose actual minimum value is desired.
2241:             * @return the minimum of the given field for the current date of this calendar
2242:             *
2243:             * @see #getMinimum
2244:             * @see #getGreatestMinimum
2245:             * @stable ICU 2.0
2246:             */
2247:            public int getActualMinimum(int field) {
2248:                int result;
2249:
2250:                switch (field) {
2251:                case DAY_OF_WEEK:
2252:                case AM_PM:
2253:                case HOUR:
2254:                case HOUR_OF_DAY:
2255:                case MINUTE:
2256:                case SECOND:
2257:                case MILLISECOND:
2258:                case ZONE_OFFSET:
2259:                case DST_OFFSET:
2260:                case DOW_LOCAL:
2261:                case JULIAN_DAY:
2262:                case MILLISECONDS_IN_DAY:
2263:                    // These fields all have fixed minima/maxima
2264:                    result = getMinimum(field);
2265:                    break;
2266:
2267:                default:
2268:                    // For all other fields, do it the hard way....
2269:                    result = getActualHelper(field, getGreatestMinimum(field),
2270:                            getMinimum(field));
2271:                    break;
2272:                }
2273:                return result;
2274:            }
2275:
2276:            /**
2277:             * Prepare this calendar for computing the actual minimum or maximum.
2278:             * This method modifies this calendar's fields; it is called on a
2279:             * temporary calendar.
2280:             *
2281:             * <p>Rationale: The semantics of getActualXxx() is to return the
2282:             * maximum or minimum value that the given field can take, taking into
2283:             * account other relevant fields.  In general these other fields are
2284:             * larger fields.  For example, when computing the actual maximum
2285:             * DAY_OF_MONTH, the current value of DAY_OF_MONTH itself is ignored,
2286:             * as is the value of any field smaller.
2287:             *
2288:             * <p>The time fields all have fixed minima and maxima, so we don't
2289:             * need to worry about them.  This also lets us set the
2290:             * MILLISECONDS_IN_DAY to zero to erase any effects the time fields
2291:             * might have when computing date fields.
2292:             *
2293:             * <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and
2294:             * WEEK_OF_YEAR fields to ensure that they are computed correctly.
2295:             * @stable ICU 2.0
2296:             */
2297:            protected void prepareGetActual(int field, boolean isMinimum) {
2298:                set(MILLISECONDS_IN_DAY, 0);
2299:
2300:                switch (field) {
2301:                case YEAR:
2302:                case YEAR_WOY:
2303:                case EXTENDED_YEAR:
2304:                    set(DAY_OF_YEAR, getGreatestMinimum(DAY_OF_YEAR));
2305:                    break;
2306:
2307:                case MONTH:
2308:                    set(DAY_OF_MONTH, getGreatestMinimum(DAY_OF_MONTH));
2309:                    break;
2310:
2311:                case DAY_OF_WEEK_IN_MONTH:
2312:                    // For dowim, the maximum occurs for the DOW of the first of the
2313:                    // month.
2314:                    set(DAY_OF_MONTH, 1);
2315:                    set(DAY_OF_WEEK, get(DAY_OF_WEEK)); // Make this user set
2316:                    break;
2317:
2318:                case WEEK_OF_MONTH:
2319:                case WEEK_OF_YEAR:
2320:                    // If we're counting weeks, set the day of the week to either the
2321:                    // first or last localized DOW.  We know the last week of a month
2322:                    // or year will contain the first day of the week, and that the
2323:                    // first week will contain the last DOW.
2324:                {
2325:                    int dow = firstDayOfWeek;
2326:                    if (isMinimum) {
2327:                        dow = (dow + 6) % 7; // set to last DOW
2328:                        if (dow < SUNDAY) {
2329:                            dow += 7;
2330:                        }
2331:                    }
2332:                    set(DAY_OF_WEEK, dow);
2333:                }
2334:                    break;
2335:                }
2336:
2337:                // Do this last to give it the newest time stamp
2338:                set(field, getGreatestMinimum(field));
2339:            }
2340:
2341:            private int getActualHelper(int field, int startValue, int endValue) {
2342:
2343:                if (startValue == endValue) {
2344:                    // if we know that the maximum value is always the same, just return it
2345:                    return startValue;
2346:                }
2347:
2348:                final int delta = (endValue > startValue) ? 1 : -1;
2349:
2350:                // clone the calendar so we don't mess with the real one, and set it to
2351:                // accept anything for the field values
2352:                Calendar work = (Calendar) clone();
2353:                work.setLenient(true);
2354:                work.prepareGetActual(field, delta < 0);
2355:
2356:                // now try each value from the start to the end one by one until
2357:                // we get a value that normalizes to another value.  The last value that
2358:                // normalizes to itself is the actual maximum for the current date
2359:                int result = startValue;
2360:                do {
2361:                    work.set(field, startValue);
2362:                    if (work.get(field) != startValue) {
2363:                        break;
2364:                    } else {
2365:                        result = startValue;
2366:                        startValue += delta;
2367:                    }
2368:                } while (result != endValue);
2369:
2370:                return result;
2371:            }
2372:
2373:            /**
2374:             * Rolls (up/down) a single unit of time on the given field.  If the
2375:             * field is rolled past its maximum allowable value, it will "wrap" back
2376:             * to its minimum and continue rolling. For
2377:             * example, to roll the current date up by one day, you can call:
2378:             * <p>
2379:             * <code>roll({@link #DATE}, true)</code>
2380:             * <p>
2381:             * When rolling on the {@link #YEAR} field, it will roll the year
2382:             * value in the range between 1 and the value returned by calling
2383:             * {@link #getMaximum getMaximum}({@link #YEAR}).
2384:             * <p>
2385:             * When rolling on certain fields, the values of other fields may conflict and
2386:             * need to be changed.  For example, when rolling the <code>MONTH</code> field
2387:             * for the Gregorian date 1/31/96 upward, the <code>DAY_OF_MONTH</code> field
2388:             * must be adjusted so that the result is 2/29/96 rather than the invalid
2389:             * 2/31/96.
2390:             * <p>
2391:             * <b>Note:</b> Calling <tt>roll(field, true)</tt> N times is <em>not</em>
2392:             * necessarily equivalent to calling <tt>roll(field, N)</tt>.  For example,
2393:             * imagine that you start with the date Gregorian date January 31, 1995.  If you call
2394:             * <tt>roll(Calendar.MONTH, 2)</tt>, the result will be March 31, 1995.
2395:             * But if you call <tt>roll(Calendar.MONTH, true)</tt>, the result will be
2396:             * February 28, 1995.  Calling it one more time will give March 28, 1995, which
2397:             * is usually not the desired result.
2398:             * <p>
2399:             * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
2400:             * than attempting to perform arithmetic operations directly on the fields
2401:             * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
2402:             * to have fields with non-linear behavior, for example missing months
2403:             * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
2404:             * methods will take this into account, while simple arithmetic manipulations
2405:             * may give invalid results.
2406:             * <p>
2407:             * @param field the calendar field to roll.
2408:             *
2409:             * @param up    indicates if the value of the specified time field is to be
2410:             *              rolled up or rolled down. Use <code>true</code> if rolling up,
2411:             *              <code>false</code> otherwise.
2412:             *
2413:             * @exception   IllegalArgumentException if the field is invalid or refers
2414:             *              to a field that cannot be handled by this method.
2415:             * @see #roll(int, int)
2416:             * @see #add
2417:             * @stable ICU 2.0
2418:             */
2419:            public final void roll(int field, boolean up) {
2420:                roll(field, up ? +1 : -1);
2421:            }
2422:
2423:            /**
2424:             * Rolls (up/down) a specified amount time on the given field.  For
2425:             * example, to roll the current date up by three days, you can call
2426:             * <code>roll(Calendar.DATE, 3)</code>.  If the
2427:             * field is rolled past its maximum allowable value, it will "wrap" back
2428:             * to its minimum and continue rolling.
2429:             * For example, calling <code>roll(Calendar.DATE, 10)</code>
2430:             * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96.
2431:             * <p>
2432:             * When rolling on certain fields, the values of other fields may conflict and
2433:             * need to be changed.  For example, when rolling the {@link #MONTH MONTH} field
2434:             * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
2435:             * must be adjusted so that the result is 2/29/96 rather than the invalid
2436:             * 2/31/96.
2437:             * <p>
2438:             * The <code>com.ibm.icu.util.Calendar</code> implementation of this method is able to roll
2439:             * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
2440:             * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
2441:             * additional fields in their overrides of <code>roll</code>.
2442:             * <p>
2443:             * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
2444:             * than attempting to perform arithmetic operations directly on the fields
2445:             * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
2446:             * to have fields with non-linear behavior, for example missing months
2447:             * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
2448:             * methods will take this into account, while simple arithmetic manipulations
2449:             * may give invalid results.
2450:             * <p>
2451:             * <b>Subclassing:</b><br>
2452:             * This implementation of <code>roll</code> assumes that the behavior of the
2453:             * field is continuous between its minimum and maximum, which are found by
2454:             * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}.
2455:             * For most such fields, simple addition, subtraction, and modulus operations
2456:             * are sufficient to perform the roll.  For week-related fields,
2457:             * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and
2458:             * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary.
2459:             * Subclasses can override these two methods if their values differ from the defaults.
2460:             * <p>
2461:             * Subclasses that have fields for which the assumption of continuity breaks
2462:             * down must overide <code>roll</code> to handle those fields specially.
2463:             * For example, in the Hebrew calendar the month "Adar I"
2464:             * only occurs in leap years; in other years the calendar jumps from
2465:             * Shevat (month #4) to Adar (month #6).  The
2466:             * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account,
2467:             * so that rolling the month of Shevat by one gives the proper result (Adar) in a
2468:             * non-leap year.
2469:             * <p>
2470:             * @param field     the calendar field to roll.
2471:             * @param amount    the amount by which the field should be rolled.
2472:             *
2473:             * @exception   IllegalArgumentException if the field is invalid or refers
2474:             *              to a field that cannot be handled by this method.
2475:             * @see #roll(int, boolean)
2476:             * @see #add
2477:             * @stable ICU 2.0
2478:             */
2479:            public void roll(int field, int amount) {
2480:
2481:                if (amount == 0) {
2482:                    return; // Nothing to do
2483:                }
2484:
2485:                complete();
2486:
2487:                switch (field) {
2488:                case DAY_OF_MONTH:
2489:                case AM_PM:
2490:                case MINUTE:
2491:                case SECOND:
2492:                case MILLISECOND:
2493:                case MILLISECONDS_IN_DAY:
2494:                case ERA:
2495:                    // These are the standard roll instructions.  These work for all
2496:                    // simple cases, that is, cases in which the limits are fixed, such
2497:                    // as the hour, the day of the month, and the era.
2498:                {
2499:                    int min = getActualMinimum(field);
2500:                    int max = getActualMaximum(field);
2501:                    int gap = max - min + 1;
2502:
2503:                    int value = internalGet(field) + amount;
2504:                    value = (value - min) % gap;
2505:                    if (value < 0) {
2506:                        value += gap;
2507:                    }
2508:                    value += min;
2509:
2510:                    set(field, value);
2511:                    return;
2512:                }
2513:
2514:                case HOUR:
2515:                case HOUR_OF_DAY:
2516:                    // Rolling the hour is difficult on the ONSET and CEASE days of
2517:                    // daylight savings.  For example, if the change occurs at
2518:                    // 2 AM, we have the following progression:
2519:                    // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
2520:                    // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
2521:                    // To get around this problem we don't use fields; we manipulate
2522:                    // the time in millis directly.
2523:                {
2524:                    // Assume min == 0 in calculations below
2525:                    long start = getTimeInMillis();
2526:                    int oldHour = internalGet(field);
2527:                    int max = getMaximum(field);
2528:                    int newHour = (oldHour + amount) % (max + 1);
2529:                    if (newHour < 0) {
2530:                        newHour += max + 1;
2531:                    }
2532:                    setTimeInMillis(start + ONE_HOUR * (newHour - oldHour));
2533:                    return;
2534:                }
2535:
2536:                case MONTH:
2537:                    // Rolling the month involves both pinning the final value
2538:                    // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
2539:                    // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
2540:                    // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
2541:                {
2542:                    int max = getActualMaximum(MONTH);
2543:                    int mon = (internalGet(MONTH) + amount) % (max + 1);
2544:
2545:                    if (mon < 0) {
2546:                        mon += (max + 1);
2547:                    }
2548:                    set(MONTH, mon);
2549:
2550:                    // Keep the day of month in range.  We don't want to spill over
2551:                    // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
2552:                    // mar3.
2553:                    pinField(DAY_OF_MONTH);
2554:                    return;
2555:                }
2556:
2557:                case YEAR:
2558:                case YEAR_WOY:
2559:                case EXTENDED_YEAR:
2560:                    // Rolling the year can involve pinning the DAY_OF_MONTH.
2561:                    set(field, internalGet(field) + amount);
2562:                    pinField(MONTH);
2563:                    pinField(DAY_OF_MONTH);
2564:                    return;
2565:
2566:                case WEEK_OF_MONTH: {
2567:                    // This is tricky, because during the roll we may have to shift
2568:                    // to a different day of the week.  For example:
2569:
2570:                    //    s  m  t  w  r  f  s
2571:                    //          1  2  3  4  5
2572:                    //    6  7  8  9 10 11 12
2573:
2574:                    // When rolling from the 6th or 7th back one week, we go to the
2575:                    // 1st (assuming that the first partial week counts).  The same
2576:                    // thing happens at the end of the month.
2577:
2578:                    // The other tricky thing is that we have to figure out whether
2579:                    // the first partial week actually counts or not, based on the
2580:                    // minimal first days in the week.  And we have to use the
2581:                    // correct first day of the week to delineate the week
2582:                    // boundaries.
2583:
2584:                    // Here's our algorithm.  First, we find the real boundaries of
2585:                    // the month.  Then we discard the first partial week if it
2586:                    // doesn't count in this locale.  Then we fill in the ends with
2587:                    // phantom days, so that the first partial week and the last
2588:                    // partial week are full weeks.  We then have a nice square
2589:                    // block of weeks.  We do the usual rolling within this block,
2590:                    // as is done elsewhere in this method.  If we wind up on one of
2591:                    // the phantom days that we added, we recognize this and pin to
2592:                    // the first or the last day of the month.  Easy, eh?
2593:
2594:                    // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
2595:                    // in this locale.  We have dow in 0..6.
2596:                    int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
2597:                    if (dow < 0)
2598:                        dow += 7;
2599:
2600:                    // Find the day of the week (normalized for locale) for the first
2601:                    // of the month.
2602:                    int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7;
2603:                    if (fdm < 0)
2604:                        fdm += 7;
2605:
2606:                    // Get the first day of the first full week of the month,
2607:                    // including phantom days, if any.  Figure out if the first week
2608:                    // counts or not; if it counts, then fill in phantom days.  If
2609:                    // not, advance to the first real full week (skip the partial week).
2610:                    int start;
2611:                    if ((7 - fdm) < getMinimalDaysInFirstWeek())
2612:                        start = 8 - fdm; // Skip the first partial week
2613:                    else
2614:                        start = 1 - fdm; // This may be zero or negative
2615:
2616:                    // Get the day of the week (normalized for locale) for the last
2617:                    // day of the month.
2618:                    int monthLen = getActualMaximum(DAY_OF_MONTH);
2619:                    int ldm = (monthLen - internalGet(DAY_OF_MONTH) + dow) % 7;
2620:                    // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.
2621:
2622:                    // Get the limit day for the blocked-off rectangular month; that
2623:                    // is, the day which is one past the last day of the month,
2624:                    // after the month has already been filled in with phantom days
2625:                    // to fill out the last week.  This day has a normalized DOW of 0.
2626:                    int limit = monthLen + 7 - ldm;
2627:
2628:                    // Now roll between start and (limit - 1).
2629:                    int gap = limit - start;
2630:                    int day_of_month = (internalGet(DAY_OF_MONTH) + amount * 7 - start)
2631:                            % gap;
2632:                    if (day_of_month < 0)
2633:                        day_of_month += gap;
2634:                    day_of_month += start;
2635:
2636:                    // Finally, pin to the real start and end of the month.
2637:                    if (day_of_month < 1)
2638:                        day_of_month = 1;
2639:                    if (day_of_month > monthLen)
2640:                        day_of_month = monthLen;
2641:
2642:                    // Set the DAY_OF_MONTH.  We rely on the fact that this field
2643:                    // takes precedence over everything else (since all other fields
2644:                    // are also set at this point).  If this fact changes (if the
2645:                    // disambiguation algorithm changes) then we will have to unset
2646:                    // the appropriate fields here so that DAY_OF_MONTH is attended
2647:                    // to.
2648:                    set(DAY_OF_MONTH, day_of_month);
2649:                    return;
2650:                }
2651:                case WEEK_OF_YEAR: {
2652:                    // This follows the outline of WEEK_OF_MONTH, except it applies
2653:                    // to the whole year.  Please see the comment for WEEK_OF_MONTH
2654:                    // for general notes.
2655:
2656:                    // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
2657:                    // in this locale.  We have dow in 0..6.
2658:                    int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
2659:                    if (dow < 0)
2660:                        dow += 7;
2661:
2662:                    // Find the day of the week (normalized for locale) for the first
2663:                    // of the year.
2664:                    int fdy = (dow - internalGet(DAY_OF_YEAR) + 1) % 7;
2665:                    if (fdy < 0)
2666:                        fdy += 7;
2667:
2668:                    // Get the first day of the first full week of the year,
2669:                    // including phantom days, if any.  Figure out if the first week
2670:                    // counts or not; if it counts, then fill in phantom days.  If
2671:                    // not, advance to the first real full week (skip the partial week).
2672:                    int start;
2673:                    if ((7 - fdy) < getMinimalDaysInFirstWeek())
2674:                        start = 8 - fdy; // Skip the first partial week
2675:                    else
2676:                        start = 1 - fdy; // This may be zero or negative
2677:
2678:                    // Get the day of the week (normalized for locale) for the last
2679:                    // day of the year.
2680:                    int yearLen = getActualMaximum(DAY_OF_YEAR);
2681:                    int ldy = (yearLen - internalGet(DAY_OF_YEAR) + dow) % 7;
2682:                    // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here.
2683:
2684:                    // Get the limit day for the blocked-off rectangular year; that
2685:                    // is, the day which is one past the last day of the year,
2686:                    // after the year has already been filled in with phantom days
2687:                    // to fill out the last week.  This day has a normalized DOW of 0.
2688:                    int limit = yearLen + 7 - ldy;
2689:
2690:                    // Now roll between start and (limit - 1).
2691:                    int gap = limit - start;
2692:                    int day_of_year = (internalGet(DAY_OF_YEAR) + amount * 7 - start)
2693:                            % gap;
2694:                    if (day_of_year < 0)
2695:                        day_of_year += gap;
2696:                    day_of_year += start;
2697:
2698:                    // Finally, pin to the real start and end of the month.
2699:                    if (day_of_year < 1)
2700:                        day_of_year = 1;
2701:                    if (day_of_year > yearLen)
2702:                        day_of_year = yearLen;
2703:
2704:                    // Make sure that the year and day of year are attended to by
2705:                    // clearing other fields which would normally take precedence.
2706:                    // If the disambiguation algorithm is changed, this section will
2707:                    // have to be updated as well.
2708:                    set(DAY_OF_YEAR, day_of_year);
2709:                    clear(MONTH);
2710:                    return;
2711:                }
2712:                case DAY_OF_YEAR: {
2713:                    // Roll the day of year using millis.  Compute the millis for
2714:                    // the start of the year, and get the length of the year.
2715:                    long delta = amount * ONE_DAY; // Scale up from days to millis
2716:                    long min2 = time - (internalGet(DAY_OF_YEAR) - 1) * ONE_DAY;
2717:                    int yearLength = getActualMaximum(DAY_OF_YEAR);
2718:                    time = (time + delta - min2) % (yearLength * ONE_DAY);
2719:                    if (time < 0)
2720:                        time += yearLength * ONE_DAY;
2721:                    setTimeInMillis(time + min2);
2722:                    return;
2723:                }
2724:                case DAY_OF_WEEK:
2725:                case DOW_LOCAL: {
2726:                    // Roll the day of week using millis.  Compute the millis for
2727:                    // the start of the week, using the first day of week setting.
2728:                    // Restrict the millis to [start, start+7days).
2729:                    long delta = amount * ONE_DAY; // Scale up from days to millis
2730:                    // Compute the number of days before the current day in this
2731:                    // week.  This will be a value 0..6.
2732:                    int leadDays = internalGet(field);
2733:                    leadDays -= (field == DAY_OF_WEEK) ? getFirstDayOfWeek()
2734:                            : 1;
2735:                    if (leadDays < 0)
2736:                        leadDays += 7;
2737:                    long min2 = time - leadDays * ONE_DAY;
2738:                    time = (time + delta - min2) % ONE_WEEK;
2739:                    if (time < 0)
2740:                        time += ONE_WEEK;
2741:                    setTimeInMillis(time + min2);
2742:                    return;
2743:                }
2744:                case DAY_OF_WEEK_IN_MONTH: {
2745:                    // Roll the day of week in the month using millis.  Determine
2746:                    // the first day of the week in the month, and then the last,
2747:                    // and then roll within that range.
2748:                    long delta = amount * ONE_WEEK; // Scale up from weeks to millis
2749:                    // Find the number of same days of the week before this one
2750:                    // in this month.
2751:                    int preWeeks = (internalGet(DAY_OF_MONTH) - 1) / 7;
2752:                    // Find the number of same days of the week after this one
2753:                    // in this month.
2754:                    int postWeeks = (getActualMaximum(DAY_OF_MONTH) - internalGet(DAY_OF_MONTH)) / 7;
2755:                    // From these compute the min and gap millis for rolling.
2756:                    long min2 = time - preWeeks * ONE_WEEK;
2757:                    long gap2 = ONE_WEEK * (preWeeks + postWeeks + 1); // Must add 1!
2758:                    // Roll within this range
2759:                    time = (time + delta - min2) % gap2;
2760:                    if (time < 0)
2761:                        time += gap2;
2762:                    setTimeInMillis(time + min2);
2763:                    return;
2764:                }
2765:                case JULIAN_DAY:
2766:                    set(field, internalGet(field) + amount);
2767:                    return;
2768:                default:
2769:                    // Other fields cannot be rolled by this method
2770:                    throw new IllegalArgumentException("Calendar.roll("
2771:                            + fieldName(field) + ") not supported");
2772:                }
2773:            }
2774:
2775:            /**
2776:             * Add a signed amount to a specified field, using this calendar's rules.
2777:             * For example, to add three days to the current date, you can call
2778:             * <code>add(Calendar.DATE, 3)</code>.
2779:             * <p>
2780:             * When adding to certain fields, the values of other fields may conflict and
2781:             * need to be changed.  For example, when adding one to the {@link #MONTH MONTH} field
2782:             * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
2783:             * must be adjusted so that the result is 2/29/96 rather than the invalid
2784:             * 2/31/96.
2785:             * <p>
2786:             * The <code>com.ibm.icu.util.Calendar</code> implementation of this method is able to add to
2787:             * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
2788:             * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
2789:             * additional fields in their overrides of <code>add</code>.
2790:             * <p>
2791:             * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
2792:             * than attempting to perform arithmetic operations directly on the fields
2793:             * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
2794:             * to have fields with non-linear behavior, for example missing months
2795:             * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
2796:             * methods will take this into account, while simple arithmetic manipulations
2797:             * may give invalid results.
2798:             * <p>
2799:             * <b>Subclassing:</b><br>
2800:             * This implementation of <code>add</code> assumes that the behavior of the
2801:             * field is continuous between its minimum and maximum, which are found by
2802:             * calling {@link #getActualMinimum getActualMinimum} and
2803:             * {@link #getActualMaximum getActualMaximum}.
2804:             * For such fields, simple arithmetic operations are sufficient to
2805:             * perform the add.
2806:             * <p>
2807:             * Subclasses that have fields for which this assumption of continuity breaks
2808:             * down must overide <code>add</code> to handle those fields specially.
2809:             * For example, in the Hebrew calendar the month "Adar I"
2810:             * only occurs in leap years; in other years the calendar jumps from
2811:             * Shevat (month #4) to Adar (month #6).  The
2812:             * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account,
2813:             * so that adding one month
2814:             * to a date in Shevat gives the proper result (Adar) in a non-leap year.
2815:             * <p>
2816:             * @param field     the time field.
2817:             * @param amount    the amount to add to the field.
2818:             *
2819:             * @exception   IllegalArgumentException if the field is invalid or refers
2820:             *              to a field that cannot be handled by this method.
2821:             * @see #roll(int, int)
2822:             * @stable ICU 2.0
2823:             */
2824:            public void add(int field, int amount) {
2825:
2826:                if (amount == 0) {
2827:                    return; // Do nothing!
2828:                }
2829:
2830:                // We handle most fields in the same way.  The algorithm is to add
2831:                // a computed amount of millis to the current millis.  The only
2832:                // wrinkle is with DST -- for some fields, like the DAY_OF_MONTH,
2833:                // we don't want the HOUR to shift due to changes in DST.  If the
2834:                // result of the add operation is to move from DST to Standard, or
2835:                // vice versa, we need to adjust by an hour forward or back,
2836:                // respectively.  For such fields we set keepHourInvariant to true.
2837:
2838:                // We only adjust the DST for fields larger than an hour.  For
2839:                // fields smaller than an hour, we cannot adjust for DST without
2840:                // causing problems.  for instance, if you add one hour to April 5,
2841:                // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an
2842:                // illegal value), but then the adjustment sees the change and
2843:                // compensates by subtracting an hour.  As a result the time
2844:                // doesn't advance at all.
2845:
2846:                // For some fields larger than a day, such as a MONTH, we pin the
2847:                // DAY_OF_MONTH.  This allows <March 31>.add(MONTH, 1) to be
2848:                // <April 30>, rather than <April 31> => <May 1>.
2849:
2850:                long delta = amount; // delta in ms
2851:                boolean keepHourInvariant = true;
2852:
2853:                switch (field) {
2854:                case ERA:
2855:                    set(field, get(field) + amount);
2856:                    pinField(ERA);
2857:                    return;
2858:
2859:                case YEAR:
2860:                case EXTENDED_YEAR:
2861:                case YEAR_WOY:
2862:                case MONTH:
2863:                    set(field, get(field) + amount);
2864:                    pinField(DAY_OF_MONTH);
2865:                    return;
2866:
2867:                case WEEK_OF_YEAR:
2868:                case WEEK_OF_MONTH:
2869:                case DAY_OF_WEEK_IN_MONTH:
2870:                    delta *= ONE_WEEK;
2871:                    break;
2872:
2873:                case AM_PM:
2874:                    delta *= 12 * ONE_HOUR;
2875:                    break;
2876:
2877:                case DAY_OF_MONTH:
2878:                case DAY_OF_YEAR:
2879:                case DAY_OF_WEEK:
2880:                case DOW_LOCAL:
2881:                case JULIAN_DAY:
2882:                    delta *= ONE_DAY;
2883:                    break;
2884:
2885:                case HOUR_OF_DAY:
2886:                case HOUR:
2887:                    delta *= ONE_HOUR;
2888:                    keepHourInvariant = false;
2889:                    break;
2890:
2891:                case MINUTE:
2892:                    delta *= ONE_MINUTE;
2893:                    keepHourInvariant = false;
2894:                    break;
2895:
2896:                case SECOND:
2897:                    delta *= ONE_SECOND;
2898:                    keepHourInvariant = false;
2899:                    break;
2900:
2901:                case MILLISECOND:
2902:                case MILLISECONDS_IN_DAY:
2903:                    keepHourInvariant = false;
2904:                    break;
2905:
2906:                default:
2907:                    throw new IllegalArgumentException("Calendar.add("
2908:                            + fieldName(field) + ") not supported");
2909:                }
2910:
2911:                // In order to keep the hour invariant (for fields where this is
2912:                // appropriate), record the DST_OFFSET before and after the add()
2913:                // operation.  If it has changed, then adjust the millis to
2914:                // compensate.
2915:                int dst = 0;
2916:                int hour = 0;
2917:                if (keepHourInvariant) {
2918:                    dst = get(DST_OFFSET);
2919:                    hour = internalGet(HOUR_OF_DAY);
2920:                }
2921:
2922:                setTimeInMillis(getTimeInMillis() + delta);
2923:
2924:                if (keepHourInvariant) {
2925:                    dst -= get(DST_OFFSET);
2926:                    if (dst != 0) {
2927:                        // We have done an hour-invariant adjustment but the
2928:                        // DST offset has altered.  We adjust millis to keep
2929:                        // the hour constant.  In cases such as midnight after
2930:                        // a DST change which occurs at midnight, there is the
2931:                        // danger of adjusting into a different day.  To avoid
2932:                        // this we make the adjustment only if it actually
2933:                        // maintains the hour.
2934:                        long t = time;
2935:                        setTimeInMillis(time + dst);
2936:                        if (get(HOUR_OF_DAY) != hour) {
2937:                            setTimeInMillis(t);
2938:                        }
2939:                    }
2940:                }
2941:            }
2942:
2943:            /**
2944:             * Return the name of this calendar in the language of the given locale.
2945:             * @stable ICU 2.0
2946:             */
2947:            public String getDisplayName(Locale loc) {
2948:                return this .getClass().getName();
2949:            }
2950:
2951:            /**
2952:             * Return the name of this calendar in the language of the given locale.
2953:             * @draft ICU 3.2
2954:             * @provisional This API might change or be removed in a future release.
2955:             */
2956:            public String getDisplayName(ULocale loc) {
2957:                return this .getClass().getName();
2958:            }
2959:
2960:            /**
2961:             * Compares the times (in millis) represented by two
2962:             * <code>Calendar</code> objects.
2963:             *
2964:             * @param that the <code>Calendar</code> to compare to this.
2965:             * @return <code>0</code> if the time represented by 
2966:             * this <code>Calendar</code> is equal to the time represented 
2967:             * by that <code>Calendar</code>, a value less than 
2968:             * <code>0</code> if the time represented by this is before
2969:             * the time represented by that, and a value greater than
2970:             * <code>0</code> if the time represented by this
2971:             * is after the time represented by that.
2972:             * @throws NullPointerException if that 
2973:             * <code>Calendar</code> is null.
2974:             * @throws IllegalArgumentException if the time of that 
2975:             * <code>Calendar</code> can't be obtained because of invalid
2976:             * calendar values.
2977:             * @draft ICU 3.4
2978:             * @provisional This API might change or be removed in a future release.
2979:             */
2980:            public int compareTo(Calendar that) {
2981:                long v = getTimeInMillis() - that.getTimeInMillis();
2982:                return v < 0 ? -1 : (v > 0 ? 1 : 0);
2983:            }
2984:
2985:            /**
2986:             * Implement comparable API as a convenience override of
2987:             * {@link #compareTo(Calendar)}.
2988:             * @draft ICU 3.4
2989:             * @provisional This API might change or be removed in a future release.
2990:             */
2991:            public int compareTo(Object that) {
2992:                return compareTo((Calendar) that);
2993:            }
2994:
2995:            //-------------------------------------------------------------------------
2996:            // Interface for creating custon DateFormats for different types of Calendars
2997:            //-------------------------------------------------------------------------
2998:
2999:            /**
3000:             * Return a <code>DateFormat</code> appropriate to this calendar.
3001:             * Subclasses wishing to specialize this behavior should override
3002:             * <code>handleGetDateFormat()</code>
3003:             * @see #handleGetDateFormat
3004:             * @stable ICU 2.0
3005:             */
3006:            public DateFormat getDateTimeFormat(int dateStyle, int timeStyle,
3007:                    Locale loc) {
3008:                return formatHelper(this , ULocale.forLocale(loc), dateStyle,
3009:                        timeStyle);
3010:            }
3011:
3012:            /**
3013:             * Return a <code>DateFormat</code> appropriate to this calendar.
3014:             * Subclasses wishing to specialize this behavior should override
3015:             * <code>handleGetDateFormat()</code>
3016:             * @see #handleGetDateFormat
3017:             * @draft ICU 3.2
3018:             * @provisional This API might change or be removed in a future release.
3019:             */
3020:            public DateFormat getDateTimeFormat(int dateStyle, int timeStyle,
3021:                    ULocale loc) {
3022:                return formatHelper(this , loc, dateStyle, timeStyle);
3023:            }
3024:
3025:            /**
3026:             * Create a <code>DateFormat</code> appropriate to this calendar.
3027:             * This is a framework method for subclasses to override.  This method
3028:             * is responsible for creating the calendar-specific DateFormat and
3029:             * DateFormatSymbols objects as needed.
3030:             * @param pattern the pattern, specific to the <code>DateFormat</code>
3031:             * subclass
3032:             * @param locale the locale for which the symbols should be drawn
3033:             * @return a <code>DateFormat</code> appropriate to this calendar
3034:             * @stable ICU 2.0
3035:             */
3036:            protected DateFormat handleGetDateFormat(String pattern,
3037:                    Locale locale) {
3038:                return handleGetDateFormat(pattern, ULocale.forLocale(locale));
3039:            }
3040:
3041:            /**
3042:             * Create a <code>DateFormat</code> appropriate to this calendar.
3043:             * This is a framework method for subclasses to override.  This method
3044:             * is responsible for creating the calendar-specific DateFormat and
3045:             * DateFormatSymbols objects as needed.
3046:             * @param pattern the pattern, specific to the <code>DateFormat</code>
3047:             * subclass
3048:             * @param locale the locale for which the symbols should be drawn
3049:             * @return a <code>DateFormat</code> appropriate to this calendar
3050:             * @draft ICU 3.2
3051:             * @provisional This API might change or be removed in a future release.
3052:             */
3053:            protected DateFormat handleGetDateFormat(String pattern,
3054:                    ULocale locale) {
3055:                DateFormatSymbols symbols = new DateFormatSymbols(this , locale);
3056:                return new SimpleDateFormat(pattern, symbols, locale);
3057:            }
3058:
3059:            static private DateFormat formatHelper(Calendar cal, ULocale loc,
3060:                    int dateStyle, int timeStyle) {
3061:                // See if there are any custom resources for this calendar
3062:                // If not, just use the default DateFormat
3063:                DateFormat result = null;
3064:
3065:                try {
3066:                    CalendarData calData = new CalendarData(loc, cal.getType());
3067:                    String[] patterns = calData.get("DateTimePatterns")
3068:                            .getStringArray();
3069:
3070:                    String pattern = null;
3071:                    if ((timeStyle >= 0) && (dateStyle >= 0)) {
3072:                        Object[] dateTimeArgs = { patterns[timeStyle],
3073:                                patterns[dateStyle + 4] };
3074:                        pattern = MessageFormat.format(patterns[8],
3075:                                dateTimeArgs);
3076:                    } else if (timeStyle >= 0) {
3077:                        pattern = patterns[timeStyle];
3078:                    } else if (dateStyle >= 0) {
3079:                        pattern = patterns[dateStyle + 4];
3080:                    } else {
3081:                        throw new IllegalArgumentException(
3082:                                "No date or time style specified");
3083:                    }
3084:                    result = cal.handleGetDateFormat(pattern, loc);
3085:                } catch (MissingResourceException e) {
3086:                    // !!! need dateformat subclass appropriate to calendar type here!
3087:                    // No custom patterns
3088:                    // !!! note: possible circularity here, if getDateTimeInstance calls us because of
3089:                    // loc specifying a calendar.
3090:                    result = DateFormat.getDateTimeInstance(dateStyle,
3091:                            timeStyle, loc);
3092:
3093:                    DateFormatSymbols symbols = new DateFormatSymbols(cal, loc);
3094:                    ((SimpleDateFormat) result).setDateFormatSymbols(symbols); // aliu
3095:                }
3096:                result.setCalendar(cal);
3097:                return result;
3098:            }
3099:
3100:            //-------------------------------------------------------------------------
3101:            // Protected utility methods for use by subclasses.  These are very handy
3102:            // for implementing add, roll, and computeFields.
3103:            //-------------------------------------------------------------------------
3104:
3105:            /**
3106:             * Adjust the specified field so that it is within
3107:             * the allowable range for the date to which this calendar is set.
3108:             * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH}
3109:             * field for a calendar set to April 31 would cause it to be set
3110:             * to April 30.
3111:             * <p>
3112:             * <b>Subclassing:</b>
3113:             * <br>
3114:             * This utility method is intended for use by subclasses that need to implement
3115:             * their own overrides of {@link #roll roll} and {@link #add add}.
3116:             * <p>
3117:             * <b>Note:</b>
3118:             * <code>pinField</code> is implemented in terms of
3119:             * {@link #getActualMinimum getActualMinimum}
3120:             * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
3121:             * a slow, iterative algorithm for a particular field, it would be
3122:             * unwise to attempt to call <code>pinField</code> for that field.  If you
3123:             * really do need to do so, you should override this method to do
3124:             * something more efficient for that field.
3125:             * <p>
3126:             * @param field The calendar field whose value should be pinned.
3127:             *
3128:             * @see #getActualMinimum
3129:             * @see #getActualMaximum
3130:             * @stable ICU 2.0
3131:             */
3132:            protected void pinField(int field) {
3133:                int max = getActualMaximum(field);
3134:                int min = getActualMinimum(field);
3135:
3136:                if (fields[field] > max) {
3137:                    set(field, max);
3138:                } else if (fields[field] < min) {
3139:                    set(field, min);
3140:                }
3141:            }
3142:
3143:            /**
3144:             * Return the week number of a day, within a period. This may be the week number in
3145:             * a year or the week number in a month. Usually this will be a value >= 1, but if
3146:             * some initial days of the period are excluded from week 1, because
3147:             * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, then
3148:             * the week number will be zero for those
3149:             * initial days. This method requires the day number and day of week for some
3150:             * known date in the period in order to determine the day of week
3151:             * on the desired day.
3152:             * <p>
3153:             * <b>Subclassing:</b>
3154:             * <br>
3155:             * This method is intended for use by subclasses in implementing their
3156:             * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
3157:             * It is often useful in {@link #getActualMinimum getActualMinimum} and
3158:             * {@link #getActualMaximum getActualMaximum} as well.
3159:             * <p>
3160:             * This variant is handy for computing the week number of some other
3161:             * day of a period (often the first or last day of the period) when its day
3162:             * of the week is not known but the day number and day of week for some other
3163:             * day in the period (e.g. the current date) <em>is</em> known.
3164:             * <p>
3165:             * @param desiredDay    The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
3166:             *              {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
3167:             *              Should be 1 for the first day of the period.
3168:             *
3169:             * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR}
3170:             *              or {@link #DAY_OF_MONTH DAY_OF_MONTH} for a day in the period whose
3171:             *              {@link #DAY_OF_WEEK DAY_OF_WEEK} is specified by the
3172:             *              <code>dayOfWeek</code> parameter.
3173:             *              Should be 1 for first day of period.
3174:             *
3175:             * @param dayOfWeek  The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
3176:             *              corresponding to the <code>dayOfPeriod</code> parameter.
3177:             *              1-based with 1=Sunday.
3178:             *
3179:             * @return      The week number (one-based), or zero if the day falls before
3180:             *              the first week because
3181:             *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
3182:             *              is more than one.
3183:             * @stable ICU 2.0
3184:             */
3185:            protected int weekNumber(int desiredDay, int dayOfPeriod,
3186:                    int dayOfWeek) {
3187:                // Determine the day of the week of the first day of the period
3188:                // in question (either a year or a month).  Zero represents the
3189:                // first day of the week on this calendar.
3190:                int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek()
3191:                        - dayOfPeriod + 1) % 7;
3192:                if (periodStartDayOfWeek < 0)
3193:                    periodStartDayOfWeek += 7;
3194:
3195:                // Compute the week number.  Initially, ignore the first week, which
3196:                // may be fractional (or may not be).  We add periodStartDayOfWeek in
3197:                // order to fill out the first week, if it is fractional.
3198:                int weekNo = (desiredDay + periodStartDayOfWeek - 1) / 7;
3199:
3200:                // If the first week is long enough, then count it.  If
3201:                // the minimal days in the first week is one, or if the period start
3202:                // is zero, we always increment weekNo.
3203:                if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek())
3204:                    ++weekNo;
3205:
3206:                return weekNo;
3207:            }
3208:
3209:            /**
3210:             * Return the week number of a day, within a period. This may be the week number in
3211:             * a year, or the week number in a month. Usually this will be a value >= 1, but if
3212:             * some initial days of the period are excluded from week 1, because
3213:             * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1,
3214:             * then the week number will be zero for those
3215:             * initial days. This method requires the day of week for the given date in order to
3216:             * determine the result.
3217:             * <p>
3218:             * <b>Subclassing:</b>
3219:             * <br>
3220:             * This method is intended for use by subclasses in implementing their
3221:             * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
3222:             * It is often useful in {@link #getActualMinimum getActualMinimum} and
3223:             * {@link #getActualMaximum getActualMaximum} as well.
3224:             * <p>
3225:             * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
3226:             *                      {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
3227:             *                      Should be 1 for the first day of the period.
3228:             *
3229:             * @param dayOfWeek     The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
3230:             *                      corresponding to the <code>dayOfPeriod</code> parameter.
3231:             *                      1-based with 1=Sunday.
3232:             *
3233:             * @return      The week number (one-based), or zero if the day falls before
3234:             *              the first week because
3235:             *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
3236:             *              is more than one.
3237:             * @stable ICU 2.0
3238:             */
3239:            protected final int weekNumber(int dayOfPeriod, int dayOfWeek) {
3240:                return weekNumber(dayOfPeriod, dayOfPeriod, dayOfWeek);
3241:            }
3242:
3243:            //-------------------------------------------------------------------------
3244:            // Constants
3245:            //-------------------------------------------------------------------------
3246:
3247:            /**
3248:             * [NEW]
3249:             * Return the difference between the given time and the time this
3250:             * calendar object is set to.  If this calendar is set
3251:             * <em>before</em> the given time, the returned value will be
3252:             * positive.  If this calendar is set <em>after</em> the given
3253:             * time, the returned value will be negative.  The
3254:             * <code>field</code> parameter specifies the units of the return
3255:             * value.  For example, if <code>fieldDifference(when,
3256:             * Calendar.MONTH)</code> returns 3, then this calendar is set to
3257:             * 3 months before <code>when</code>, and possibly some additional
3258:             * time less than one month.
3259:             *
3260:             * <p>As a side effect of this call, this calendar is advanced
3261:             * toward <code>when</code> by the given amount.  That is, calling
3262:             * this method has the side effect of calling <code>add(field,
3263:             * n)</code>, where <code>n</code> is the return value.
3264:             *
3265:             * <p>Usage: To use this method, call it first with the largest
3266:             * field of interest, then with progressively smaller fields.  For
3267:             * example:
3268:             *
3269:             * <pre>
3270:             * int y = cal.fieldDifference(when, Calendar.YEAR);
3271:             * int m = cal.fieldDifference(when, Calendar.MONTH);
3272:             * int d = cal.fieldDifference(when, Calendar.DATE);</pre>
3273:             *
3274:             * computes the difference between <code>cal</code> and
3275:             * <code>when</code> in years, months, and days.
3276:             *
3277:             * <p>Note: <code>fieldDifference()</code> is
3278:             * <em>asymmetrical</em>.  That is, in the following code:
3279:             *
3280:             * <pre>
3281:             * cal.setTime(date1);
3282:             * int m1 = cal.fieldDifference(date2, Calendar.MONTH);
3283:             * int d1 = cal.fieldDifference(date2, Calendar.DATE);
3284:             * cal.setTime(date2);
3285:             * int m2 = cal.fieldDifference(date1, Calendar.MONTH);
3286:             * int d2 = cal.fieldDifference(date1, Calendar.DATE);</pre>
3287:             *
3288:             * one might expect that <code>m1 == -m2 && d1 == -d2</code>.
3289:             * However, this is not generally the case, because of
3290:             * irregularities in the underlying calendar system (e.g., the
3291:             * Gregorian calendar has a varying number of days per month).
3292:             *
3293:             * @param when the date to compare this calendar's time to
3294:             * @param field the field in which to compute the result
3295:             * @return the difference, either positive or negative, between
3296:             * this calendar's time and <code>when</code>, in terms of
3297:             * <code>field</code>.
3298:             * @stable ICU 2.0
3299:             */
3300:            public int fieldDifference(Date when, int field) {
3301:                int min = 0;
3302:                long startMs = getTimeInMillis();
3303:                long targetMs = when.getTime();
3304:                // Always add from the start millis.  This accomodates
3305:                // operations like adding years from February 29, 2000 up to
3306:                // February 29, 2004.  If 1, 1, 1, 1 is added to the year
3307:                // field, the DOM gets pinned to 28 and stays there, giving an
3308:                // incorrect DOM difference of 1.  We have to add 1, reset, 2,
3309:                // reset, 3, reset, 4.
3310:                if (startMs < targetMs) {
3311:                    int max = 1;
3312:                    // Find a value that is too large
3313:                    for (;;) {
3314:                        setTimeInMillis(startMs);
3315:                        add(field, max);
3316:                        long ms = getTimeInMillis();
3317:                        if (ms == targetMs) {
3318:                            return max;
3319:                        } else if (ms > targetMs) {
3320:                            break;
3321:                        } else {
3322:                            max <<= 1;
3323:                            if (max < 0) {
3324:                                // Field difference too large to fit into int
3325:                                throw new RuntimeException();
3326:                            }
3327:                        }
3328:                    }
3329:                    // Do a binary search
3330:                    while ((max - min) > 1) {
3331:                        int t = (min + max) / 2;
3332:                        setTimeInMillis(startMs);
3333:                        add(field, t);
3334:                        long ms = getTimeInMillis();
3335:                        if (ms == targetMs) {
3336:                            return t;
3337:                        } else if (ms > targetMs) {
3338:                            max = t;
3339:                        } else {
3340:                            min = t;
3341:                        }
3342:                    }
3343:                } else if (startMs > targetMs) {
3344:                    if (false) {
3345:                        // This works, and makes the code smaller, but costs
3346:                        // an extra object creation and an extra couple cycles
3347:                        // of calendar computation.
3348:                        setTimeInMillis(targetMs);
3349:                        min = -fieldDifference(new Date(startMs), field);
3350:                    }
3351:                    int max = -1;
3352:                    // Find a value that is too small
3353:                    for (;;) {
3354:                        setTimeInMillis(startMs);
3355:                        add(field, max);
3356:                        long ms = getTimeInMillis();
3357:                        if (ms == targetMs) {
3358:                            return max;
3359:                        } else if (ms < targetMs) {
3360:                            break;
3361:                        } else {
3362:                            max <<= 1;
3363:                            if (max == 0) {
3364:                                // Field difference too large to fit into int
3365:                                throw new RuntimeException();
3366:                            }
3367:                        }
3368:                    }
3369:                    // Do a binary search
3370:                    while ((min - max) > 1) {
3371:                        int t = (min + max) / 2;
3372:                        setTimeInMillis(startMs);
3373:                        add(field, t);
3374:                        long ms = getTimeInMillis();
3375:                        if (ms == targetMs) {
3376:                            return t;
3377:                        } else if (ms < targetMs) {
3378:                            max = t;
3379:                        } else {
3380:                            min = t;
3381:                        }
3382:                    }
3383:                }
3384:                // Set calendar to end point
3385:                setTimeInMillis(startMs);
3386:                add(field, min);
3387:                return min;
3388:            }
3389:
3390:            /**
3391:             * Sets the time zone with the given time zone value.
3392:             * @param value the given time zone.
3393:             * @stable ICU 2.0
3394:             */
3395:            public void setTimeZone(TimeZone value) {
3396:                zone = value;
3397:                /* Recompute the fields from the time using the new zone.  This also
3398:                 * works if isTimeSet is false (after a call to set()).  In that case
3399:                 * the time will be computed from the fields using the new zone, then
3400:                 * the fields will get recomputed from that.  Consider the sequence of
3401:                 * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
3402:                 * Is cal set to 1 o'clock EST or 1 o'clock PST?  Answer: PST.  More
3403:                 * generally, a call to setTimeZone() affects calls to set() BEFORE AND
3404:                 * AFTER it up to the next call to complete().
3405:                 */
3406:                areFieldsSet = false;
3407:            }
3408:
3409:            /**
3410:             * Gets the time zone.
3411:             * @return the time zone object associated with this calendar.
3412:             * @stable ICU 2.0
3413:             */
3414:            public TimeZone getTimeZone() {
3415:                return zone;
3416:            }
3417:
3418:            /**
3419:             * Specify whether or not date/time interpretation is to be lenient.  With
3420:             * lenient interpretation, a date such as "February 942, 1996" will be
3421:             * treated as being equivalent to the 941st day after February 1, 1996.
3422:             * With strict interpretation, such dates will cause an exception to be
3423:             * thrown.
3424:             *
3425:             * @see DateFormat#setLenient
3426:             * @stable ICU 2.0
3427:             */
3428:            public void setLenient(boolean lenient) {
3429:                this .lenient = lenient;
3430:            }
3431:
3432:            /**
3433:             * Tell whether date/time interpretation is to be lenient.
3434:             * @stable ICU 2.0
3435:             */
3436:            public boolean isLenient() {
3437:                return lenient;
3438:            }
3439:
3440:            /**
3441:             * Sets what the first day of the week is; e.g., Sunday in US,
3442:             * Monday in France.
3443:             * @param value the given first day of the week.
3444:             * @stable ICU 2.0
3445:             */
3446:            public void setFirstDayOfWeek(int value) {
3447:                if (firstDayOfWeek != value) {
3448:                    if (value < SUNDAY || value > SATURDAY) {
3449:                        throw new IllegalArgumentException(
3450:                                "Invalid day of week");
3451:                    }
3452:                    firstDayOfWeek = value;
3453:                    areFieldsSet = false;
3454:                }
3455:            }
3456:
3457:            /**
3458:             * Gets what the first day of the week is; e.g., Sunday in US,
3459:             * Monday in France.
3460:             * @return the first day of the week.
3461:             * @stable ICU 2.0
3462:             */
3463:            public int getFirstDayOfWeek() {
3464:                return firstDayOfWeek;
3465:            }
3466:
3467:            /**
3468:             * Sets what the minimal days required in the first week of the year are.
3469:             * For example, if the first week is defined as one that contains the first
3470:             * day of the first month of a year, call the method with value 1. If it
3471:             * must be a full week, use value 7.
3472:             * @param value the given minimal days required in the first week
3473:             * of the year.
3474:             * @stable ICU 2.0
3475:             */
3476:            public void setMinimalDaysInFirstWeek(int value) {
3477:                // Values less than 1 have the same effect as 1; values greater
3478:                // than 7 have the same effect as 7. However, we normalize values
3479:                // so operator== and so forth work.
3480:                if (value < 1) {
3481:                    value = 1;
3482:                } else if (value > 7) {
3483:                    value = 7;
3484:                }
3485:                if (minimalDaysInFirstWeek != value) {
3486:                    minimalDaysInFirstWeek = value;
3487:                    areFieldsSet = false;
3488:                }
3489:            }
3490:
3491:            /**
3492:             * Gets what the minimal days required in the first week of the year are;
3493:             * e.g., if the first week is defined as one that contains the first day
3494:             * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
3495:             * the minimal days required must be a full week, getMinimalDaysInFirstWeek
3496:             * returns 7.
3497:             * @return the minimal days required in the first week of the year.
3498:             * @stable ICU 2.0
3499:             */
3500:            public int getMinimalDaysInFirstWeek() {
3501:                return minimalDaysInFirstWeek;
3502:            }
3503:
3504:            private static final int LIMITS[][] = {
3505:                    //    Minimum  Greatest min      Least max   Greatest max
3506:                    {/*                                                      */}, // ERA
3507:                    {/*                                                      */}, // YEAR
3508:                    {/*                                                      */}, // MONTH
3509:                    {/*                                                      */}, // WEEK_OF_YEAR
3510:                    {/*                                                      */}, // WEEK_OF_MONTH
3511:                    {/*                                                      */}, // DAY_OF_MONTH
3512:                    {/*                                                      */}, // DAY_OF_YEAR
3513:                    { 1, 1, 7, 7 }, // DAY_OF_WEEK
3514:                    {/*                                                      */}, // DAY_OF_WEEK_IN_MONTH
3515:                    { 0, 0, 1, 1 }, // AM_PM
3516:                    { 0, 0, 11, 11 }, // HOUR
3517:                    { 0, 0, 23, 23 }, // HOUR_OF_DAY
3518:                    { 0, 0, 59, 59 }, // MINUTE
3519:                    { 0, 0, 59, 59 }, // SECOND
3520:                    { 0, 0, 999, 999 }, // MILLISECOND
3521:                    { -12 * ONE_HOUR, -12 * ONE_HOUR, 12 * ONE_HOUR,
3522:                            12 * ONE_HOUR }, // ZONE_OFFSET
3523:                    { 0, 0, 1 * ONE_HOUR, 1 * ONE_HOUR }, // DST_OFFSET
3524:                    {/*                                                      */}, // YEAR_WOY
3525:                    { 1, 1, 7, 7 }, // DOW_LOCAL
3526:                    {/*                                                      */}, // EXTENDED_YEAR
3527:                    { -0x7F000000, -0x7F000000, 0x7F000000, 0x7F000000 }, // JULIAN_DAY
3528:                    { 0, 0, 24 * ONE_HOUR - 1, 24 * ONE_HOUR - 1 }, // MILLISECONDS_IN_DAY
3529:            };
3530:
3531:            /**
3532:             * Subclass API for defining limits of different types.
3533:             * Subclasses must implement this method to return limits for the
3534:             * following fields:
3535:             *
3536:             * <pre>ERA
3537:             * YEAR
3538:             * MONTH
3539:             * WEEK_OF_YEAR
3540:             * WEEK_OF_MONTH
3541:             * DAY_OF_MONTH
3542:             * DAY_OF_YEAR
3543:             * DAY_OF_WEEK_IN_MONTH
3544:             * YEAR_WOY
3545:             * EXTENDED_YEAR</pre>
3546:             *
3547:             * @param field one of the above field numbers
3548:             * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
3549:             * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
3550:             * @stable ICU 2.0
3551:             */
3552:            abstract protected int handleGetLimit(int field, int limitType);
3553:
3554:            /**
3555:             * Return a limit for a field.
3556:             * @param field the field, from 0..</code>getFieldCount()-1</code>
3557:             * @param limitType the type specifier for the limit
3558:             * @see #MINIMUM
3559:             * @see #GREATEST_MINIMUM
3560:             * @see #LEAST_MAXIMUM
3561:             * @see #MAXIMUM
3562:             * @stable ICU 2.0
3563:             */
3564:            protected int getLimit(int field, int limitType) {
3565:                switch (field) {
3566:                case DAY_OF_WEEK:
3567:                case AM_PM:
3568:                case HOUR:
3569:                case HOUR_OF_DAY:
3570:                case MINUTE:
3571:                case SECOND:
3572:                case MILLISECOND:
3573:                case ZONE_OFFSET:
3574:                case DST_OFFSET:
3575:                case DOW_LOCAL:
3576:                case JULIAN_DAY:
3577:                case MILLISECONDS_IN_DAY:
3578:                    return LIMITS[field][limitType];
3579:                }
3580:                return handleGetLimit(field, limitType);
3581:            }
3582:
3583:            /**
3584:             * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
3585:             * indicating the minimum value that a field can take (least minimum).
3586:             * @see #getLimit
3587:             * @see #handleGetLimit
3588:             * @stable ICU 2.0
3589:             */
3590:            protected static final int MINIMUM = 0;
3591:
3592:            /**
3593:             * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
3594:             * indicating the greatest minimum value that a field can take.
3595:             * @see #getLimit
3596:             * @see #handleGetLimit
3597:             * @stable ICU 2.0
3598:             */
3599:            protected static final int GREATEST_MINIMUM = 1;
3600:
3601:            /**
3602:             * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
3603:             * indicating the least maximum value that a field can take.
3604:             * @see #getLimit
3605:             * @see #handleGetLimit
3606:             * @stable ICU 2.0
3607:             */
3608:            protected static final int LEAST_MAXIMUM = 2;
3609:
3610:            /**
3611:             * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
3612:             * indicating the maximum value that a field can take (greatest maximum).
3613:             * @see #getLimit
3614:             * @see #handleGetLimit
3615:             * @stable ICU 2.0
3616:             */
3617:            protected static final int MAXIMUM = 3;
3618:
3619:            /**
3620:             * Gets the minimum value for the given time field.
3621:             * e.g., for Gregorian DAY_OF_MONTH, 1.
3622:             * @param field the given time field.
3623:             * @return the minimum value for the given time field.
3624:             * @stable ICU 2.0
3625:             */
3626:            public final int getMinimum(int field) {
3627:                return getLimit(field, MINIMUM);
3628:            }
3629:
3630:            /**
3631:             * Gets the maximum value for the given time field.
3632:             * e.g. for Gregorian DAY_OF_MONTH, 31.
3633:             * @param field the given time field.
3634:             * @return the maximum value for the given time field.
3635:             * @stable ICU 2.0
3636:             */
3637:            public final int getMaximum(int field) {
3638:                return getLimit(field, MAXIMUM);
3639:            }
3640:
3641:            /**
3642:             * Gets the highest minimum value for the given field if varies.
3643:             * Otherwise same as getMinimum(). For Gregorian, no difference.
3644:             * @param field the given time field.
3645:             * @return the highest minimum value for the given time field.
3646:             * @stable ICU 2.0
3647:             */
3648:            public final int getGreatestMinimum(int field) {
3649:                return getLimit(field, GREATEST_MINIMUM);
3650:            }
3651:
3652:            /**
3653:             * Gets the lowest maximum value for the given field if varies.
3654:             * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
3655:             * @param field the given time field.
3656:             * @return the lowest maximum value for the given time field.
3657:             * @stable ICU 2.0
3658:             */
3659:            public final int getLeastMaximum(int field) {
3660:                return getLimit(field, LEAST_MAXIMUM);
3661:            }
3662:
3663:            //-------------------------------------------------------------------------
3664:            // Weekend support -- determining which days of the week are the weekend
3665:            // in a given locale
3666:            //-------------------------------------------------------------------------
3667:
3668:            /**
3669:             * Return whether the given day of the week is a weekday, a
3670:             * weekend day, or a day that transitions from one to the other,
3671:             * in this calendar system.  If a transition occurs at midnight,
3672:             * then the days before and after the transition will have the
3673:             * type WEEKDAY or WEEKEND.  If a transition occurs at a time
3674:             * other than midnight, then the day of the transition will have
3675:             * the type WEEKEND_ONSET or WEEKEND_CEASE.  In this case, the
3676:             * method getWeekendTransition() will return the point of
3677:             * transition.
3678:             * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
3679:             * THURSDAY, FRIDAY, or SATURDAY
3680:             * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or
3681:             * WEEKEND_CEASE
3682:             * @exception IllegalArgumentException if dayOfWeek is not
3683:             * between SUNDAY and SATURDAY, inclusive
3684:             * @see #WEEKDAY
3685:             * @see #WEEKEND
3686:             * @see #WEEKEND_ONSET
3687:             * @see #WEEKEND_CEASE
3688:             * @see #getWeekendTransition
3689:             * @see #isWeekend(Date)
3690:             * @see #isWeekend()
3691:             * @stable ICU 2.0
3692:             */
3693:            public int getDayOfWeekType(int dayOfWeek) {
3694:                if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY) {
3695:                    throw new IllegalArgumentException("Invalid day of week");
3696:                }
3697:                if (weekendOnset < weekendCease) {
3698:                    if (dayOfWeek < weekendOnset || dayOfWeek > weekendCease) {
3699:                        return WEEKDAY;
3700:                    }
3701:                } else {
3702:                    if (dayOfWeek > weekendCease && dayOfWeek < weekendOnset) {
3703:                        return WEEKDAY;
3704:                    }
3705:                }
3706:                if (dayOfWeek == weekendOnset) {
3707:                    return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET;
3708:                }
3709:                if (dayOfWeek == weekendCease) {
3710:                    return (weekendCeaseMillis == 0) ? WEEKDAY : WEEKEND_CEASE;
3711:                }
3712:                return WEEKEND;
3713:            }
3714:
3715:            /**
3716:             * Return the time during the day at which the weekend begins or end in
3717:             * this calendar system.  If getDayOfWeekType(dayOfWeek) ==
3718:             * WEEKEND_ONSET return the time at which the weekend begins.  If
3719:             * getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE return the time at
3720:             * which the weekend ends.  If getDayOfWeekType(dayOfWeek) has some
3721:             * other value, then throw an exception.
3722:             * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
3723:             * THURSDAY, FRIDAY, or SATURDAY
3724:             * @return the milliseconds after midnight at which the
3725:             * weekend begins or ends
3726:             * @exception IllegalArgumentException if dayOfWeek is not
3727:             * WEEKEND_ONSET or WEEKEND_CEASE
3728:             * @see #getDayOfWeekType
3729:             * @see #isWeekend(Date)
3730:             * @see #isWeekend()
3731:             * @stable ICU 2.0
3732:             */
3733:            public int getWeekendTransition(int dayOfWeek) {
3734:                if (dayOfWeek == weekendOnset) {
3735:                    return weekendOnsetMillis;
3736:                } else if (dayOfWeek == weekendCease) {
3737:                    return weekendCeaseMillis;
3738:                }
3739:                throw new IllegalArgumentException("Not weekend transition day");
3740:            }
3741:
3742:            /**
3743:             * Return true if the given date and time is in the weekend in
3744:             * this calendar system.  Equivalent to calling setTime() followed
3745:             * by isWeekend().  Note: This method changes the time this
3746:             * calendar is set to.
3747:             * @param date the date and time
3748:             * @return true if the given date and time is part of the
3749:             * weekend
3750:             * @see #getDayOfWeekType
3751:             * @see #getWeekendTransition
3752:             * @see #isWeekend()
3753:             * @stable ICU 2.0
3754:             */
3755:            public boolean isWeekend(Date date) {
3756:                setTime(date);
3757:                return isWeekend();
3758:            }
3759:
3760:            /**
3761:             * Return true if this Calendar's current date and time is in the
3762:             * weekend in this calendar system.
3763:             * @return true if the given date and time is part of the
3764:             * weekend
3765:             * @see #getDayOfWeekType
3766:             * @see #getWeekendTransition
3767:             * @see #isWeekend(Date)
3768:             * @stable ICU 2.0
3769:             */
3770:            public boolean isWeekend() {
3771:                int dow = get(DAY_OF_WEEK);
3772:                int dowt = getDayOfWeekType(dow);
3773:                switch (dowt) {
3774:                case WEEKDAY:
3775:                    return false;
3776:                case WEEKEND:
3777:                    return true;
3778:                default: // That is, WEEKEND_ONSET or WEEKEND_CEASE
3779:                    // Use internalGet() because the above call to get() populated
3780:                    // all fields.
3781:                    // [Note: There should be a better way to get millis in day.
3782:                    //  For ICU4J, submit request for a MILLIS_IN_DAY field
3783:                    //  and a DAY_NUMBER field (could be Julian day #). - aliu]
3784:                    int millisInDay = internalGet(MILLISECOND)
3785:                            + 1000
3786:                            * (internalGet(SECOND) + 60 * (internalGet(MINUTE) + 60 * internalGet(HOUR_OF_DAY)));
3787:                    int transition = getWeekendTransition(dow);
3788:                    return (dowt == WEEKEND_ONSET) ? (millisInDay >= transition)
3789:                            : (millisInDay < transition);
3790:                }
3791:                // (We can never reach this point.)
3792:            }
3793:
3794:            //-------------------------------------------------------------------------
3795:            // End of weekend support
3796:            //-------------------------------------------------------------------------
3797:
3798:            /**
3799:             * Overrides Cloneable
3800:             * @stable ICU 2.0
3801:             */
3802:            public Object clone() {
3803:                try {
3804:                    Calendar other = (Calendar) super .clone();
3805:
3806:                    other.fields = new int[fields.length];
3807:                    other.stamp = new int[fields.length];
3808:                    System.arraycopy(this .fields, 0, other.fields, 0,
3809:                            fields.length);
3810:                    System.arraycopy(this .stamp, 0, other.stamp, 0,
3811:                            fields.length);
3812:
3813:                    other.zone = (TimeZone) zone.clone();
3814:                    return other;
3815:                } catch (CloneNotSupportedException e) {
3816:                    // this shouldn't happen, since we are Cloneable
3817:                    throw new IllegalStateException();
3818:                }
3819:            }
3820:
3821:            /**
3822:             * Return a string representation of this calendar. This method
3823:             * is intended to be used only for debugging purposes, and the
3824:             * format of the returned string may vary between implementations.
3825:             * The returned string may be empty but may not be <code>null</code>.
3826:             *
3827:             * @return  a string representation of this calendar.
3828:             * @stable ICU 2.0
3829:             */
3830:            public String toString() {
3831:                StringBuffer buffer = new StringBuffer();
3832:                buffer.append(getClass().getName());
3833:                buffer.append("[time=");
3834:                buffer.append(isTimeSet ? String.valueOf(time) : "?");
3835:                buffer.append(",areFieldsSet=");
3836:                buffer.append(areFieldsSet);
3837:                buffer.append(",areAllFieldsSet=");
3838:                buffer.append(areAllFieldsSet);
3839:                buffer.append(",lenient=");
3840:                buffer.append(lenient);
3841:                buffer.append(",zone=");
3842:                buffer.append(zone);
3843:                buffer.append(",firstDayOfWeek=");
3844:                buffer.append(firstDayOfWeek);
3845:                buffer.append(",minimalDaysInFirstWeek=");
3846:                buffer.append(minimalDaysInFirstWeek);
3847:                for (int i = 0; i < fields.length; ++i) {
3848:                    buffer.append(',').append(FIELD_NAME[i]).append('=');
3849:                    buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?");
3850:                }
3851:                buffer.append(']');
3852:                return buffer.toString();
3853:            }
3854:
3855:            // =======================privates===============================
3856:
3857:            /**
3858:             * Internal class that holds cached locale data.
3859:             */
3860:            private static class WeekData {
3861:                public int firstDayOfWeek;
3862:                public int minimalDaysInFirstWeek;
3863:                public int weekendOnset;
3864:                public int weekendOnsetMillis;
3865:                public int weekendCease;
3866:                public int weekendCeaseMillis;
3867:                public ULocale actualLocale;
3868:
3869:                public WeekData(int fdow, int mdifw, int weekendOnset,
3870:                        int weekendOnsetMillis, int weekendCease,
3871:                        int weekendCeaseMillis, ULocale actualLoc) {
3872:                    this .firstDayOfWeek = fdow;
3873:                    this .minimalDaysInFirstWeek = mdifw;
3874:                    this .actualLocale = actualLoc;
3875:                    this .weekendOnset = weekendOnset;
3876:                    this .weekendOnsetMillis = weekendOnsetMillis;
3877:                    this .weekendCease = weekendCease;
3878:                    this .weekendCeaseMillis = weekendCeaseMillis;
3879:                }
3880:            }
3881:
3882:            /**
3883:             * Set this calendar to contain week and weekend data for the given
3884:             * locale.
3885:             * @param locale the locale
3886:             */
3887:            private void setWeekData(ULocale locale) {
3888:                /* try to get the Locale data from the cache */
3889:                WeekData data = (WeekData) cachedLocaleData.get(locale);
3890:
3891:                if (data == null) { /* cache miss */
3892:
3893:                    CalendarData calData = new CalendarData(locale, getType());
3894:                    int[] dateTimeElements = calData.get("DateTimeElements")
3895:                            .getIntVector();
3896:                    int[] weekend = calData.get("weekend").getIntVector();
3897:                    data = new WeekData(dateTimeElements[0],
3898:                            dateTimeElements[1], weekend[0], weekend[1],
3899:                            weekend[2], weekend[3], calData.getULocale());
3900:                    /* cache update */
3901:                    cachedLocaleData.put(locale, data);
3902:                }
3903:                setFirstDayOfWeek(data.firstDayOfWeek);
3904:                setMinimalDaysInFirstWeek(data.minimalDaysInFirstWeek);
3905:                weekendOnset = data.weekendOnset;
3906:                weekendOnsetMillis = data.weekendOnsetMillis;
3907:                weekendCease = data.weekendCease;
3908:                weekendCeaseMillis = data.weekendCeaseMillis;
3909:
3910:                // TODO: determine the actual/valid locale
3911:                ULocale uloc = data.actualLocale;
3912:                setLocale(uloc, uloc);
3913:            }
3914:
3915:            /**
3916:             * Recompute the time and update the status fields isTimeSet
3917:             * and areFieldsSet.  Callers should check isTimeSet and only
3918:             * call this method if isTimeSet is false.
3919:             */
3920:            private void updateTime() {
3921:                computeTime();
3922:                // If we are lenient, we need to recompute the fields to normalize
3923:                // the values.  Also, if we haven't set all the fields yet (i.e.,
3924:                // in a newly-created object), we need to fill in the fields. [LIU]
3925:                if (isLenient() || !areAllFieldsSet)
3926:                    areFieldsSet = false;
3927:                isTimeSet = true;
3928:                areFieldsVirtuallySet = false;
3929:            }
3930:
3931:            /**
3932:             * Save the state of this object to a stream (i.e., serialize it).
3933:             *
3934:             * Ideally, <code>Calendar</code> would only write out its state data and
3935:             * the current time, and not write any field data out, such as
3936:             * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
3937:             * and <code>isSet[]</code>.  <code>nextStamp</code> also should not be part
3938:             * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
3939:             * shipped. To be compatible with JDK 1.1, we will always have to write out
3940:             * the field values and state flags.  However, <code>nextStamp</code> can be
3941:             * removed from the serialization stream; this will probably happen in the
3942:             * near future.
3943:             */
3944:            private void writeObject(ObjectOutputStream stream)
3945:                    throws IOException {
3946:                // Try to compute the time correctly, for the future (stream
3947:                // version 2) in which we don't write out fields[] or isSet[].
3948:                if (!isTimeSet) {
3949:                    try {
3950:                        updateTime();
3951:                    } catch (IllegalArgumentException e) {
3952:                    }
3953:                }
3954:
3955:                // Write out the 1.1 FCS object.
3956:                stream.defaultWriteObject();
3957:            }
3958:
3959:            /**
3960:             * Reconstitute this object from a stream (i.e., deserialize it).
3961:             */
3962:            private void readObject(ObjectInputStream stream)
3963:                    throws IOException, ClassNotFoundException {
3964:
3965:                stream.defaultReadObject();
3966:
3967:                initInternal();
3968:
3969:                isTimeSet = true;
3970:                areFieldsSet = areAllFieldsSet = false;
3971:                nextStamp = MINIMUM_USER_STAMP;
3972:            }
3973:
3974:            //----------------------------------------------------------------------
3975:            // Time -> Fields
3976:            //----------------------------------------------------------------------
3977:
3978:            /**
3979:             * Converts the current millisecond time value <code>time</code> to
3980:             * field values in <code>fields[]</code>.  This synchronizes the time
3981:             * field values with a new time that is set for the calendar.  The time
3982:             * is <em>not</em> recomputed first; to recompute the time, then the
3983:             * fields, call the <code>complete</code> method.
3984:             * @see #complete
3985:             * @stable ICU 2.0
3986:             */
3987:            protected void computeFields() {
3988:                int offsets[] = new int[2];
3989:                getTimeZone().getOffset(time, false, offsets);
3990:                long localMillis = time + offsets[0] + offsets[1];
3991:
3992:                // Mark fields as set.  Do this before calling handleComputeFields().
3993:                int mask = internalSetMask;
3994:                for (int i = 0; i < fields.length; ++i) {
3995:                    if ((mask & 1) == 0) {
3996:                        stamp[i] = INTERNALLY_SET;
3997:                    } else {
3998:                        stamp[i] = UNSET;
3999:                    }
4000:                    mask >>= 1;
4001:                }
4002:
4003:                // We used to check for and correct extreme millis values (near
4004:                // Long.MIN_VALUE or Long.MAX_VALUE) here.  Such values would cause
4005:                // overflows from positive to negative (or vice versa) and had to
4006:                // be manually tweaked.  We no longer need to do this because we
4007:                // have limited the range of supported dates to those that have a
4008:                // Julian day that fits into an int.  This allows us to implement a
4009:                // JULIAN_DAY field and also removes some inelegant code. - Liu
4010:                // 11/6/00
4011:
4012:                long days = floorDivide(localMillis, ONE_DAY);
4013:
4014:                fields[JULIAN_DAY] = (int) days + EPOCH_JULIAN_DAY;
4015:
4016:                // In some cases we will have to call this method again below to
4017:                // adjust for DST pushing us into the next Julian day.
4018:                computeGregorianAndDOWFields(fields[JULIAN_DAY]);
4019:
4020:                // Call framework method to have subclass compute its fields.
4021:                // These must include, at a minimum, MONTH, DAY_OF_MONTH,
4022:                // EXTENDED_YEAR, YEAR, DAY_OF_YEAR.  This method will call internalSet(),
4023:                // which will update stamp[].
4024:                handleComputeFields(fields[JULIAN_DAY]);
4025:
4026:                // Compute week-related fields, based on the subclass-computed
4027:                // fields computed by handleComputeFields().
4028:                computeWeekFields();
4029:
4030:                // Compute time-related fields.  These are indepent of the date and
4031:                // of the subclass algorithm.  They depend only on the local zone
4032:                // wall milliseconds in day.
4033:                int millisInDay = (int) (localMillis - (days * ONE_DAY));
4034:                fields[MILLISECONDS_IN_DAY] = millisInDay;
4035:                fields[MILLISECOND] = millisInDay % 1000;
4036:                millisInDay /= 1000;
4037:                fields[SECOND] = millisInDay % 60;
4038:                millisInDay /= 60;
4039:                fields[MINUTE] = millisInDay % 60;
4040:                millisInDay /= 60;
4041:                fields[HOUR_OF_DAY] = millisInDay;
4042:                fields[AM_PM] = millisInDay / 12; // Assume AM == 0
4043:                fields[HOUR] = millisInDay % 12;
4044:                fields[ZONE_OFFSET] = offsets[0];
4045:                fields[DST_OFFSET] = offsets[1];
4046:            }
4047:
4048:            /**
4049:             * Compute the Gregorian calendar year, month, and day of month from
4050:             * the given Julian day.  These values are not stored in fields, but in
4051:             * member variables gregorianXxx.  Also compute the DAY_OF_WEEK and
4052:             * DOW_LOCAL fields.
4053:             */
4054:            private final void computeGregorianAndDOWFields(int julianDay) {
4055:                computeGregorianFields(julianDay);
4056:
4057:                // Compute day of week: JD 0 = Monday
4058:                int dow = fields[DAY_OF_WEEK] = julianDayToDayOfWeek(julianDay);
4059:
4060:                // Calculate 1-based localized day of week
4061:                int dowLocal = dow - getFirstDayOfWeek() + 1;
4062:                if (dowLocal < 1) {
4063:                    dowLocal += 7;
4064:                }
4065:                fields[DOW_LOCAL] = dowLocal;
4066:            }
4067:
4068:            /**
4069:             * Compute the Gregorian calendar year, month, and day of month from the
4070:             * Julian day.  These values are not stored in fields, but in member
4071:             * variables gregorianXxx.  They are used for time zone computations and by
4072:             * subclasses that are Gregorian derivatives.  Subclasses may call this
4073:             * method to perform a Gregorian calendar millis->fields computation.
4074:             * To perform a Gregorian calendar fields->millis computation, call
4075:             * computeGregorianMonthStart().
4076:             * @see #computeGregorianMonthStart
4077:             * @stable ICU 2.0
4078:             */
4079:            protected final void computeGregorianFields(int julianDay) {
4080:                int year, month, dayOfMonth, dayOfYear;
4081:
4082:                // The Gregorian epoch day is zero for Monday January 1, year 1.
4083:                long gregorianEpochDay = julianDay - JAN_1_1_JULIAN_DAY;
4084:
4085:                // Here we convert from the day number to the multiple radix
4086:                // representation.  We use 400-year, 100-year, and 4-year cycles.
4087:                // For example, the 4-year cycle has 4 years + 1 leap day; giving
4088:                // 1461 == 365*4 + 1 days.
4089:                int[] rem = new int[1];
4090:                int n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length
4091:                int n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length
4092:                int n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length
4093:                int n1 = floorDivide(rem[0], 365, rem);
4094:                year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
4095:                dayOfYear = rem[0]; // zero-based day of year
4096:                if (n100 == 4 || n1 == 4) {
4097:                    dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
4098:                } else {
4099:                    ++year;
4100:                }
4101:
4102:                boolean isLeap = ((year & 0x3) == 0) && // equiv. to (year%4 == 0)
4103:                        (year % 100 != 0 || year % 400 == 0);
4104:
4105:                int correction = 0;
4106:                int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
4107:                if (dayOfYear >= march1)
4108:                    correction = isLeap ? 1 : 2;
4109:                month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
4110:                dayOfMonth = dayOfYear
4111:                        - GREGORIAN_MONTH_COUNT[month][isLeap ? 3 : 2] + 1; // one-based DOM
4112:
4113:                gregorianYear = year;
4114:                gregorianMonth = month; // 0-based already
4115:                gregorianDayOfMonth = dayOfMonth; // 1-based already
4116:                gregorianDayOfYear = dayOfYear + 1; // Convert from 0-based to 1-based
4117:            }
4118:
4119:            /**
4120:             * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH,
4121:             * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR,
4122:             * DAY_OF_WEEK, and DAY_OF_YEAR.  The latter fields are computed by the
4123:             * subclass based on the calendar system.
4124:             *
4125:             * <p>The YEAR_WOY field is computed simplistically.  It is equal to YEAR
4126:             * most of the time, but at the year boundary it may be adjusted to YEAR-1
4127:             * or YEAR+1 to reflect the overlap of a week into an adjacent year.  In
4128:             * this case, a simple increment or decrement is performed on YEAR, even
4129:             * though this may yield an invalid YEAR value.  For instance, if the YEAR
4130:             * is part of a calendar system with an N-year cycle field CYCLE, then
4131:             * incrementing the YEAR may involve incrementing CYCLE and setting YEAR
4132:             * back to 0 or 1.  This is not handled by this code, and in fact cannot be
4133:             * simply handled without having subclasses define an entire parallel set of
4134:             * fields for fields larger than or equal to a year.  This additional
4135:             * complexity is not warranted, since the intention of the YEAR_WOY field is
4136:             * to support ISO 8601 notation, so it will typically be used with a
4137:             * proleptic Gregorian calendar, which has no field larger than a year.
4138:             */
4139:            private final void computeWeekFields() {
4140:                int eyear = fields[EXTENDED_YEAR];
4141:                int year = fields[YEAR];
4142:                int dayOfWeek = fields[DAY_OF_WEEK];
4143:                int dayOfYear = fields[DAY_OF_YEAR];
4144:
4145:                // WEEK_OF_YEAR start
4146:                // Compute the week of the year.  For the Gregorian calendar, valid week
4147:                // numbers run from 1 to 52 or 53, depending on the year, the first day
4148:                // of the week, and the minimal days in the first week.  For other
4149:                // calendars, the valid range may be different -- it depends on the year
4150:                // length.  Days at the start of the year may fall into the last week of
4151:                // the previous year; days at the end of the year may fall into the
4152:                // first week of the next year.  ASSUME that the year length is less than
4153:                // 7000 days.
4154:                int yearOfWeekOfYear = year;
4155:                int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
4156:                int relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6
4157:                int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
4158:                if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
4159:                    ++woy;
4160:                }
4161:
4162:                // Adjust for weeks at the year end that overlap into the previous or
4163:                // next calendar year.
4164:                if (woy == 0) {
4165:                    // We are the last week of the previous year.
4166:                    // Check to see if we are in the last week; if so, we need
4167:                    // to handle the case in which we are the first week of the
4168:                    // next year.
4169:
4170:                    int prevDoy = dayOfYear + handleGetYearLength(eyear - 1);
4171:                    woy = weekNumber(prevDoy, dayOfWeek);
4172:                    yearOfWeekOfYear--;
4173:                } else {
4174:                    int lastDoy = handleGetYearLength(eyear);
4175:                    // Fast check: For it to be week 1 of the next year, the DOY
4176:                    // must be on or after L-5, where L is yearLength(), then it
4177:                    // cannot possibly be week 1 of the next year:
4178:                    //          L-5                  L
4179:                    // doy: 359 360 361 362 363 364 365 001
4180:                    // dow:      1   2   3   4   5   6   7
4181:                    if (dayOfYear >= (lastDoy - 5)) {
4182:                        int lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
4183:                        if (lastRelDow < 0) {
4184:                            lastRelDow += 7;
4185:                        }
4186:                        if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek())
4187:                                && ((dayOfYear + 7 - relDow) > lastDoy)) {
4188:                            woy = 1;
4189:                            yearOfWeekOfYear++;
4190:                        }
4191:                    }
4192:                }
4193:                fields[WEEK_OF_YEAR] = woy;
4194:                fields[YEAR_WOY] = yearOfWeekOfYear;
4195:                // WEEK_OF_YEAR end
4196:
4197:                int dayOfMonth = fields[DAY_OF_MONTH];
4198:                fields[WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek);
4199:                fields[DAY_OF_WEEK_IN_MONTH] = (dayOfMonth - 1) / 7 + 1;
4200:            }
4201:
4202:            //----------------------------------------------------------------------
4203:            // Fields -> Time
4204:            //----------------------------------------------------------------------
4205:
4206:            /**
4207:             * Value to OR against resolve table field values for remapping.
4208:             * @see #resolveFields
4209:             * @stable ICU 2.0
4210:             */
4211:            protected static final int RESOLVE_REMAP = 32;
4212:            // A power of 2 greater than or equal to MAX_FIELD_COUNT
4213:
4214:            // Default table for day in year
4215:            static final int[][][] DATE_PRECEDENCE = {
4216:                    { { DAY_OF_MONTH }, { WEEK_OF_YEAR, DAY_OF_WEEK },
4217:                            { WEEK_OF_MONTH, DAY_OF_WEEK },
4218:                            { DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
4219:                            { WEEK_OF_YEAR, DOW_LOCAL },
4220:                            { WEEK_OF_MONTH, DOW_LOCAL },
4221:                            { DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
4222:                            { DAY_OF_YEAR }, },
4223:                    {
4224:                            { WEEK_OF_YEAR },
4225:                            { WEEK_OF_MONTH },
4226:                            { DAY_OF_WEEK_IN_MONTH },
4227:                            { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
4228:                            { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DOW_LOCAL }, }, };
4229:
4230:            static final int[][][] DOW_PRECEDENCE = { { { DAY_OF_WEEK },
4231:                    { DOW_LOCAL }, }, };
4232:
4233:            /**
4234:             * Given a precedence table, return the newest field combination in
4235:             * the table, or -1 if none is found.
4236:             *
4237:             * <p>The precedence table is a 3-dimensional array of integers.  It
4238:             * may be thought of as an array of groups.  Each group is an array of
4239:             * lines.  Each line is an array of field numbers.  Within a line, if
4240:             * all fields are set, then the time stamp of the line is taken to be
4241:             * the stamp of the most recently set field.  If any field of a line is
4242:             * unset, then the line fails to match.  Within a group, the line with
4243:             * the newest time stamp is selected.  The first field of the line is
4244:             * returned to indicate which line matched.
4245:             *
4246:             * <p>In some cases, it may be desirable to map a line to field that
4247:             * whose stamp is NOT examined.  For example, if the best field is
4248:             * DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used.  In
4249:             * order to do this, insert the value <code>REMAP_RESOLVE | F</code> at
4250:             * the start of the line, where <code>F</code> is the desired return
4251:             * field value.  This field will NOT be examined; it only determines
4252:             * the return value if the other fields in the line are the newest.
4253:             *
4254:             * <p>If all lines of a group contain at least one unset field, then no
4255:             * line will match, and the group as a whole will fail to match.  In
4256:             * that case, the next group will be processed.  If all groups fail to
4257:             * match, then -1 is returned.
4258:             * @stable ICU 2.0
4259:             */
4260:            protected int resolveFields(int[][][] precedenceTable) {
4261:                int bestField = -1;
4262:                for (int g = 0; g < precedenceTable.length && bestField < 0; ++g) {
4263:                    int[][] group = precedenceTable[g];
4264:                    int bestStamp = UNSET;
4265:                    linesInGroup: for (int l = 0; l < group.length; ++l) {
4266:                        int[] line = group[l];
4267:                        int lineStamp = UNSET;
4268:                        // Skip over first entry if it is negative
4269:                        for (int i = (line[0] >= RESOLVE_REMAP) ? 1 : 0; i < line.length; ++i) {
4270:                            int s = stamp[line[i]];
4271:                            // If any field is unset then don't use this line
4272:                            if (s == UNSET) {
4273:                                continue linesInGroup;
4274:                            } else {
4275:                                lineStamp = Math.max(lineStamp, s);
4276:                            }
4277:                        }
4278:                        // Record new maximum stamp & field no.
4279:                        if (lineStamp > bestStamp) {
4280:                            bestStamp = lineStamp;
4281:                            bestField = line[0]; // First field refers to entire line
4282:                        }
4283:                    }
4284:                }
4285:                return (bestField >= RESOLVE_REMAP) ? (bestField & (RESOLVE_REMAP - 1))
4286:                        : bestField;
4287:            }
4288:
4289:            /**
4290:             * Return the newest stamp of a given range of fields.
4291:             * @stable ICU 2.0
4292:             */
4293:            protected int newestStamp(int first, int last, int bestStampSoFar) {
4294:                int bestStamp = bestStampSoFar;
4295:                for (int i = first; i <= last; ++i) {
4296:                    if (stamp[i] > bestStamp) {
4297:                        bestStamp = stamp[i];
4298:                    }
4299:                }
4300:                return bestStamp;
4301:            }
4302:
4303:            /**
4304:             * Return the timestamp of a field.
4305:             * @stable ICU 2.0
4306:             */
4307:            protected final int getStamp(int field) {
4308:                return stamp[field];
4309:            }
4310:
4311:            /**
4312:             * Return the field that is newer, either defaultField, or
4313:             * alternateField.  If neither is newer or neither is set, return defaultField.
4314:             * @stable ICU 2.0
4315:             */
4316:            protected int newerField(int defaultField, int alternateField) {
4317:                if (stamp[alternateField] > stamp[defaultField]) {
4318:                    return alternateField;
4319:                }
4320:                return defaultField;
4321:            }
4322:
4323:            /**
4324:             * Ensure that each field is within its valid range by calling {@link
4325:             * #validateField(int)} on each field that has been set.  This method
4326:             * should only be called if this calendar is not lenient.
4327:             * @see #isLenient
4328:             * @see #validateField(int)
4329:             * @stable ICU 2.0
4330:             */
4331:            protected void validateFields() {
4332:                for (int field = 0; field < fields.length; field++) {
4333:                    if (isSet(field)) {
4334:                        validateField(field);
4335:                    }
4336:                }
4337:            }
4338:
4339:            /**
4340:             * Validate a single field of this calendar.  Subclasses should
4341:             * override this method to validate any calendar-specific fields.
4342:             * Generic fields can be handled by
4343:             * <code>Calendar.validateField()</code>.
4344:             * @see #validateField(int, int, int)
4345:             * @stable ICU 2.0
4346:             */
4347:            protected void validateField(int field) {
4348:                int y;
4349:                switch (field) {
4350:                case DAY_OF_MONTH:
4351:                    y = handleGetExtendedYear();
4352:                    validateField(field, 1, handleGetMonthLength(y,
4353:                            internalGet(MONTH)));
4354:                    break;
4355:                case DAY_OF_YEAR:
4356:                    y = handleGetExtendedYear();
4357:                    validateField(field, 1, handleGetYearLength(y));
4358:                    break;
4359:                case DAY_OF_WEEK_IN_MONTH:
4360:                    if (internalGet(field) == 0) {
4361:                        throw new IllegalArgumentException(
4362:                                "DAY_OF_WEEK_IN_MONTH cannot be zero");
4363:                    }
4364:                    validateField(field, getMinimum(field), getMaximum(field));
4365:                    break;
4366:                default:
4367:                    validateField(field, getMinimum(field), getMaximum(field));
4368:                    break;
4369:                }
4370:            }
4371:
4372:            /**
4373:             * Validate a single field of this calendar given its minimum and
4374:             * maximum allowed value.  If the field is out of range, throw a
4375:             * descriptive <code>IllegalArgumentException</code>.  Subclasses may
4376:             * use this method in their implementation of {@link
4377:             * #validateField(int)}.
4378:             * @stable ICU 2.0
4379:             */
4380:            protected final void validateField(int field, int min, int max) {
4381:                int value = fields[field];
4382:                if (value < min || value > max) {
4383:                    throw new IllegalArgumentException(fieldName(field) + '='
4384:                            + value + ", valid range=" + min + ".." + max);
4385:                }
4386:            }
4387:
4388:            /**
4389:             * Converts the current field values in <code>fields[]</code> to the
4390:             * millisecond time value <code>time</code>.
4391:             * @stable ICU 2.0
4392:             */
4393:            protected void computeTime() {
4394:                if (!isLenient()) {
4395:                    validateFields();
4396:                }
4397:
4398:                // Compute the Julian day
4399:                int julianDay = computeJulianDay();
4400:
4401:                long millis = julianDayToMillis(julianDay);
4402:
4403:                int millisInDay;
4404:
4405:                // We only use MILLISECONDS_IN_DAY if it has been set by the user.
4406:                // This makes it possible for the caller to set the calendar to a
4407:                // time and call clear(MONTH) to reset the MONTH to January.  This
4408:                // is legacy behavior.  Without this, clear(MONTH) has no effect,
4409:                // since the internally set JULIAN_DAY is used.
4410:                if (stamp[MILLISECONDS_IN_DAY] >= MINIMUM_USER_STAMP
4411:                        && newestStamp(AM_PM, MILLISECOND, UNSET) <= stamp[MILLISECONDS_IN_DAY]) {
4412:                    millisInDay = internalGet(MILLISECONDS_IN_DAY);
4413:                } else {
4414:                    millisInDay = computeMillisInDay();
4415:                }
4416:
4417:                // Compute the time zone offset and DST offset.  There are two potential
4418:                // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
4419:                // for discussion purposes here.
4420:                // 1. The transition into DST.  Here, a designated time of 2:00 am - 2:59 am
4421:                //    can be in standard or in DST depending.  However, 2:00 am is an invalid
4422:                //    representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
4423:                //    We assume standard time.
4424:                // 2. The transition out of DST.  Here, a designated time of 1:00 am - 1:59 am
4425:                //    can be in standard or DST.  Both are valid representations (the rep
4426:                //    jumps from 1:59:59 DST to 1:00:00 Std).
4427:                //    Again, we assume standard time.
4428:                // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
4429:                // or DST_OFFSET fields; then we use those fields.
4430:                if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP
4431:                        || stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
4432:                    millisInDay -= internalGet(ZONE_OFFSET)
4433:                            + internalGet(DST_OFFSET);
4434:                } else {
4435:                    millisInDay -= computeZoneOffset(millis, millisInDay);
4436:                }
4437:
4438:                time = millis + millisInDay;
4439:            }
4440:
4441:            /**
4442:             * Compute the milliseconds in the day from the fields.  This is a
4443:             * value from 0 to 23:59:59.999 inclusive, unless fields are out of
4444:             * range, in which case it can be an arbitrary value.  This value
4445:             * reflects local zone wall time.
4446:             * @stable ICU 2.0
4447:             */
4448:            protected int computeMillisInDay() {
4449:                // Do the time portion of the conversion.
4450:
4451:                int millisInDay = 0;
4452:
4453:                // Find the best set of fields specifying the time of day.  There
4454:                // are only two possibilities here; the HOUR_OF_DAY or the
4455:                // AM_PM and the HOUR.
4456:                int hourOfDayStamp = stamp[HOUR_OF_DAY];
4457:                int hourStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
4458:                int bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp
4459:                        : hourOfDayStamp;
4460:
4461:                // Hours
4462:                if (bestStamp != UNSET) {
4463:                    if (bestStamp == hourOfDayStamp) {
4464:                        // Don't normalize here; let overflow bump into the next period.
4465:                        // This is consistent with how we handle other fields.
4466:                        millisInDay += internalGet(HOUR_OF_DAY);
4467:                    } else {
4468:                        // Don't normalize here; let overflow bump into the next period.
4469:                        // This is consistent with how we handle other fields.
4470:                        millisInDay += internalGet(HOUR);
4471:                        millisInDay += 12 * internalGet(AM_PM); // Default works for unset AM_PM
4472:                    }
4473:                }
4474:
4475:                // We use the fact that unset == 0; we start with millisInDay
4476:                // == HOUR_OF_DAY.
4477:                millisInDay *= 60;
4478:                millisInDay += internalGet(MINUTE); // now have minutes
4479:                millisInDay *= 60;
4480:                millisInDay += internalGet(SECOND); // now have seconds
4481:                millisInDay *= 1000;
4482:                millisInDay += internalGet(MILLISECOND); // now have millis
4483:
4484:                return millisInDay;
4485:            }
4486:
4487:            /**
4488:             * This method can assume EXTENDED_YEAR has been set.
4489:             * @param millis milliseconds of the date fields (local midnight millis)
4490:             * @param millisInDay milliseconds of the time fields; may be out
4491:             * or range.
4492:             * @return total zone offset (raw + DST) for the given moment
4493:             * @stable ICU 2.0
4494:             */
4495:            protected int computeZoneOffset(long millis, int millisInDay) {
4496:                int offsets[] = new int[2];
4497:                zone.getOffset(millis + millisInDay, true, offsets);
4498:                return offsets[0] + offsets[1];
4499:
4500:                // Note: Because we pass in wall millisInDay, rather than
4501:                // standard millisInDay, we interpret "1:00 am" on the day
4502:                // of cessation of DST as "1:00 am Std" (assuming the time
4503:                // of cessation is 2:00 am).
4504:            }
4505:
4506:            /**
4507:             * Compute the Julian day number as specified by this calendar's fields.
4508:             * @stable ICU 2.0
4509:             */
4510:            protected int computeJulianDay() {
4511:
4512:                // We want to see if any of the date fields is newer than the
4513:                // JULIAN_DAY.  If not, then we use JULIAN_DAY.  If so, then we do
4514:                // the normal resolution.  We only use JULIAN_DAY if it has been
4515:                // set by the user.  This makes it possible for the caller to set
4516:                // the calendar to a time and call clear(MONTH) to reset the MONTH
4517:                // to January.  This is legacy behavior.  Without this,
4518:                // clear(MONTH) has no effect, since the internally set JULIAN_DAY
4519:                // is used.
4520:                if (stamp[JULIAN_DAY] >= MINIMUM_USER_STAMP) {
4521:                    int bestStamp = newestStamp(ERA, DAY_OF_WEEK_IN_MONTH,
4522:                            UNSET);
4523:                    bestStamp = newestStamp(YEAR_WOY, EXTENDED_YEAR, bestStamp);
4524:                    if (bestStamp <= stamp[JULIAN_DAY]) {
4525:                        return internalGet(JULIAN_DAY);
4526:                    }
4527:                }
4528:
4529:                int bestField = resolveFields(getFieldResolutionTable());
4530:                if (bestField < 0) {
4531:                    bestField = DAY_OF_MONTH;
4532:                }
4533:
4534:                return handleComputeJulianDay(bestField);
4535:            }
4536:
4537:            /**
4538:             * Return the field resolution array for this calendar.  Calendars that
4539:             * define additional fields or change the semantics of existing fields
4540:             * should override this method to adjust the field resolution semantics
4541:             * accordingly.  Other subclasses should not override this method.
4542:             * @see #resolveFields
4543:             * @stable ICU 2.0
4544:             */
4545:            protected int[][][] getFieldResolutionTable() {
4546:                return DATE_PRECEDENCE;
4547:            }
4548:
4549:            /**
4550:             * Return the Julian day number of day before the first day of the
4551:             * given month in the given extended year.  Subclasses should override
4552:             * this method to implement their calendar system.
4553:             * @param eyear the extended year
4554:             * @param month the zero-based month, or 0 if useMonth is false
4555:             * @param useMonth if false, compute the day before the first day of
4556:             * the given year, otherwise, compute the day before the first day of
4557:             * the given month
4558:             * @return the Julian day number of the day before the first
4559:             * day of the given month and year
4560:             * @stable ICU 2.0
4561:             */
4562:            abstract protected int handleComputeMonthStart(int eyear,
4563:                    int month, boolean useMonth);
4564:
4565:            /**
4566:             * Return the extended year defined by the current fields.  This will
4567:             * use the EXTENDED_YEAR field or the YEAR and supra-year fields (such
4568:             * as ERA) specific to the calendar system, depending on which set of
4569:             * fields is newer.
4570:             * @return the extended year
4571:             * @stable ICU 2.0
4572:             */
4573:            abstract protected int handleGetExtendedYear();
4574:
4575:            // (The following method is not called because all existing subclasses
4576:            // override it.  2003-06-11 ICU 2.6 Alan)
4577:            ///CLOVER:OFF
4578:            /**
4579:             * Return the number of days in the given month of the given extended
4580:             * year of this calendar system.  Subclasses should override this
4581:             * method if they can provide a more correct or more efficient
4582:             * implementation than the default implementation in Calendar.
4583:             * @stable ICU 2.0
4584:             */
4585:            protected int handleGetMonthLength(int extendedYear, int month) {
4586:                return handleComputeMonthStart(extendedYear, month + 1, true)
4587:                        - handleComputeMonthStart(extendedYear, month, true);
4588:            }
4589:
4590:            ///CLOVER:ON
4591:
4592:            /**
4593:             * Return the number of days in the given extended year of this
4594:             * calendar system.  Subclasses should override this method if they can
4595:             * provide a more correct or more efficient implementation than the
4596:             * default implementation in Calendar.
4597:             * @stable ICU 2.0
4598:             */
4599:            protected int handleGetYearLength(int eyear) {
4600:                return handleComputeMonthStart(eyear + 1, 0, false)
4601:                        - handleComputeMonthStart(eyear, 0, false);
4602:            }
4603:
4604:            /**
4605:             * Subclasses that use additional fields beyond those defined in
4606:             * <code>Calendar</code> should override this method to return an
4607:             * <code>int[]</code> array of the appropriate length.  The length
4608:             * must be at least <code>BASE_FIELD_COUNT</code> and no more than
4609:             * <code>MAX_FIELD_COUNT</code>.
4610:             * @stable ICU 2.0
4611:             */
4612:            protected int[] handleCreateFields() {
4613:                return new int[BASE_FIELD_COUNT];
4614:            }
4615:
4616:            /**
4617:             * Subclasses may override this. 
4618:             * Called by handleComputeJulianDay.  Returns the default month (0-based) for the year,
4619:             * taking year and era into account.  Defaults to 0 (JANUARY) for Gregorian.
4620:             * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
4621:             * @return the default month
4622:             * @provisional ICU 3.6
4623:             * @draft ICU 3.6
4624:             * @see #MONTH
4625:             */
4626:            protected int getDefaultMonthInYear(int extendedYear) {
4627:                return Calendar.JANUARY;
4628:            }
4629:
4630:            /**
4631:             * Subclasses may override this. 
4632:             * Called by handleComputeJulianDay.  Returns the default day (1-based) for the month,
4633:             * taking currently-set year and era into account.  Defaults to 1 for Gregorian.
4634:             * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
4635:             * @param month the month, as returned by getDefaultMonthInYear
4636:             * @return the default day of the month
4637:             * @draft ICU 3.6
4638:             * @provisional ICU 3.6
4639:             * @see #DAY_OF_MONTH
4640:             */
4641:            protected int getDefaultDayInMonth(int extendedYear, int month) {
4642:                return 1;
4643:            }
4644:
4645:            /**
4646:             * Subclasses may override this.  This method calls
4647:             * handleGetMonthLength() to obtain the calendar-specific month
4648:             * length.
4649:             * @stable ICU 2.0
4650:             */
4651:            protected int handleComputeJulianDay(int bestField) {
4652:
4653:                boolean useMonth = (bestField == DAY_OF_MONTH
4654:                        || bestField == WEEK_OF_MONTH || bestField == DAY_OF_WEEK_IN_MONTH);
4655:
4656:                int year = handleGetExtendedYear();
4657:                internalSet(EXTENDED_YEAR, year);
4658:
4659:                int month = useMonth ? internalGet(MONTH,
4660:                        getDefaultMonthInYear(year)) : 0;
4661:
4662:                int dom = internalGet(DAY_OF_MONTH, getDefaultDayInMonth(year,
4663:                        month));
4664:
4665:                // Get the Julian day of the day BEFORE the start of this year.
4666:                // If useMonth is true, get the day before the start of the month.
4667:                int julianDay = handleComputeMonthStart(year, month, useMonth);
4668:
4669:                if (bestField == DAY_OF_MONTH) {
4670:                    if (isSet(DAY_OF_MONTH)) {
4671:                        return julianDay
4672:                                + internalGet(DAY_OF_MONTH,
4673:                                        getDefaultDayInMonth(year, month));
4674:                    } else {
4675:                        return julianDay + getDefaultDayInMonth(year, month);
4676:                    }
4677:                }
4678:
4679:                if (bestField == DAY_OF_YEAR) {
4680:                    return julianDay + internalGet(DAY_OF_YEAR);
4681:                }
4682:
4683:                int firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw
4684:
4685:                // At this point julianDay is the 0-based day BEFORE the first day of
4686:                // January 1, year 1 of the given calendar.  If julianDay == 0, it
4687:                // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
4688:                // or Gregorian).
4689:
4690:                // At this point we need to process the WEEK_OF_MONTH or
4691:                // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
4692:                // First, perform initial shared computations.  These locate the
4693:                // first week of the period.
4694:
4695:                // Get the 0-based localized DOW of day one of the month or year.
4696:                // Valid range 0..6.
4697:                int first = julianDayToDayOfWeek(julianDay + 1)
4698:                        - firstDayOfWeek;
4699:                if (first < 0) {
4700:                    first += 7;
4701:                }
4702:
4703:                // Get zero-based localized DOW, valid range 0..6.  This is the DOW
4704:                // we are looking for.
4705:                int dowLocal = 0;
4706:                switch (resolveFields(DOW_PRECEDENCE)) {
4707:                case DAY_OF_WEEK:
4708:                    dowLocal = internalGet(DAY_OF_WEEK) - firstDayOfWeek;
4709:                    break;
4710:                case DOW_LOCAL:
4711:                    dowLocal = internalGet(DOW_LOCAL) - 1;
4712:                    break;
4713:                }
4714:                dowLocal = dowLocal % 7;
4715:                if (dowLocal < 0) {
4716:                    dowLocal += 7;
4717:                }
4718:
4719:                // Find the first target DOW (dowLocal) in the month or year.
4720:                // Actually, it may be just before the first of the month or year.
4721:                // It will be an integer from -5..7.
4722:                int date = 1 - first + dowLocal;
4723:
4724:                if (bestField == DAY_OF_WEEK_IN_MONTH) {
4725:
4726:                    // Adjust the target DOW to be in the month or year.
4727:                    if (date < 1) {
4728:                        date += 7;
4729:                    }
4730:
4731:                    // The only trickiness occurs if the day-of-week-in-month is
4732:                    // negative.
4733:                    int dim = internalGet(DAY_OF_WEEK_IN_MONTH, 1);
4734:                    if (dim >= 0) {
4735:                        date += 7 * (dim - 1);
4736:
4737:                    } else {
4738:                        // Move date to the last of this day-of-week in this month,
4739:                        // then back up as needed.  If dim==-1, we don't back up at
4740:                        // all.  If dim==-2, we back up once, etc.  Don't back up
4741:                        // past the first of the given day-of-week in this month.
4742:                        // Note that we handle -2, -3, etc. correctly, even though
4743:                        // values < -1 are technically disallowed.
4744:                        int m = internalGet(MONTH, JANUARY);
4745:                        int monthLength = handleGetMonthLength(year, m);
4746:                        date += ((monthLength - date) / 7 + dim + 1) * 7;
4747:                    }
4748:                } else {
4749:                    // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR)
4750:
4751:                    // Adjust for minimal days in first week
4752:                    if ((7 - first) < getMinimalDaysInFirstWeek()) {
4753:                        date += 7;
4754:                    }
4755:
4756:                    // Now adjust for the week number.
4757:                    date += 7 * (internalGet(bestField) - 1);
4758:                }
4759:
4760:                return julianDay + date;
4761:            }
4762:
4763:            /**
4764:             * Compute the Julian day of a month of the Gregorian calendar.
4765:             * Subclasses may call this method to perform a Gregorian calendar
4766:             * fields->millis computation.  To perform a Gregorian calendar
4767:             * millis->fields computation, call computeGregorianFields().
4768:             * @param year extended Gregorian year
4769:             * @param month zero-based Gregorian month
4770:             * @return the Julian day number of the day before the first
4771:             * day of the given month in the given extended year
4772:             * @see #computeGregorianFields
4773:             * @stable ICU 2.0
4774:             */
4775:            protected int computeGregorianMonthStart(int year, int month) {
4776:
4777:                // If the month is out of range, adjust it into range, and
4778:                // modify the extended year value accordingly.
4779:                if (month < 0 || month > 11) {
4780:                    int[] rem = new int[1];
4781:                    year += floorDivide(month, 12, rem);
4782:                    month = rem[0];
4783:                }
4784:
4785:                boolean isLeap = (year % 4 == 0)
4786:                        && ((year % 100 != 0) || (year % 400 == 0));
4787:                int y = year - 1;
4788:                // This computation is actually ... + (JAN_1_1_JULIAN_DAY - 3) + 2.
4789:                // Add 2 because Gregorian calendar starts 2 days after Julian
4790:                // calendar.
4791:                int julianDay = 365 * y + floorDivide(y, 4)
4792:                        - floorDivide(y, 100) + floorDivide(y, 400)
4793:                        + JAN_1_1_JULIAN_DAY - 1;
4794:
4795:                // At this point julianDay indicates the day BEFORE the first day
4796:                // of January 1, <eyear> of the Gregorian calendar.
4797:                if (month != 0) {
4798:                    julianDay += GREGORIAN_MONTH_COUNT[month][isLeap ? 3 : 2];
4799:                }
4800:
4801:                return julianDay;
4802:            }
4803:
4804:            //----------------------------------------------------------------------
4805:            // Subclass API
4806:            // For subclasses to override
4807:            //----------------------------------------------------------------------
4808:
4809:            // (The following method is not called because all existing subclasses
4810:            // override it.  2003-06-11 ICU 2.6 Alan)
4811:            ///CLOVER:OFF
4812:            /**
4813:             * Subclasses may override this method to compute several fields
4814:             * specific to each calendar system.  These are:
4815:             *
4816:             * <ul><li>ERA
4817:             * <li>YEAR
4818:             * <li>MONTH
4819:             * <li>DAY_OF_MONTH
4820:             * <li>DAY_OF_YEAR
4821:             * <li>EXTENDED_YEAR</ul>
4822:             *
4823:             * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, which
4824:             * will be set when this method is called.  Subclasses can also call
4825:             * the getGregorianXxx() methods to obtain Gregorian calendar
4826:             * equivalents for the given Julian day.
4827:             *
4828:             * <p>In addition, subclasses should compute any subclass-specific
4829:             * fields, that is, fields from BASE_FIELD_COUNT to
4830:             * getFieldCount() - 1.
4831:             *
4832:             * <p>The default implementation in <code>Calendar</code> implements
4833:             * a pure proleptic Gregorian calendar.
4834:             * @stable ICU 2.0
4835:             */
4836:            protected void handleComputeFields(int julianDay) {
4837:                internalSet(MONTH, getGregorianMonth());
4838:                internalSet(DAY_OF_MONTH, getGregorianDayOfMonth());
4839:                internalSet(DAY_OF_YEAR, getGregorianDayOfYear());
4840:                int eyear = getGregorianYear();
4841:                internalSet(EXTENDED_YEAR, eyear);
4842:                int era = GregorianCalendar.AD;
4843:                if (eyear < 1) {
4844:                    era = GregorianCalendar.BC;
4845:                    eyear = 1 - eyear;
4846:                }
4847:                internalSet(ERA, era);
4848:                internalSet(YEAR, eyear);
4849:            }
4850:
4851:            ///CLOVER:ON
4852:
4853:            //----------------------------------------------------------------------
4854:            // Subclass API
4855:            // For subclasses to call
4856:            //----------------------------------------------------------------------
4857:
4858:            /**
4859:             * Return the extended year on the Gregorian calendar as computed by
4860:             * <code>computeGregorianFields()</code>.
4861:             * @see #computeGregorianFields
4862:             * @stable ICU 2.0
4863:             */
4864:            protected final int getGregorianYear() {
4865:                return gregorianYear;
4866:            }
4867:
4868:            /**
4869:             * Return the month (0-based) on the Gregorian calendar as computed by
4870:             * <code>computeGregorianFields()</code>.
4871:             * @see #computeGregorianFields
4872:             * @stable ICU 2.0
4873:             */
4874:            protected final int getGregorianMonth() {
4875:                return gregorianMonth;
4876:            }
4877:
4878:            /**
4879:             * Return the day of year (1-based) on the Gregorian calendar as
4880:             * computed by <code>computeGregorianFields()</code>.
4881:             * @see #computeGregorianFields
4882:             * @stable ICU 2.0
4883:             */
4884:            protected final int getGregorianDayOfYear() {
4885:                return gregorianDayOfYear;
4886:            }
4887:
4888:            /**
4889:             * Return the day of month (1-based) on the Gregorian calendar as
4890:             * computed by <code>computeGregorianFields()</code>.
4891:             * @see #computeGregorianFields
4892:             * @stable ICU 2.0
4893:             */
4894:            protected final int getGregorianDayOfMonth() {
4895:                return gregorianDayOfMonth;
4896:            }
4897:
4898:            /**
4899:             * Return the number of fields defined by this calendar.  Valid field
4900:             * arguments to <code>set()</code> and <code>get()</code> are
4901:             * <code>0..getFieldCount()-1</code>.
4902:             * @stable ICU 2.0
4903:             */
4904:            public final int getFieldCount() {
4905:                return fields.length;
4906:            }
4907:
4908:            /**
4909:             * Set a field to a value.  Subclasses should use this method when
4910:             * computing fields.  It sets the time stamp in the
4911:             * <code>stamp[]</code> array to <code>INTERNALLY_SET</code>.  If a
4912:             * field that may not be set by subclasses is passed in, an
4913:             * <code>IllegalArgumentException</code> is thrown.  This prevents
4914:             * subclasses from modifying fields that are intended to be
4915:             * calendar-system invariant.
4916:             * @stable ICU 2.0
4917:             */
4918:            protected final void internalSet(int field, int value) {
4919:                if (((1 << field) & internalSetMask) == 0) {
4920:                    throw new IllegalStateException("Subclass cannot set "
4921:                            + fieldName(field));
4922:                }
4923:                fields[field] = value;
4924:                stamp[field] = INTERNALLY_SET;
4925:            }
4926:
4927:            private static final int[][] GREGORIAN_MONTH_COUNT = {
4928:            //len len2   st  st2
4929:                    { 31, 31, 0, 0 }, // Jan
4930:                    { 28, 29, 31, 31 }, // Feb
4931:                    { 31, 31, 59, 60 }, // Mar
4932:                    { 30, 30, 90, 91 }, // Apr
4933:                    { 31, 31, 120, 121 }, // May
4934:                    { 30, 30, 151, 152 }, // Jun
4935:                    { 31, 31, 181, 182 }, // Jul
4936:                    { 31, 31, 212, 213 }, // Aug
4937:                    { 30, 30, 243, 244 }, // Sep
4938:                    { 31, 31, 273, 274 }, // Oct
4939:                    { 30, 30, 304, 305 }, // Nov
4940:                    { 31, 31, 334, 335 } // Dec
4941:            // len  length of month
4942:            // len2 length of month in a leap year
4943:            // st   days in year before start of month
4944:            // st2  days in year before month in leap year
4945:            };
4946:
4947:            /**
4948:             * Determines if the given year is a leap year. Returns true if the
4949:             * given year is a leap year.
4950:             * @param year the given year.
4951:             * @return true if the given year is a leap year; false otherwise.
4952:             * @stable ICU 2.0
4953:             */
4954:            protected static final boolean isGregorianLeapYear(int year) {
4955:                return (year % 4 == 0)
4956:                        && ((year % 100 != 0) || (year % 400 == 0));
4957:            }
4958:
4959:            /**
4960:             * Return the length of a month of the Gregorian calendar.
4961:             * @param y the extended year
4962:             * @param m the 0-based month number
4963:             * @return the number of days in the given month
4964:             * @stable ICU 2.0
4965:             */
4966:            protected static final int gregorianMonthLength(int y, int m) {
4967:                return GREGORIAN_MONTH_COUNT[m][isGregorianLeapYear(y) ? 1 : 0];
4968:            }
4969:
4970:            /**
4971:             * Return the length of a previous month of the Gregorian calendar.
4972:             * @param y the extended year
4973:             * @param m the 0-based month number
4974:             * @return the number of days in the month previous to the given month
4975:             * @stable ICU 2.0
4976:             */
4977:            protected static final int gregorianPreviousMonthLength(int y, int m) {
4978:                return (m > 0) ? gregorianMonthLength(y, m - 1) : 31;
4979:            }
4980:
4981:            /**
4982:             * Divide two long integers, returning the floor of the quotient.
4983:             * <p>
4984:             * Unlike the built-in division, this is mathematically well-behaved.
4985:             * E.g., <code>-1/4</code> => 0
4986:             * but <code>floorDivide(-1,4)</code> => -1.
4987:             * @param numerator the numerator
4988:             * @param denominator a divisor which must be > 0
4989:             * @return the floor of the quotient.
4990:             * @stable ICU 2.0
4991:             */
4992:            protected static final long floorDivide(long numerator,
4993:                    long denominator) {
4994:                // We do this computation in order to handle
4995:                // a numerator of Long.MIN_VALUE correctly
4996:                return (numerator >= 0) ? numerator / denominator
4997:                        : ((numerator + 1) / denominator) - 1;
4998:            }
4999:
5000:            /**
5001:             * Divide two integers, returning the floor of the quotient.
5002:             * <p>
5003:             * Unlike the built-in division, this is mathematically well-behaved.
5004:             * E.g., <code>-1/4</code> => 0
5005:             * but <code>floorDivide(-1,4)</code> => -1.
5006:             * @param numerator the numerator
5007:             * @param denominator a divisor which must be > 0
5008:             * @return the floor of the quotient.
5009:             * @stable ICU 2.0
5010:             */
5011:            protected static final int floorDivide(int numerator,
5012:                    int denominator) {
5013:                // We do this computation in order to handle
5014:                // a numerator of Integer.MIN_VALUE correctly
5015:                return (numerator >= 0) ? numerator / denominator
5016:                        : ((numerator + 1) / denominator) - 1;
5017:            }
5018:
5019:            /**
5020:             * Divide two integers, returning the floor of the quotient, and
5021:             * the modulus remainder.
5022:             * <p>
5023:             * Unlike the built-in division, this is mathematically well-behaved.
5024:             * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
5025:             * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
5026:             * @param numerator the numerator
5027:             * @param denominator a divisor which must be > 0
5028:             * @param remainder an array of at least one element in which the value
5029:             * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
5030:             * % denominator</code>, this will always be non-negative.
5031:             * @return the floor of the quotient.
5032:             * @stable ICU 2.0
5033:             */
5034:            protected static final int floorDivide(int numerator,
5035:                    int denominator, int[] remainder) {
5036:                if (numerator >= 0) {
5037:                    remainder[0] = numerator % denominator;
5038:                    return numerator / denominator;
5039:                }
5040:                int quotient = ((numerator + 1) / denominator) - 1;
5041:                remainder[0] = numerator - (quotient * denominator);
5042:                return quotient;
5043:            }
5044:
5045:            /**
5046:             * Divide two integers, returning the floor of the quotient, and
5047:             * the modulus remainder.
5048:             * <p>
5049:             * Unlike the built-in division, this is mathematically well-behaved.
5050:             * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
5051:             * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
5052:             * @param numerator the numerator
5053:             * @param denominator a divisor which must be > 0
5054:             * @param remainder an array of at least one element in which the value
5055:             * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
5056:             * % denominator</code>, this will always be non-negative.
5057:             * @return the floor of the quotient.
5058:             * @stable ICU 2.0
5059:             */
5060:            protected static final int floorDivide(long numerator,
5061:                    int denominator, int[] remainder) {
5062:                if (numerator >= 0) {
5063:                    remainder[0] = (int) (numerator % denominator);
5064:                    return (int) (numerator / denominator);
5065:                }
5066:                int quotient = (int) (((numerator + 1) / denominator) - 1);
5067:                remainder[0] = (int) (numerator - (quotient * denominator));
5068:                return quotient;
5069:            }
5070:
5071:            private static final String[] FIELD_NAME = { "ERA", "YEAR",
5072:                    "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
5073:                    "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH",
5074:                    "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND",
5075:                    "MILLISECOND", "ZONE_OFFSET", "DST_OFFSET", "YEAR_WOY",
5076:                    "DOW_LOCAL", "EXTENDED_YEAR", "JULIAN_DAY",
5077:                    "MILLISECONDS_IN_DAY", };
5078:
5079:            /**
5080:             * Return a string name for a field, for debugging and exceptions.
5081:             * @stable ICU 2.0
5082:             */
5083:            protected String fieldName(int field) {
5084:                try {
5085:                    return FIELD_NAME[field];
5086:                } catch (ArrayIndexOutOfBoundsException e) {
5087:                    return "Field " + field;
5088:                }
5089:            }
5090:
5091:            /**
5092:             * Converts time as milliseconds to Julian day.
5093:             * @param millis the given milliseconds.
5094:             * @return the Julian day number.
5095:             * @stable ICU 2.0
5096:             */
5097:            protected static final int millisToJulianDay(long millis) {
5098:                return (int) (EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY));
5099:            }
5100:
5101:            /**
5102:             * Converts Julian day to time as milliseconds.
5103:             * @param julian the given Julian day number.
5104:             * @return time as milliseconds.
5105:             * @stable ICU 2.0
5106:             */
5107:            protected static final long julianDayToMillis(int julian) {
5108:                return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;
5109:            }
5110:
5111:            /**
5112:             * Return the day of week, from SUNDAY to SATURDAY, given a Julian day.
5113:             * @stable ICU 2.0
5114:             */
5115:            protected static final int julianDayToDayOfWeek(int julian) {
5116:                // If julian is negative, then julian%7 will be negative, so we adjust
5117:                // accordingly.  Julian day 0 is Monday.
5118:                int dayOfWeek = (julian + MONDAY) % 7;
5119:                if (dayOfWeek < SUNDAY) {
5120:                    dayOfWeek += 7;
5121:                }
5122:                return dayOfWeek;
5123:            }
5124:
5125:            /**
5126:             * Return the current milliseconds without recomputing.
5127:             * @stable ICU 2.0
5128:             */
5129:            protected final long internalGetTimeInMillis() {
5130:                return time;
5131:            }
5132:
5133:            /**
5134:             * Return the current Calendar type.
5135:             * Note, in 3.0 this function will return 'gregorian' in Calendar to emulate legacy behavior
5136:             * @return type of calendar (gregorian, etc)
5137:             * @internal ICU 3.0
5138:             * @deprecated This API is ICU internal only.
5139:             */
5140:            public String getType() {
5141:                return "gregorian";
5142:            }
5143:
5144:            // -------- BEGIN ULocale boilerplate --------
5145:
5146:            /**
5147:             * Return the locale that was used to create this object, or null.
5148:             * This may may differ from the locale requested at the time of
5149:             * this object's creation.  For example, if an object is created
5150:             * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
5151:             * drawn from <tt>en</tt> (the <i>actual</i> locale), and
5152:             * <tt>en_US</tt> may be the most specific locale that exists (the
5153:             * <i>valid</i> locale).
5154:             *
5155:             * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
5156:             * contains a partial preview implementation.  The * <i>actual</i>
5157:             * locale is returned correctly, but the <i>valid</i> locale is
5158:             * not, in most cases.
5159:             * @param type type of information requested, either {@link
5160:             * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
5161:             * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
5162:             * @return the information specified by <i>type</i>, or null if
5163:             * this object was not constructed from locale data.
5164:             * @see com.ibm.icu.util.ULocale
5165:             * @see com.ibm.icu.util.ULocale#VALID_LOCALE
5166:             * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
5167:             * @draft ICU 2.8 (retain)
5168:             * @provisional This API might change or be removed in a future release.
5169:             */
5170:            public final ULocale getLocale(ULocale.Type type) {
5171:                return type == ULocale.ACTUAL_LOCALE ? this .actualLocale
5172:                        : this .validLocale;
5173:            }
5174:
5175:            /**
5176:             * Set information about the locales that were used to create this
5177:             * object.  If the object was not constructed from locale data,
5178:             * both arguments should be set to null.  Otherwise, neither
5179:             * should be null.  The actual locale must be at the same level or
5180:             * less specific than the valid locale.  This method is intended
5181:             * for use by factories or other entities that create objects of
5182:             * this class.
5183:             * @param valid the most specific locale containing any resource
5184:             * data, or null
5185:             * @param actual the locale containing data used to construct this
5186:             * object, or null
5187:             * @see com.ibm.icu.util.ULocale
5188:             * @see com.ibm.icu.util.ULocale#VALID_LOCALE
5189:             * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
5190:             * @internal
5191:             */
5192:            final void setLocale(ULocale valid, ULocale actual) {
5193:                // Change the following to an assertion later
5194:                if ((valid == null) != (actual == null)) {
5195:                    ///CLOVER:OFF
5196:                    throw new IllegalArgumentException();
5197:                    ///CLOVER:ON
5198:                }
5199:                // Another check we could do is that the actual locale is at
5200:                // the same level or less specific than the valid locale.
5201:                this .validLocale = valid;
5202:                this .actualLocale = actual;
5203:            }
5204:
5205:            /**
5206:             * The most specific locale containing any resource data, or null.
5207:             * @see com.ibm.icu.util.ULocale
5208:             * @internal
5209:             */
5210:            private ULocale validLocale;
5211:
5212:            /**
5213:             * The locale containing data used to construct this object, or
5214:             * null.
5215:             * @see com.ibm.icu.util.ULocale
5216:             * @internal
5217:             */
5218:            private ULocale actualLocale;
5219:
5220:            // -------- END ULocale boilerplate --------
5221:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.