gregocal.h revision c73f511526464f8e56c242df80552e9b0d94ae3d
1/*
2* Copyright (C) 1997-2013, 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#ifndef U_HIDE_DEPRECATED_API
378    /**
379     * Return the minimum value that this field could have, given the current date.
380     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
381     * @param field    the time field.
382     * @return         the minimum value that this field could have, given the current date.
383     * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead.
384     */
385    int32_t getActualMinimum(EDateFields field) const;
386
387    /**
388     * Return the minimum value that this field could have, given the current date.
389     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
390     * @param field    the time field.
391     * @param status
392     * @return         the minimum value that this field could have, given the current date.
393     * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead. (Added to ICU 3.0 for signature consistency)
394     */
395    int32_t getActualMinimum(EDateFields field, UErrorCode& status) const;
396#endif  /* U_HIDE_DEPRECATED_API */
397
398    /**
399     * Return the minimum value that this field could have, given the current date.
400     * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
401     * @param field    the time field.
402     * @param status   error result.
403     * @return         the minimum value that this field could have, given the current date.
404     * @stable ICU 3.0
405     */
406    int32_t getActualMinimum(UCalendarDateFields field, UErrorCode &status) const;
407
408#ifndef U_HIDE_DEPRECATED_API
409    /**
410     * Return the maximum value that this field could have, given the current date.
411     * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
412     * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
413     * for some years the actual maximum for MONTH is 12, and for others 13.
414     * @param field    the time field.
415     * @return         the maximum value that this field could have, given the current date.
416     * @deprecated ICU 2.6. Use getActualMaximum(UCalendarDateFields field) instead.
417     */
418    int32_t getActualMaximum(EDateFields field) const;
419#endif  /* U_HIDE_DEPRECATED_API */
420
421    /**
422     * Return the maximum value that this field could have, given the current date.
423     * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
424     * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
425     * for some years the actual maximum for MONTH is 12, and for others 13.
426     * @param field    the time field.
427     * @param status   returns any errors that may result from this function call.
428     * @return         the maximum value that this field could have, given the current date.
429     * @stable ICU 2.6
430     */
431    virtual int32_t getActualMaximum(UCalendarDateFields field, UErrorCode& status) const;
432
433    /**
434     * (Overrides Calendar) Return true if the current date for this Calendar is in
435     * Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
436     *
437     * @param status Fill-in parameter which receives the status of this operation.
438     * @return   True if the current date for this Calendar is in Daylight Savings Time,
439     *           false, otherwise.
440     * @stable ICU 2.0
441     */
442    virtual UBool inDaylightTime(UErrorCode& status) const;
443
444public:
445
446    /**
447     * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
448     * override. This method is to implement a simple version of RTTI, since not all C++
449     * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
450     * this method.
451     *
452     * @return   The class ID for this object. All objects of a given class have the
453     *           same class ID. Objects of other classes have different class IDs.
454     * @stable ICU 2.0
455     */
456    virtual UClassID getDynamicClassID(void) const;
457
458    /**
459     * Return the class ID for this class. This is useful only for comparing to a return
460     * value from getDynamicClassID(). For example:
461     *
462     *      Base* polymorphic_pointer = createPolymorphicObject();
463     *      if (polymorphic_pointer->getDynamicClassID() ==
464     *          Derived::getStaticClassID()) ...
465     *
466     * @return   The class ID for all objects of this class.
467     * @stable ICU 2.0
468     */
469    static UClassID U_EXPORT2 getStaticClassID(void);
470
471    /**
472     * Returns the calendar type name string for this Calendar object.
473     * The returned string is the legacy ICU calendar attribute value,
474     * for example, "gregorian" or "japanese".
475     *
476     * For more details see the Calendar::getType() documentation.
477     *
478     * @return legacy calendar type name string
479     * @stable ICU 49
480     */
481    virtual const char * getType() const;
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#ifndef U_HIDE_INTERNAL_API
557    /**
558     * return the length of the given year.
559     * @param year    the given year.
560     * @return        the length of the given year.
561     * @internal
562     */
563    int32_t yearLength(int32_t year) const;
564
565    /**
566     * return the length of the year field.
567     * @return    the length of the year field
568     * @internal
569     */
570    int32_t yearLength(void) const;
571
572    /**
573     * After adjustments such as add(MONTH), add(YEAR), we don't want the
574     * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
575     * 3, we want it to go to Feb 28.  Adjustments which might run into this
576     * problem call this method to retain the proper month.
577     * @internal
578     */
579    void pinDayOfMonth(void);
580#endif  /* U_HIDE_INTERNAL_API */
581
582    /**
583     * Return the day number with respect to the epoch.  January 1, 1970 (Gregorian)
584     * is day zero.
585     * @param status Fill-in parameter which receives the status of this operation.
586     * @return       the day number with respect to the epoch.
587     * @internal
588     */
589    virtual UDate getEpochDay(UErrorCode& status);
590
591    /**
592     * Subclass API for defining limits of different types.
593     * Subclasses must implement this method to return limits for the
594     * following fields:
595     *
596     * <pre>UCAL_ERA
597     * UCAL_YEAR
598     * UCAL_MONTH
599     * UCAL_WEEK_OF_YEAR
600     * UCAL_WEEK_OF_MONTH
601     * UCAL_DATE (DAY_OF_MONTH on Java)
602     * UCAL_DAY_OF_YEAR
603     * UCAL_DAY_OF_WEEK_IN_MONTH
604     * UCAL_YEAR_WOY
605     * UCAL_EXTENDED_YEAR</pre>
606     *
607     * @param field one of the above field numbers
608     * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
609     * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
610     * @internal
611     */
612    virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
613
614    /**
615     * Return the extended year defined by the current fields.  This will
616     * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such
617     * as UCAL_ERA) specific to the calendar system, depending on which set of
618     * fields is newer.
619     * @return the extended year
620     * @internal
621     */
622    virtual int32_t handleGetExtendedYear();
623
624    /**
625     * Subclasses may override this to convert from week fields
626     * (YEAR_WOY and WEEK_OF_YEAR) to an extended year in the case
627     * where YEAR, EXTENDED_YEAR are not set.
628     * The Gregorian implementation assumes a yearWoy in gregorian format, according to the current era.
629     * @return the extended year, UCAL_EXTENDED_YEAR
630     * @internal
631     */
632    virtual int32_t handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy);
633
634
635    /**
636     * Subclasses may override this method to compute several fields
637     * specific to each calendar system.  These are:
638     *
639     * <ul><li>ERA
640     * <li>YEAR
641     * <li>MONTH
642     * <li>DAY_OF_MONTH
643     * <li>DAY_OF_YEAR
644     * <li>EXTENDED_YEAR</ul>
645     *
646     * <p>The GregorianCalendar implementation implements
647     * a calendar with the specified Julian/Gregorian cutover date.
648     * @internal
649     */
650    virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
651
652 private:
653    /**
654     * Compute the julian day number of the given year.
655     * @param isGregorian    if true, using Gregorian calendar, otherwise using Julian calendar
656     * @param year           the given year.
657     * @param isLeap         true if the year is a leap year.
658     * @return
659     */
660    static double computeJulianDayOfYear(UBool isGregorian, int32_t year,
661                                         UBool& isLeap);
662
663    /**
664     * Validates the values of the set time fields.  True if they're all valid.
665     * @return    True if the set time fields are all valid.
666     */
667    UBool validateFields(void) const;
668
669    /**
670     * Validates the value of the given time field.  True if it's valid.
671     */
672    UBool boundsCheck(int32_t value, UCalendarDateFields field) const;
673
674    /**
675     * Return the pseudo-time-stamp for two fields, given their
676     * individual pseudo-time-stamps.  If either of the fields
677     * is unset, then the aggregate is unset.  Otherwise, the
678     * aggregate is the later of the two stamps.
679     * @param stamp_a    One given field.
680     * @param stamp_b    Another given field.
681     * @return the pseudo-time-stamp for two fields
682     */
683    int32_t aggregateStamp(int32_t stamp_a, int32_t stamp_b);
684
685    /**
686     * The point at which the Gregorian calendar rules are used, measured in
687     * milliseconds from the standard epoch.  Default is October 15, 1582
688     * (Gregorian) 00:00:00 UTC, that is, October 4, 1582 (Julian) is followed
689     * by October 15, 1582 (Gregorian).  This corresponds to Julian day number
690     * 2299161. This is measured from the standard epoch, not in Julian Days.
691     */
692    UDate                fGregorianCutover;
693
694    /**
695     * Julian day number of the Gregorian cutover
696     */
697    int32_t             fCutoverJulianDay;
698
699    /**
700     * Midnight, local time (using this Calendar's TimeZone) at or before the
701     * gregorianCutover. This is a pure date value with no time of day or
702     * timezone component.
703     */
704    UDate                 fNormalizedGregorianCutover;// = gregorianCutover;
705
706    /**
707     * The year of the gregorianCutover, with 0 representing
708     * 1 BC, -1 representing 2 BC, etc.
709     */
710    int32_t fGregorianCutoverYear;// = 1582;
711
712    /**
713     * The year of the gregorianCutover, with 0 representing
714     * 1 BC, -1 representing 2 BC, etc.
715     */
716    int32_t fGregorianCutoverJulianDay;// = 2299161;
717
718    /**
719     * Converts time as milliseconds to Julian date. The Julian date used here is not a
720     * true Julian date, since it is measured from midnight, not noon.
721     *
722     * @param millis  The given milliseconds.
723     * @return        The Julian date number.
724     */
725    static double millisToJulianDay(UDate millis);
726
727    /**
728     * Converts Julian date to time as milliseconds. The Julian date used here is not a
729     * true Julian date, since it is measured from midnight, not noon.
730     *
731     * @param julian  The given Julian date number.
732     * @return        Time as milliseconds.
733     */
734    static UDate julianDayToMillis(double julian);
735
736    /**
737     * Used by handleComputeJulianDay() and handleComputeMonthStart().
738     * Temporary field indicating whether the calendar is currently Gregorian as opposed to Julian.
739     */
740    UBool fIsGregorian;
741
742    /**
743     * Used by handleComputeJulianDay() and handleComputeMonthStart().
744     * Temporary field indicating that the sense of the gregorian cutover should be inverted
745     * to handle certain calculations on and around the cutover date.
746     */
747    UBool fInvertGregorian;
748
749
750 public: // internal implementation
751
752    /**
753     * @return TRUE if this calendar has the notion of a default century
754     * @internal
755     */
756    virtual UBool haveDefaultCentury() const;
757
758    /**
759     * @return the start of the default century
760     * @internal
761     */
762    virtual UDate defaultCenturyStart() const;
763
764    /**
765     * @return the beginning year of the default century
766     * @internal
767     */
768    virtual int32_t defaultCenturyStartYear() const;
769};
770
771U_NAMESPACE_END
772
773#endif /* #if !UCONFIG_NO_FORMATTING */
774
775#endif // _GREGOCAL
776//eof
777
778