Home | History | Annotate | Download | only in unicode
      1 /*
      2 * Copyright (C) 1997-2011, 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  private:
    476     GregorianCalendar(); // default constructor not implemented
    477 
    478  protected:
    479     /**
    480      * Return the ERA.  We need a special method for this because the
    481      * default ERA is AD, but a zero (unset) ERA is BC.
    482      * @return    the ERA.
    483      * @internal
    484      */
    485     virtual int32_t internalGetEra() const;
    486 
    487     /**
    488      * Return the Julian day number of day before the first day of the
    489      * given month in the given extended year.  Subclasses should override
    490      * this method to implement their calendar system.
    491      * @param eyear the extended year
    492      * @param month the zero-based month, or 0 if useMonth is false
    493      * @param useMonth if false, compute the day before the first day of
    494      * the given year, otherwise, compute the day before the first day of
    495      * the given month
    496      * @return the Julian day number of the day before the first
    497      * day of the given month and year
    498      * @internal
    499      */
    500     virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month,
    501                                                    UBool useMonth) const;
    502 
    503     /**
    504      * Subclasses may override this.  This method calls
    505      * handleGetMonthLength() to obtain the calendar-specific month
    506      * length.
    507      * @param bestField which field to use to calculate the date
    508      * @return julian day specified by calendar fields.
    509      * @internal
    510      */
    511     virtual int32_t handleComputeJulianDay(UCalendarDateFields bestField)  ;
    512 
    513     /**
    514      * Return the number of days in the given month of the given extended
    515      * year of this calendar system.  Subclasses should override this
    516      * method if they can provide a more correct or more efficient
    517      * implementation than the default implementation in Calendar.
    518      * @internal
    519      */
    520     virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
    521 
    522     /**
    523      * Return the number of days in the given extended year of this
    524      * calendar system.  Subclasses should override this method if they can
    525      * provide a more correct or more efficient implementation than the
    526      * default implementation in Calendar.
    527      * @stable ICU 2.0
    528      */
    529     virtual int32_t handleGetYearLength(int32_t eyear) const;
    530 
    531     /**
    532      * return the length of the given month.
    533      * @param month    the given month.
    534      * @return    the length of the given month.
    535      * @internal
    536      */
    537     virtual int32_t monthLength(int32_t month) const;
    538 
    539     /**
    540      * return the length of the month according to the given year.
    541      * @param month    the given month.
    542      * @param year     the given year.
    543      * @return         the length of the month
    544      * @internal
    545      */
    546     virtual int32_t monthLength(int32_t month, int32_t year) const;
    547 
    548     /**
    549      * return the length of the given year.
    550      * @param year    the given year.
    551      * @return        the length of the given year.
    552      * @internal
    553      */
    554     int32_t yearLength(int32_t year) const;
    555 
    556     /**
    557      * return the length of the year field.
    558      * @return    the length of the year field
    559      * @internal
    560      */
    561     int32_t yearLength(void) const;
    562 
    563     /**
    564      * After adjustments such as add(MONTH), add(YEAR), we don't want the
    565      * month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
    566      * 3, we want it to go to Feb 28.  Adjustments which might run into this
    567      * problem call this method to retain the proper month.
    568      * @internal
    569      */
    570     void pinDayOfMonth(void);
    571 
    572     /**
    573      * Return the day number with respect to the epoch.  January 1, 1970 (Gregorian)
    574      * is day zero.
    575      * @param status Fill-in parameter which receives the status of this operation.
    576      * @return       the day number with respect to the epoch.
    577      * @internal
    578      */
    579     virtual UDate getEpochDay(UErrorCode& status);
    580 
    581     /**
    582      * Subclass API for defining limits of different types.
    583      * Subclasses must implement this method to return limits for the
    584      * following fields:
    585      *
    586      * <pre>UCAL_ERA
    587      * UCAL_YEAR
    588      * UCAL_MONTH
    589      * UCAL_WEEK_OF_YEAR
    590      * UCAL_WEEK_OF_MONTH
    591      * UCAL_DATE (DAY_OF_MONTH on Java)
    592      * UCAL_DAY_OF_YEAR
    593      * UCAL_DAY_OF_WEEK_IN_MONTH
    594      * UCAL_YEAR_WOY
    595      * UCAL_EXTENDED_YEAR</pre>
    596      *
    597      * @param field one of the above field numbers
    598      * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
    599      * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
    600      * @internal
    601      */
    602     virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
    603 
    604     /**
    605      * Return the extended year defined by the current fields.  This will
    606      * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such
    607      * as UCAL_ERA) specific to the calendar system, depending on which set of
    608      * fields is newer.
    609      * @return the extended year
    610      * @internal
    611      */
    612     virtual int32_t handleGetExtendedYear();
    613 
    614     /**
    615      * Subclasses may override this to convert from week fields
    616      * (YEAR_WOY and WEEK_OF_YEAR) to an extended year in the case
    617      * where YEAR, EXTENDED_YEAR are not set.
    618      * The Gregorian implementation assumes a yearWoy in gregorian format, according to the current era.
    619      * @return the extended year, UCAL_EXTENDED_YEAR
    620      * @internal
    621      */
    622     virtual int32_t handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy);
    623 
    624 
    625     /**
    626      * Subclasses may override this method to compute several fields
    627      * specific to each calendar system.  These are:
    628      *
    629      * <ul><li>ERA
    630      * <li>YEAR
    631      * <li>MONTH
    632      * <li>DAY_OF_MONTH
    633      * <li>DAY_OF_YEAR
    634      * <li>EXTENDED_YEAR</ul>
    635      *
    636      * <p>The GregorianCalendar implementation implements
    637      * a calendar with the specified Julian/Gregorian cutover date.
    638      * @internal
    639      */
    640     virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
    641 
    642  private:
    643     /**
    644      * Compute the julian day number of the given year.
    645      * @param isGregorian    if true, using Gregorian calendar, otherwise using Julian calendar
    646      * @param year           the given year.
    647      * @param isLeap         true if the year is a leap year.
    648      * @return
    649      */
    650     static double computeJulianDayOfYear(UBool isGregorian, int32_t year,
    651                                          UBool& isLeap);
    652 
    653     /**
    654      * Validates the values of the set time fields.  True if they're all valid.
    655      * @return    True if the set time fields are all valid.
    656      */
    657     UBool validateFields(void) const;
    658 
    659     /**
    660      * Validates the value of the given time field.  True if it's valid.
    661      */
    662     UBool boundsCheck(int32_t value, UCalendarDateFields field) const;
    663 
    664     /**
    665      * Return the pseudo-time-stamp for two fields, given their
    666      * individual pseudo-time-stamps.  If either of the fields
    667      * is unset, then the aggregate is unset.  Otherwise, the
    668      * aggregate is the later of the two stamps.
    669      * @param stamp_a    One given field.
    670      * @param stamp_b    Another given field.
    671      * @return the pseudo-time-stamp for two fields
    672      */
    673     int32_t aggregateStamp(int32_t stamp_a, int32_t stamp_b);
    674 
    675     /**
    676      * The point at which the Gregorian calendar rules are used, measured in
    677      * milliseconds from the standard epoch.  Default is October 15, 1582
    678      * (Gregorian) 00:00:00 UTC, that is, October 4, 1582 (Julian) is followed
    679      * by October 15, 1582 (Gregorian).  This corresponds to Julian day number
    680      * 2299161. This is measured from the standard epoch, not in Julian Days.
    681      * @internal
    682      */
    683     UDate                fGregorianCutover;
    684 
    685     /**
    686      * Julian day number of the Gregorian cutover
    687      */
    688     int32_t             fCutoverJulianDay;
    689 
    690     /**
    691      * Midnight, local time (using this Calendar's TimeZone) at or before the
    692      * gregorianCutover. This is a pure date value with no time of day or
    693      * timezone component.
    694      */
    695     UDate                 fNormalizedGregorianCutover;// = gregorianCutover;
    696 
    697     /**
    698      * The year of the gregorianCutover, with 0 representing
    699      * 1 BC, -1 representing 2 BC, etc.
    700      */
    701     int32_t fGregorianCutoverYear;// = 1582;
    702 
    703     /**
    704      * The year of the gregorianCutover, with 0 representing
    705      * 1 BC, -1 representing 2 BC, etc.
    706      */
    707     int32_t fGregorianCutoverJulianDay;// = 2299161;
    708 
    709     /**
    710      * Converts time as milliseconds to Julian date. The Julian date used here is not a
    711      * true Julian date, since it is measured from midnight, not noon.
    712      *
    713      * @param millis  The given milliseconds.
    714      * @return        The Julian date number.
    715      */
    716     static double millisToJulianDay(UDate millis);
    717 
    718     /**
    719      * Converts Julian date to time as milliseconds. The Julian date used here is not a
    720      * true Julian date, since it is measured from midnight, not noon.
    721      *
    722      * @param julian  The given Julian date number.
    723      * @return        Time as milliseconds.
    724      */
    725     static UDate julianDayToMillis(double julian);
    726 
    727     /**
    728      * Used by handleComputeJulianDay() and handleComputeMonthStart().
    729      * Temporary field indicating whether the calendar is currently Gregorian as opposed to Julian.
    730      */
    731     UBool fIsGregorian;
    732 
    733     /**
    734      * Used by handleComputeJulianDay() and handleComputeMonthStart().
    735      * Temporary field indicating that the sense of the gregorian cutover should be inverted
    736      * to handle certain calculations on and around the cutover date.
    737      */
    738     UBool fInvertGregorian;
    739 
    740 
    741  public: // internal implementation
    742 
    743     /**
    744      * @internal
    745      * @return TRUE if this calendar has the notion of a default century
    746      */
    747     virtual UBool haveDefaultCentury() const;
    748 
    749     /**
    750      * @internal
    751      * @return the start of the default century
    752      */
    753     virtual UDate defaultCenturyStart() const;
    754 
    755     /**
    756      * @internal
    757      * @return the beginning year of the default century
    758      */
    759     virtual int32_t defaultCenturyStartYear() const;
    760 
    761  private:
    762     /**
    763      * The system maintains a static default century start date.  This is initialized
    764      * the first time it is used.  Before then, it is set to SYSTEM_DEFAULT_CENTURY to
    765      * indicate an uninitialized state.  Once the system default century date and year
    766      * are set, they do not change.
    767      */
    768     static UDate         fgSystemDefaultCenturyStart;
    769 
    770     /**
    771      * See documentation for systemDefaultCenturyStart.
    772      */
    773     static int32_t          fgSystemDefaultCenturyStartYear;
    774 
    775     /**
    776      * Default value that indicates the defaultCenturyStartYear is unitialized
    777      */
    778     static const int32_t    fgSystemDefaultCenturyYear;
    779 
    780     /**
    781      * Default value that indicates the UDate of the beginning of the system default century
    782      */
    783     static const UDate        fgSystemDefaultCentury;
    784 
    785     /**
    786      * Returns the beginning date of the 100-year window that dates with 2-digit years
    787      * are considered to fall within.
    788      * @return    the beginning date of the 100-year window that dates with 2-digit years
    789      *            are considered to fall within.
    790      */
    791     UDate         internalGetDefaultCenturyStart(void) const;
    792 
    793     /**
    794      * Returns the first year of the 100-year window that dates with 2-digit years
    795      * are considered to fall within.
    796      * @return    the first year of the 100-year window that dates with 2-digit years
    797      *            are considered to fall within.
    798      */
    799     int32_t          internalGetDefaultCenturyStartYear(void) const;
    800 
    801     /**
    802      * Initializes the 100-year window that dates with 2-digit years are considered
    803      * to fall within so that its start date is 80 years before the current time.
    804      */
    805     static void  initializeSystemDefaultCentury(void);
    806 
    807 };
    808 
    809 U_NAMESPACE_END
    810 
    811 #endif /* #if !UCONFIG_NO_FORMATTING */
    812 
    813 #endif // _GREGOCAL
    814 //eof
    815 
    816