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