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 
38 U_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  */
149 class U_I18N_API GregorianCalendar: public Calendar {
150 public:
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 
444 public:
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 
771 U_NAMESPACE_END
772 
773 #endif /* #if !UCONFIG_NO_FORMATTING */
774 
775 #endif // _GREGOCAL
776 //eof
777 
778