1/*
2* Copyright (C) 1997-2009, International Business Machines Corporation and others.
3* All Rights Reserved.
4********************************************************************************
5*
6* File GREGOCAL.H
7*
8* Modification History:
9*
10*   Date        Name        Description
11*   04/22/97    aliu        Overhauled header.
12*    07/28/98    stephen        Sync with JDK 1.2
13*    09/04/98    stephen        Re-sync with JDK 8/31 putback
14*    09/14/98    stephen        Changed type of kOneDay, kOneWeek to double.
15*                            Fixed bug in roll()
16*   10/15/99    aliu        Fixed j31, incorrect WEEK_OF_YEAR computation.
17*                           Added documentation of WEEK_OF_YEAR computation.
18*   10/15/99    aliu        Fixed j32, cannot set date to Feb 29 2000 AD.
19*                           {JDK bug 4210209 4209272}
20*   11/07/2003  srl         Update, clean up documentation.
21********************************************************************************
22*/
23
24#ifndef GREGOCAL_H
25#define GREGOCAL_H
26
27#include "unicode/utypes.h"
28
29#if !UCONFIG_NO_FORMATTING
30
31#include "unicode/calendar.h"
32
33/**
34 * \file
35 * \brief C++ API: Concrete class which provides the standard calendar.
36 */
37
38U_NAMESPACE_BEGIN
39
40/**
41 * Concrete class which provides the standard calendar used by most of the world.
42 * <P>
43 * The standard (Gregorian) calendar has 2 eras, BC and AD.
44 * <P>
45 * This implementation handles a single discontinuity, which corresponds by default to
46 * the date the Gregorian calendar was originally instituted (October 15, 1582). Not all
47 * countries adopted the Gregorian calendar then, so this cutover date may be changed by
48 * the caller.
49 * <P>
50 * Prior to the institution of the Gregorian Calendar, New Year's Day was March 25. To
51 * avoid confusion, this Calendar always uses January 1. A manual adjustment may be made
52 * if desired for dates that are prior to the Gregorian changeover and which fall
53 * between January 1 and March 24.
54 *
55 * <p>Values calculated for the <code>WEEK_OF_YEAR</code> field range from 1 to
56 * 53.  Week 1 for a year is the first week that contains at least
57 * <code>getMinimalDaysInFirstWeek()</code> days from that year.  It thus
58 * depends on the values of <code>getMinimalDaysInFirstWeek()</code>,
59 * <code>getFirstDayOfWeek()</code>, and the day of the week of January 1.
60 * Weeks between week 1 of one year and week 1 of the following year are
61 * numbered sequentially from 2 to 52 or 53 (as needed).
62 *
63 * <p>For example, January 1, 1998 was a Thursday.  If
64 * <code>getFirstDayOfWeek()</code> is <code>MONDAY</code> and
65 * <code>getMinimalDaysInFirstWeek()</code> is 4 (these are the values
66 * reflecting ISO 8601 and many national standards), then week 1 of 1998 starts
67 * on December 29, 1997, and ends on January 4, 1998.  If, however,
68 * <code>getFirstDayOfWeek()</code> is <code>SUNDAY</code>, then week 1 of 1998
69 * starts on January 4, 1998, and ends on January 10, 1998; the first three days
70 * of 1998 then are part of week 53 of 1997.
71 *
72 * <p>Example for using GregorianCalendar:
73 * <pre>
74 * \code
75 *     // get the supported ids for GMT-08:00 (Pacific Standard Time)
76 *     UErrorCode success = U_ZERO_ERROR;
77 *     const StringEnumeration *ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
78 *     // if no ids were returned, something is wrong. get out.
79 *     if (ids == 0 || ids->count(success) == 0) {
80 *         return;
81 *     }
82 *
83 *     // begin output
84 *     cout << "Current Time" << endl;
85 *
86 *     // create a Pacific Standard Time time zone
87 *     SimpleTimeZone* pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids->unext(NULL, success)));
88 *
89 *     // set up rules for daylight savings time
90 *     pdt->setStartRule(UCAL_MARCH, 1, UCAL_SUNDAY, 2 * 60 * 60 * 1000);
91 *     pdt->setEndRule(UCAL_NOVEMBER, 2, UCAL_SUNDAY, 2 * 60 * 60 * 1000);
92 *
93 *     // create a GregorianCalendar with the Pacific Daylight time zone
94 *     // and the current date and time
95 *     Calendar* calendar = new GregorianCalendar( pdt, success );
96 *
97 *     // print out a bunch of interesting things
98 *     cout << "ERA: " << calendar->get( UCAL_ERA, success ) << endl;
99 *     cout << "YEAR: " << calendar->get( UCAL_YEAR, success ) << endl;
100 *     cout << "MONTH: " << calendar->get( UCAL_MONTH, success ) << endl;
101 *     cout << "WEEK_OF_YEAR: " << calendar->get( UCAL_WEEK_OF_YEAR, success ) << endl;
102 *     cout << "WEEK_OF_MONTH: " << calendar->get( UCAL_WEEK_OF_MONTH, success ) << endl;
103 *     cout << "DATE: " << calendar->get( UCAL_DATE, success ) << endl;
104 *     cout << "DAY_OF_MONTH: " << calendar->get( UCAL_DAY_OF_MONTH, success ) << endl;
105 *     cout << "DAY_OF_YEAR: " << calendar->get( UCAL_DAY_OF_YEAR, success ) << endl;
106 *     cout << "DAY_OF_WEEK: " << calendar->get( UCAL_DAY_OF_WEEK, success ) << endl;
107 *     cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( UCAL_DAY_OF_WEEK_IN_MONTH, success ) << endl;
108 *     cout << "AM_PM: " << calendar->get( UCAL_AM_PM, success ) << endl;
109 *     cout << "HOUR: " << calendar->get( UCAL_HOUR, success ) << endl;
110 *     cout << "HOUR_OF_DAY: " << calendar->get( UCAL_HOUR_OF_DAY, success ) << endl;
111 *     cout << "MINUTE: " << calendar->get( UCAL_MINUTE, success ) << endl;
112 *     cout << "SECOND: " << calendar->get( UCAL_SECOND, success ) << endl;
113 *     cout << "MILLISECOND: " << calendar->get( UCAL_MILLISECOND, success ) << endl;
114 *     cout << "ZONE_OFFSET: " << (calendar->get( UCAL_ZONE_OFFSET, success )/(60*60*1000)) << endl;
115 *     cout << "DST_OFFSET: " << (calendar->get( UCAL_DST_OFFSET, success )/(60*60*1000)) << endl;
116 *
117 *     cout << "Current Time, with hour reset to 3" << endl;
118 *     calendar->clear(UCAL_HOUR_OF_DAY); // so doesn't override
119 *     calendar->set(UCAL_HOUR, 3);
120 *     cout << "ERA: " << calendar->get( UCAL_ERA, success ) << endl;
121 *     cout << "YEAR: " << calendar->get( UCAL_YEAR, success ) << endl;
122 *     cout << "MONTH: " << calendar->get( UCAL_MONTH, success ) << endl;
123 *     cout << "WEEK_OF_YEAR: " << calendar->get( UCAL_WEEK_OF_YEAR, success ) << endl;
124 *     cout << "WEEK_OF_MONTH: " << calendar->get( UCAL_WEEK_OF_MONTH, success ) << endl;
125 *     cout << "DATE: " << calendar->get( UCAL_DATE, success ) << endl;
126 *     cout << "DAY_OF_MONTH: " << calendar->get( UCAL_DAY_OF_MONTH, success ) << endl;
127 *     cout << "DAY_OF_YEAR: " << calendar->get( UCAL_DAY_OF_YEAR, success ) << endl;
128 *     cout << "DAY_OF_WEEK: " << calendar->get( UCAL_DAY_OF_WEEK, success ) << endl;
129 *     cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( UCAL_DAY_OF_WEEK_IN_MONTH, success ) << endl;
130 *     cout << "AM_PM: " << calendar->get( UCAL_AM_PM, success ) << endl;
131 *     cout << "HOUR: " << calendar->get( UCAL_HOUR, success ) << endl;
132 *     cout << "HOUR_OF_DAY: " << calendar->get( UCAL_HOUR_OF_DAY, success ) << endl;
133 *     cout << "MINUTE: " << calendar->get( UCAL_MINUTE, success ) << endl;
134 *     cout << "SECOND: " << calendar->get( UCAL_SECOND, success ) << endl;
135 *     cout << "MILLISECOND: " << calendar->get( UCAL_MILLISECOND, success ) << endl;
136 *     cout << "ZONE_OFFSET: " << (calendar->get( UCAL_ZONE_OFFSET, success )/(60*60*1000)) << endl; // in hours
137 *     cout << "DST_OFFSET: " << (calendar->get( UCAL_DST_OFFSET, success )/(60*60*1000)) << endl; // in hours
138 *
139 *     if (U_FAILURE(success)) {
140 *         cout << "An error occured. success=" << u_errorName(success) << endl;
141 *     }
142 *
143 *     delete ids;
144 *     delete calendar; // also deletes pdt
145 * \endcode
146 * </pre>
147 * @stable ICU 2.0
148 */
149class U_I18N_API GregorianCalendar: public Calendar {
150public:
151
152    /**
153     * Useful constants for GregorianCalendar and TimeZone.
154     * @stable ICU 2.0
155     */
156    enum EEras {
157        BC,
158        AD
159    };
160
161    /**
162     * Constructs a default GregorianCalendar using the current time in the default time
163     * zone with the default locale.
164     *
165     * @param success  Indicates the status of GregorianCalendar object construction.
166     *                 Returns U_ZERO_ERROR if constructed successfully.
167     * @stable ICU 2.0
168     */
169    GregorianCalendar(UErrorCode& success);
170
171    /**
172     * Constructs a GregorianCalendar based on the current time in the given time zone
173     * with the default locale. Clients are no longer responsible for deleting the given
174     * time zone object after it's adopted.
175     *
176     * @param zoneToAdopt     The given timezone.
177     * @param success  Indicates the status of GregorianCalendar object construction.
178     *                 Returns U_ZERO_ERROR if constructed successfully.
179     * @stable ICU 2.0
180     */
181    GregorianCalendar(TimeZone* zoneToAdopt, UErrorCode& success);
182
183    /**
184     * Constructs a GregorianCalendar based on the current time in the given time zone
185     * with the default locale.
186     *
187     * @param zone     The given timezone.
188     * @param success  Indicates the status of GregorianCalendar object construction.
189     *                 Returns U_ZERO_ERROR if constructed successfully.
190     * @stable ICU 2.0
191     */
192    GregorianCalendar(const TimeZone& zone, UErrorCode& success);
193
194    /**
195     * Constructs a GregorianCalendar based on the current time in the default time zone
196     * with the given locale.
197     *
198     * @param aLocale  The given locale.
199     * @param success  Indicates the status of GregorianCalendar object construction.
200     *                 Returns U_ZERO_ERROR if constructed successfully.
201     * @stable ICU 2.0
202     */
203    GregorianCalendar(const Locale& aLocale, UErrorCode& success);
204
205    /**
206     * Constructs a GregorianCalendar based on the current time in the given time zone
207     * with the given locale. Clients are no longer responsible for deleting the given
208     * time zone object after it's adopted.
209     *
210     * @param zoneToAdopt     The given timezone.
211     * @param aLocale  The given locale.
212     * @param success  Indicates the status of GregorianCalendar object construction.
213     *                 Returns U_ZERO_ERROR if constructed successfully.
214     * @stable ICU 2.0
215     */
216    GregorianCalendar(TimeZone* zoneToAdopt, const Locale& aLocale, UErrorCode& success);
217
218    /**
219     * Constructs a GregorianCalendar based on the current time in the given time zone
220     * with the given locale.
221     *
222     * @param zone     The given timezone.
223     * @param aLocale  The given locale.
224     * @param success  Indicates the status of GregorianCalendar object construction.
225     *                 Returns U_ZERO_ERROR if constructed successfully.
226     * @stable ICU 2.0
227     */
228    GregorianCalendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success);
229
230    /**
231     * Constructs a GregorianCalendar with the given AD date set in the default time
232     * zone with the default locale.
233     *
234     * @param year     The value used to set the YEAR time field in the calendar.
235     * @param month    The value used to set the MONTH time field in the calendar. Month
236     *                 value is 0-based. e.g., 0 for January.
237     * @param date     The value used to set the DATE time field in the calendar.
238     * @param success  Indicates the status of GregorianCalendar object construction.
239     *                 Returns U_ZERO_ERROR if constructed successfully.
240     * @stable ICU 2.0
241     */
242    GregorianCalendar(int32_t year, int32_t month, int32_t date, UErrorCode& success);
243
244    /**
245     * Constructs a GregorianCalendar with the given AD date and time set for the
246     * default time zone with the default locale.
247     *
248     * @param year     The value used to set the YEAR time field in the calendar.
249     * @param month    The value used to set the MONTH time field in the calendar. Month
250     *                 value is 0-based. e.g., 0 for January.
251     * @param date     The value used to set the DATE time field in the calendar.
252     * @param hour     The value used to set the HOUR_OF_DAY time field in the calendar.
253     * @param minute   The value used to set the MINUTE time field in the calendar.
254     * @param success  Indicates the status of GregorianCalendar object construction.
255     *                 Returns U_ZERO_ERROR if constructed successfully.
256     * @stable ICU 2.0
257     */
258    GregorianCalendar(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, UErrorCode& success);
259
260    /**
261     * Constructs a GregorianCalendar with the given AD date and time set for the
262     * default time zone with the default locale.
263     *
264     * @param year     The value used to set the YEAR time field in the calendar.
265     * @param month    The value used to set the MONTH time field in the calendar. Month
266     *                 value is 0-based. e.g., 0 for January.
267     * @param date     The value used to set the DATE time field in the calendar.
268     * @param hour     The value used to set the HOUR_OF_DAY time field in the calendar.
269     * @param minute   The value used to set the MINUTE time field in the calendar.
270     * @param second   The value used to set the SECOND time field in the calendar.
271     * @param success  Indicates the status of GregorianCalendar object construction.
272     *                 Returns U_ZERO_ERROR if constructed successfully.
273     * @stable ICU 2.0
274     */
275    GregorianCalendar(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second, UErrorCode& success);
276
277    /**
278     * Destructor
279     * @stable ICU 2.0
280     */
281    virtual ~GregorianCalendar();
282
283    /**
284     * Copy constructor
285     * @param source    the object to be copied.
286     * @stable ICU 2.0
287     */
288    GregorianCalendar(const GregorianCalendar& source);
289
290    /**
291     * Default assignment operator
292     * @param right    the object to be copied.
293     * @stable ICU 2.0
294     */
295    GregorianCalendar& operator=(const GregorianCalendar& right);
296
297    /**
298     * Create and return a polymorphic copy of this calendar.
299     * @return    return a polymorphic copy of this calendar.
300     * @stable ICU 2.0
301     */
302    virtual Calendar* clone(void) const;
303
304    /**
305     * Sets the GregorianCalendar change date. This is the point when the switch from
306     * Julian dates to Gregorian dates occurred. Default is 00:00:00 local time, October
307     * 15, 1582. Previous to this time and date will be Julian dates.
308     *
309     * @param date     The given Gregorian cutover date.
310     * @param success  Output param set to success/failure code on exit.
311     * @stable ICU 2.0
312     */
313    void setGregorianChange(UDate date, UErrorCode& success);
314
315    /**
316     * Gets the Gregorian Calendar change date. This is the point when the switch from
317     * Julian dates to Gregorian dates occurred. Default is 00:00:00 local time, October
318     * 15, 1582. Previous to this time and date will be Julian dates.
319     *
320     * @return   The Gregorian cutover time for this calendar.
321     * @stable ICU 2.0
322     */
323    UDate getGregorianChange(void) const;
324
325    /**
326     * Return true if the given year is a leap year. Determination of whether a year is
327     * a leap year is actually very complicated. We do something crude and mostly
328     * correct here, but for a real determination you need a lot of contextual
329     * information. For example, in Sweden, the change from Julian to Gregorian happened
330     * in a complex way resulting in missed leap years and double leap years between
331     * 1700 and 1753. Another example is that after the start of the Julian calendar in
332     * 45 B.C., the leap years did not regularize until 8 A.D. This method ignores these
333     * quirks, and pays attention only to the Julian onset date and the Gregorian
334     * cutover (which can be changed).
335     *
336     * @param year  The given year.
337     * @return      True if the given year is a leap year; false otherwise.
338     * @stable ICU 2.0
339     */
340    UBool isLeapYear(int32_t year) const;
341
342    /**
343     * Returns TRUE if the given Calendar object is equivalent to this
344     * one.  Calendar override.
345     *
346     * @param other the Calendar to be compared with this Calendar
347     * @stable ICU 2.4
348     */
349    virtual UBool isEquivalentTo(const Calendar& other) const;
350
351    /**
352     * (Overrides Calendar) Rolls up or down by the given amount in the specified field.
353     * For more information, see the documentation for Calendar::roll().
354     *
355     * @param field   The time field.
356     * @param amount  Indicates amount to roll.
357     * @param status  Output param set to success/failure code on exit. If any value
358     *                previously set in the time field is invalid, this will be set to
359     *                an error status.
360     * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
361     */
362    virtual void roll(EDateFields field, int32_t amount, UErrorCode& status);
363
364    /**
365     * (Overrides Calendar) Rolls up or down by the given amount in the specified field.
366     * For more information, see the documentation for Calendar::roll().
367     *
368     * @param field   The time field.
369     * @param amount  Indicates amount to roll.
370     * @param status  Output param set to success/failure code on exit. If any value
371     *                previously set in the time field is invalid, this will be set to
372     *                an error status.
373     * @stable ICU 2.6.
374     */
375    virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status);
376
377    /**
378     * Return the minimum value that this field could have, given the current date.
379     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
380     * @param field    the time field.
381     * @return         the minimum value that this field could have, given the current date.
382     * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead.
383     */
384    int32_t getActualMinimum(EDateFields field) const;
385
386    /**
387     * Return the minimum value that this field could have, given the current date.
388     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
389     * @param field    the time field.
390     * @param status
391     * @return         the minimum value that this field could have, given the current date.
392     * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead. (Added to ICU 3.0 for signature consistency)
393     */
394    int32_t getActualMinimum(EDateFields field, UErrorCode& status) const;
395
396    /**
397     * Return the minimum value that this field could have, given the current date.
398     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
399     * @param field    the time field.
400     * @param status   error result.
401     * @return         the minimum value that this field could have, given the current date.
402     * @stable ICU 3.0
403     */
404    int32_t getActualMinimum(UCalendarDateFields field, UErrorCode &status) const;
405
406    /**
407     * Return the maximum value that this field could have, given the current date.
408     * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
409     * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
410     * for some years the actual maximum for MONTH is 12, and for others 13.
411     * @param field    the time field.
412     * @return         the maximum value that this field could have, given the current date.
413     * @deprecated ICU 2.6. Use getActualMaximum(UCalendarDateFields field) instead.
414     */
415    int32_t getActualMaximum(EDateFields field) const;
416
417    /**
418     * Return the maximum value that this field could have, given the current date.
419     * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
420     * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
421     * for some years the actual maximum for MONTH is 12, and for others 13.
422     * @param field    the time field.
423     * @param status   returns any errors that may result from this function call.
424     * @return         the maximum value that this field could have, given the current date.
425     * @stable ICU 2.6
426     */
427    virtual int32_t getActualMaximum(UCalendarDateFields field, UErrorCode& status) const;
428
429    /**
430     * (Overrides Calendar) Return true if the current date for this Calendar is in
431     * Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
432     *
433     * @param status Fill-in parameter which receives the status of this operation.
434     * @return   True if the current date for this Calendar is in Daylight Savings Time,
435     *           false, otherwise.
436     * @stable ICU 2.0
437     */
438    virtual UBool inDaylightTime(UErrorCode& status) const;
439
440public:
441
442    /**
443     * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
444     * override. This method is to implement a simple version of RTTI, since not all C++
445     * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
446     * this method.
447     *
448     * @return   The class ID for this object. All objects of a given class have the
449     *           same class ID. Objects of other classes have different class IDs.
450     * @stable ICU 2.0
451     */
452    virtual UClassID getDynamicClassID(void) const;
453
454    /**
455     * Return the class ID for this class. This is useful only for comparing to a return
456     * value from getDynamicClassID(). For example:
457     *
458     *      Base* polymorphic_pointer = createPolymorphicObject();
459     *      if (polymorphic_pointer->getDynamicClassID() ==
460     *          Derived::getStaticClassID()) ...
461     *
462     * @return   The class ID for all objects of this class.
463     * @stable ICU 2.0
464     */
465    static UClassID U_EXPORT2 getStaticClassID(void);
466
467    /**
468     * Get the calendar type, "gregorian", for use in DateFormatSymbols.
469     *
470     * @return calendar type
471     * @internal
472     */
473    virtual const char * getType() const;
474
475protected:
476
477    /**
478     * (Overrides Calendar) Converts GMT as milliseconds to time field values.
479     * @param status Fill-in parameter which receives the status of this operation.
480     * @stable ICU 2.0
481     */
482
483 private:
484    GregorianCalendar(); // default constructor not implemented
485
486 protected:
487    /**
488     * Return the ERA.  We need a special method for this because the
489     * default ERA is AD, but a zero (unset) ERA is BC.
490     * @return    the ERA.
491     * @internal
492     */
493    virtual int32_t internalGetEra() const;
494
495    /**
496     * Return the Julian day number of day before the first day of the
497     * given month in the given extended year.  Subclasses should override
498     * this method to implement their calendar system.
499     * @param eyear the extended year
500     * @param month the zero-based month, or 0 if useMonth is false
501     * @param useMonth if false, compute the day before the first day of
502     * the given year, otherwise, compute the day before the first day of
503     * the given month
504     * @return the Julian day number of the day before the first
505     * day of the given month and year
506     * @internal
507     */
508    virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month,
509                                                   UBool useMonth) const;
510
511    /**
512     * Subclasses may override this.  This method calls
513     * handleGetMonthLength() to obtain the calendar-specific month
514     * length.
515     * @param bestField which field to use to calculate the date
516     * @return julian day specified by calendar fields.
517     * @internal
518     */
519    virtual int32_t handleComputeJulianDay(UCalendarDateFields bestField)  ;
520
521    /**
522     * Return the number of days in the given month of the given extended
523     * year of this calendar system.  Subclasses should override this
524     * method if they can provide a more correct or more efficient
525     * implementation than the default implementation in Calendar.
526     * @internal
527     */
528    virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
529
530    /**
531     * Return the number of days in the given extended year of this
532     * calendar system.  Subclasses should override this method if they can
533     * provide a more correct or more efficient implementation than the
534     * default implementation in Calendar.
535     * @stable ICU 2.0
536     */
537    virtual int32_t handleGetYearLength(int32_t eyear) const;
538
539    /**
540     * return the length of the given month.
541     * @param month    the given month.
542     * @return    the length of the given month.
543     * @internal
544     */
545    virtual int32_t monthLength(int32_t month) const;
546
547    /**
548     * return the length of the month according to the given year.
549     * @param month    the given month.
550     * @param year     the given year.
551     * @return         the length of the month
552     * @internal
553     */
554    virtual int32_t monthLength(int32_t month, int32_t year) const;
555
556    /**
557     * return the length of the given year.
558     * @param year    the given year.
559     * @return        the length of the given year.
560     * @internal
561     */
562    int32_t yearLength(int32_t year) const;
563
564    /**
565     * return the length of the year field.
566     * @return    the length of the year field
567     * @internal
568     */
569    int32_t yearLength(void) const;
570
571    /**
572     * After adjustments such as add(MONTH), add(YEAR), we don't want the
573     * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
574     * 3, we want it to go to Feb 28.  Adjustments which might run into this
575     * problem call this method to retain the proper month.
576     * @internal
577     */
578    void pinDayOfMonth(void);
579
580    /**
581     * Return the day number with respect to the epoch.  January 1, 1970 (Gregorian)
582     * is day zero.
583     * @param status Fill-in parameter which receives the status of this operation.
584     * @return       the day number with respect to the epoch.
585     * @internal
586     */
587    virtual UDate getEpochDay(UErrorCode& status);
588
589    /**
590     * Subclass API for defining limits of different types.
591     * Subclasses must implement this method to return limits for the
592     * following fields:
593     *
594     * <pre>UCAL_ERA
595     * UCAL_YEAR
596     * UCAL_MONTH
597     * UCAL_WEEK_OF_YEAR
598     * UCAL_WEEK_OF_MONTH
599     * UCAL_DATE (DAY_OF_MONTH on Java)
600     * UCAL_DAY_OF_YEAR
601     * UCAL_DAY_OF_WEEK_IN_MONTH
602     * UCAL_YEAR_WOY
603     * UCAL_EXTENDED_YEAR</pre>
604     *
605     * @param field one of the above field numbers
606     * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
607     * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
608     * @internal
609     */
610    virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
611
612    /**
613     * Return the extended year defined by the current fields.  This will
614     * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such
615     * as UCAL_ERA) specific to the calendar system, depending on which set of
616     * fields is newer.
617     * @return the extended year
618     * @internal
619     */
620    virtual int32_t handleGetExtendedYear();
621
622    /**
623     * Subclasses may override this to convert from week fields
624     * (YEAR_WOY and WEEK_OF_YEAR) to an extended year in the case
625     * where YEAR, EXTENDED_YEAR are not set.
626     * The Gregorian implementation assumes a yearWoy in gregorian format, according to the current era.
627     * @return the extended year, UCAL_EXTENDED_YEAR
628     * @internal
629     */
630    virtual int32_t handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy);
631
632
633    /**
634     * Subclasses may override this method to compute several fields
635     * specific to each calendar system.  These are:
636     *
637     * <ul><li>ERA
638     * <li>YEAR
639     * <li>MONTH
640     * <li>DAY_OF_MONTH
641     * <li>DAY_OF_YEAR
642     * <li>EXTENDED_YEAR</ul>
643     *
644     * <p>The GregorianCalendar implementation implements
645     * a calendar with the specified Julian/Gregorian cutover date.
646     * @internal
647     */
648    virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
649
650 private:
651    /**
652     * Compute the julian day number of the given year.
653     * @param isGregorian    if true, using Gregorian calendar, otherwise using Julian calendar
654     * @param year           the given year.
655     * @param isLeap         true if the year is a leap year.
656     * @return
657     */
658    static double computeJulianDayOfYear(UBool isGregorian, int32_t year,
659                                         UBool& isLeap);
660
661    /**
662     * Validates the values of the set time fields.  True if they're all valid.
663     * @return    True if the set time fields are all valid.
664     */
665    UBool validateFields(void) const;
666
667    /**
668     * Validates the value of the given time field.  True if it's valid.
669     */
670    UBool boundsCheck(int32_t value, UCalendarDateFields field) const;
671
672    /**
673     * Return the pseudo-time-stamp for two fields, given their
674     * individual pseudo-time-stamps.  If either of the fields
675     * is unset, then the aggregate is unset.  Otherwise, the
676     * aggregate is the later of the two stamps.
677     * @param stamp_a    One given field.
678     * @param stamp_b    Another given field.
679     * @return the pseudo-time-stamp for two fields
680     */
681    int32_t aggregateStamp(int32_t stamp_a, int32_t stamp_b);
682
683    /**
684     * The point at which the Gregorian calendar rules are used, measured in
685     * milliseconds from the standard epoch.  Default is October 15, 1582
686     * (Gregorian) 00:00:00 UTC, that is, October 4, 1582 (Julian) is followed
687     * by October 15, 1582 (Gregorian).  This corresponds to Julian day number
688     * 2299161. This is measured from the standard epoch, not in Julian Days.
689     * @internal
690     */
691    UDate                fGregorianCutover;
692
693    /**
694     * Julian day number of the Gregorian cutover
695     */
696    int32_t             fCutoverJulianDay;
697
698    /**
699     * Midnight, local time (using this Calendar's TimeZone) at or before the
700     * gregorianCutover. This is a pure date value with no time of day or
701     * timezone component.
702     */
703    UDate                 fNormalizedGregorianCutover;// = gregorianCutover;
704
705    /**
706     * The year of the gregorianCutover, with 0 representing
707     * 1 BC, -1 representing 2 BC, etc.
708     */
709    int32_t fGregorianCutoverYear;// = 1582;
710
711    /**
712     * The year of the gregorianCutover, with 0 representing
713     * 1 BC, -1 representing 2 BC, etc.
714     */
715    int32_t fGregorianCutoverJulianDay;// = 2299161;
716
717    /**
718     * Converts time as milliseconds to Julian date. The Julian date used here is not a
719     * true Julian date, since it is measured from midnight, not noon.
720     *
721     * @param millis  The given milliseconds.
722     * @return        The Julian date number.
723     */
724    static double millisToJulianDay(UDate millis);
725
726    /**
727     * Converts Julian date to time as milliseconds. The Julian date used here is not a
728     * true Julian date, since it is measured from midnight, not noon.
729     *
730     * @param julian  The given Julian date number.
731     * @return        Time as milliseconds.
732     */
733    static UDate julianDayToMillis(double julian);
734
735    /**
736     * Used by handleComputeJulianDay() and handleComputeMonthStart().
737     * Temporary field indicating whether the calendar is currently Gregorian as opposed to Julian.
738     */
739    UBool fIsGregorian;
740
741    /**
742     * Used by handleComputeJulianDay() and handleComputeMonthStart().
743     * Temporary field indicating that the sense of the gregorian cutover should be inverted
744     * to handle certain calculations on and around the cutover date.
745     */
746    UBool fInvertGregorian;
747
748
749 public: // internal implementation
750
751    /**
752     * @internal
753     * @return TRUE if this calendar has the notion of a default century
754     */
755    virtual UBool haveDefaultCentury() const;
756
757    /**
758     * @internal
759     * @return the start of the default century
760     */
761    virtual UDate defaultCenturyStart() const;
762
763    /**
764     * @internal
765     * @return the beginning year of the default century
766     */
767    virtual int32_t defaultCenturyStartYear() const;
768
769 private:
770    /**
771     * The system maintains a static default century start date.  This is initialized
772     * the first time it is used.  Before then, it is set to SYSTEM_DEFAULT_CENTURY to
773     * indicate an uninitialized state.  Once the system default century date and year
774     * are set, they do not change.
775     */
776    static UDate         fgSystemDefaultCenturyStart;
777
778    /**
779     * See documentation for systemDefaultCenturyStart.
780     */
781    static int32_t          fgSystemDefaultCenturyStartYear;
782
783    /**
784     * Default value that indicates the defaultCenturyStartYear is unitialized
785     */
786    static const int32_t    fgSystemDefaultCenturyYear;
787
788    /**
789     * Default value that indicates the UDate of the beginning of the system default century
790     */
791    static const UDate        fgSystemDefaultCentury;
792
793    /**
794     * Returns the beginning date of the 100-year window that dates with 2-digit years
795     * are considered to fall within.
796     * @return    the beginning date of the 100-year window that dates with 2-digit years
797     *            are considered to fall within.
798     */
799    UDate         internalGetDefaultCenturyStart(void) const;
800
801    /**
802     * Returns the first year of the 100-year window that dates with 2-digit years
803     * are considered to fall within.
804     * @return    the first year of the 100-year window that dates with 2-digit years
805     *            are considered to fall within.
806     */
807    int32_t          internalGetDefaultCenturyStartYear(void) const;
808
809    /**
810     * Initializes the 100-year window that dates with 2-digit years are considered
811     * to fall within so that its start date is 80 years before the current time.
812     */
813    static void  initializeSystemDefaultCentury(void);
814
815};
816
817U_NAMESPACE_END
818
819#endif /* #if !UCONFIG_NO_FORMATTING */
820
821#endif // _GREGOCAL
822//eof
823
824