• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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     /**
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 
440 public:
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 
475 protected:
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 
817 U_NAMESPACE_END
818 
819 #endif /* #if !UCONFIG_NO_FORMATTING */
820 
821 #endif // _GREGOCAL
822 //eof
823 
824