Home | History | Annotate | Download | only in unicode
      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