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