X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..f59164e3d128c7675a4d3934206346a3384e53a5:/icuSources/i18n/unicode/gregocal.h diff --git a/icuSources/i18n/unicode/gregocal.h b/icuSources/i18n/unicode/gregocal.h index 6f8e6d53..e6ae4d6a 100644 --- a/icuSources/i18n/unicode/gregocal.h +++ b/icuSources/i18n/unicode/gregocal.h @@ -1,5 +1,6 @@ /* -* Copyright (C) {1997-2003}, International Business Machines Corporation and others. All Rights Reserved. +* Copyright (C) 1997-2013, International Business Machines Corporation and others. +* All Rights Reserved. ******************************************************************************** * * File GREGOCAL.H @@ -16,6 +17,7 @@ * Added documentation of WEEK_OF_YEAR computation. * 10/15/99 aliu Fixed j32, cannot set date to Feb 29 2000 AD. * {JDK bug 4210209 4209272} +* 11/07/2003 srl Update, clean up documentation. ******************************************************************************** */ @@ -28,9 +30,14 @@ #include "unicode/calendar.h" +/** + * \file + * \brief C++ API: Concrete class which provides the standard calendar. + */ + U_NAMESPACE_BEGIN -/** +/** * Concrete class which provides the standard calendar used by most of the world. *

* The standard (Gregorian) calendar has 2 eras, BC and AD. @@ -66,10 +73,10 @@ U_NAMESPACE_BEGIN *

  * \code
  *     // get the supported ids for GMT-08:00 (Pacific Standard Time)
- *     int32_t idsCount;
- *     const UnicodeString** ids = TimeZone::createAvailableIDs(-8 * 60 * 60 * 1000, idsCount);
+ *     UErrorCode success = U_ZERO_ERROR;
+ *     const StringEnumeration *ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
  *     // if no ids were returned, something is wrong. get out.
- *     if (idsCount == 0) {
+ *     if (ids == 0 || ids->count(success) == 0) {
  *         return;
  *     }
  *
@@ -77,60 +84,63 @@ U_NAMESPACE_BEGIN
  *     cout << "Current Time" << endl;
  *
  *     // create a Pacific Standard Time time zone
- *     SimpleTimeZone* pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, *(ids[0]));
+ *     SimpleTimeZone* pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids->unext(NULL, success)));
  *
  *     // set up rules for daylight savings time
- *     pdt->setStartRule(Calendar::APRIL, 1, Calendar::SUNDAY, 2 * 60 * 60 * 1000);
- *     pdt->setEndRule(Calendar::OCTOBER, -1, Calendar::SUNDAY, 2 * 60 * 60 * 1000);
+ *     pdt->setStartRule(UCAL_MARCH, 1, UCAL_SUNDAY, 2 * 60 * 60 * 1000);
+ *     pdt->setEndRule(UCAL_NOVEMBER, 2, UCAL_SUNDAY, 2 * 60 * 60 * 1000);
  *
  *     // create a GregorianCalendar with the Pacific Daylight time zone
  *     // and the current date and time
- *     UErrorCode success = U_ZERO_ERROR;
  *     Calendar* calendar = new GregorianCalendar( pdt, success );
  *
  *     // print out a bunch of interesting things
- *     cout << "ERA: " << calendar->get( Calendar::ERA, success ) << endl;
- *     cout << "YEAR: " << calendar->get( Calendar::YEAR, success ) << endl;
- *     cout << "MONTH: " << calendar->get( Calendar::MONTH, success ) << endl;
- *     cout << "WEEK_OF_YEAR: " << calendar->get( Calendar::WEEK_OF_YEAR, success ) << endl;
- *     cout << "WEEK_OF_MONTH: " << calendar->get( Calendar::WEEK_OF_MONTH, success ) << endl;
- *     cout << "DATE: " << calendar->get( Calendar::DATE, success ) << endl;
- *     cout << "DAY_OF_MONTH: " << calendar->get( Calendar::DAY_OF_MONTH, success ) << endl;
- *     cout << "DAY_OF_YEAR: " << calendar->get( Calendar::DAY_OF_YEAR, success ) << endl;
- *     cout << "DAY_OF_WEEK: " << calendar->get( Calendar::DAY_OF_WEEK, success ) << endl;
- *     cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( Calendar::DAY_OF_WEEK_IN_MONTH, success ) << endl;
- *     cout << "AM_PM: " << calendar->get( Calendar::AM_PM, success ) << endl;
- *     cout << "HOUR: " << calendar->get( Calendar::HOUR, success ) << endl;
- *     cout << "HOUR_OF_DAY: " << calendar->get( Calendar::HOUR_OF_DAY, success ) << endl;
- *     cout << "MINUTE: " << calendar->get( Calendar::MINUTE, success ) << endl;
- *     cout << "SECOND: " << calendar->get( Calendar::SECOND, success ) << endl;
- *     cout << "MILLISECOND: " << calendar->get( Calendar::MILLISECOND, success ) << endl;
- *     cout << "ZONE_OFFSET: " << (calendar->get( Calendar::ZONE_OFFSET, success )/(60*60*1000)) << endl;
- *     cout << "DST_OFFSET: " << (calendar->get( Calendar::DST_OFFSET, success )/(60*60*1000)) << endl;
+ *     cout << "ERA: " << calendar->get( UCAL_ERA, success ) << endl;
+ *     cout << "YEAR: " << calendar->get( UCAL_YEAR, success ) << endl;
+ *     cout << "MONTH: " << calendar->get( UCAL_MONTH, success ) << endl;
+ *     cout << "WEEK_OF_YEAR: " << calendar->get( UCAL_WEEK_OF_YEAR, success ) << endl;
+ *     cout << "WEEK_OF_MONTH: " << calendar->get( UCAL_WEEK_OF_MONTH, success ) << endl;
+ *     cout << "DATE: " << calendar->get( UCAL_DATE, success ) << endl;
+ *     cout << "DAY_OF_MONTH: " << calendar->get( UCAL_DAY_OF_MONTH, success ) << endl;
+ *     cout << "DAY_OF_YEAR: " << calendar->get( UCAL_DAY_OF_YEAR, success ) << endl;
+ *     cout << "DAY_OF_WEEK: " << calendar->get( UCAL_DAY_OF_WEEK, success ) << endl;
+ *     cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( UCAL_DAY_OF_WEEK_IN_MONTH, success ) << endl;
+ *     cout << "AM_PM: " << calendar->get( UCAL_AM_PM, success ) << endl;
+ *     cout << "HOUR: " << calendar->get( UCAL_HOUR, success ) << endl;
+ *     cout << "HOUR_OF_DAY: " << calendar->get( UCAL_HOUR_OF_DAY, success ) << endl;
+ *     cout << "MINUTE: " << calendar->get( UCAL_MINUTE, success ) << endl;
+ *     cout << "SECOND: " << calendar->get( UCAL_SECOND, success ) << endl;
+ *     cout << "MILLISECOND: " << calendar->get( UCAL_MILLISECOND, success ) << endl;
+ *     cout << "ZONE_OFFSET: " << (calendar->get( UCAL_ZONE_OFFSET, success )/(60*60*1000)) << endl;
+ *     cout << "DST_OFFSET: " << (calendar->get( UCAL_DST_OFFSET, success )/(60*60*1000)) << endl;
  *
  *     cout << "Current Time, with hour reset to 3" << endl;
- *     calendar->clear(Calendar::HOUR_OF_DAY); // so doesn't override
- *     calendar->set(Calendar::HOUR, 3);
- *     cout << "ERA: " << calendar->get( Calendar::ERA, success ) << endl;
- *     cout << "YEAR: " << calendar->get( Calendar::YEAR, success ) << endl;
- *     cout << "MONTH: " << calendar->get( Calendar::MONTH, success ) << endl;
- *     cout << "WEEK_OF_YEAR: " << calendar->get( Calendar::WEEK_OF_YEAR, success ) << endl;
- *     cout << "WEEK_OF_MONTH: " << calendar->get( Calendar::WEEK_OF_MONTH, success ) << endl;
- *     cout << "DATE: " << calendar->get( Calendar::DATE, success ) << endl;
- *     cout << "DAY_OF_MONTH: " << calendar->get( Calendar::DAY_OF_MONTH, success ) << endl;
- *     cout << "DAY_OF_YEAR: " << calendar->get( Calendar::DAY_OF_YEAR, success ) << endl;
- *     cout << "DAY_OF_WEEK: " << calendar->get( Calendar::DAY_OF_WEEK, success ) << endl;
- *     cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( Calendar::DAY_OF_WEEK_IN_MONTH, success ) << endl;
- *     cout << "AM_PM: " << calendar->get( Calendar::AM_PM, success ) << endl;
- *     cout << "HOUR: " << calendar->get( Calendar::HOUR, success ) << endl;
- *     cout << "HOUR_OF_DAY: " << calendar->get( Calendar::HOUR_OF_DAY, success ) << endl;
- *     cout << "MINUTE: " << calendar->get( Calendar::MINUTE, success ) << endl;
- *     cout << "SECOND: " << calendar->get( Calendar::SECOND, success ) << endl;
- *     cout << "MILLISECOND: " << calendar->get( Calendar::MILLISECOND, success ) << endl;
- *     cout << "ZONE_OFFSET: " << (calendar->get( Calendar::ZONE_OFFSET, success )/(60*60*1000)) << endl; // in hours
- *     cout << "DST_OFFSET: " << (calendar->get( Calendar::DST_OFFSET, success )/(60*60*1000)) << endl; // in hours
+ *     calendar->clear(UCAL_HOUR_OF_DAY); // so doesn't override
+ *     calendar->set(UCAL_HOUR, 3);
+ *     cout << "ERA: " << calendar->get( UCAL_ERA, success ) << endl;
+ *     cout << "YEAR: " << calendar->get( UCAL_YEAR, success ) << endl;
+ *     cout << "MONTH: " << calendar->get( UCAL_MONTH, success ) << endl;
+ *     cout << "WEEK_OF_YEAR: " << calendar->get( UCAL_WEEK_OF_YEAR, success ) << endl;
+ *     cout << "WEEK_OF_MONTH: " << calendar->get( UCAL_WEEK_OF_MONTH, success ) << endl;
+ *     cout << "DATE: " << calendar->get( UCAL_DATE, success ) << endl;
+ *     cout << "DAY_OF_MONTH: " << calendar->get( UCAL_DAY_OF_MONTH, success ) << endl;
+ *     cout << "DAY_OF_YEAR: " << calendar->get( UCAL_DAY_OF_YEAR, success ) << endl;
+ *     cout << "DAY_OF_WEEK: " << calendar->get( UCAL_DAY_OF_WEEK, success ) << endl;
+ *     cout << "DAY_OF_WEEK_IN_MONTH: " << calendar->get( UCAL_DAY_OF_WEEK_IN_MONTH, success ) << endl;
+ *     cout << "AM_PM: " << calendar->get( UCAL_AM_PM, success ) << endl;
+ *     cout << "HOUR: " << calendar->get( UCAL_HOUR, success ) << endl;
+ *     cout << "HOUR_OF_DAY: " << calendar->get( UCAL_HOUR_OF_DAY, success ) << endl;
+ *     cout << "MINUTE: " << calendar->get( UCAL_MINUTE, success ) << endl;
+ *     cout << "SECOND: " << calendar->get( UCAL_SECOND, success ) << endl;
+ *     cout << "MILLISECOND: " << calendar->get( UCAL_MILLISECOND, success ) << endl;
+ *     cout << "ZONE_OFFSET: " << (calendar->get( UCAL_ZONE_OFFSET, success )/(60*60*1000)) << endl; // in hours
+ *     cout << "DST_OFFSET: " << (calendar->get( UCAL_DST_OFFSET, success )/(60*60*1000)) << endl; // in hours
  *
- *     delete[] ids;
+ *     if (U_FAILURE(success)) {
+ *         cout << "An error occured. success=" << u_errorName(success) << endl;
+ *     }
+ *
+ *     delete ids;
  *     delete calendar; // also deletes pdt
  * \endcode
  * 
@@ -334,38 +344,10 @@ public: * one. Calendar override. * * @param other the Calendar to be compared with this Calendar - * @draft ICU 2.4 + * @stable ICU 2.4 */ virtual UBool isEquivalentTo(const Calendar& other) const; - /** - * (Overrides Calendar) UDate Arithmetic function. Adds the specified (signed) amount - * of time to the given time field, based on the calendar's rules. For more - * information, see the documentation for Calendar::add(). - * - * @param field The time field. - * @param amount The amount of date or time to be added to the field. - * @param status Output param set to success/failure code on exit. If any value - * previously set in the time field is invalid, this will be set to - * an error status. - * @deprecated ICU 2.6. Use add(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead. - */ - virtual void add(EDateFields field, int32_t amount, UErrorCode& status); - - /** - * (Overrides Calendar) UDate Arithmetic function. Adds the specified (signed) amount - * of time to the given time field, based on the calendar's rules. For more - * information, see the documentation for Calendar::add(). - * - * @param field The time field. - * @param amount The amount of date or time to be added to the field. - * @param status Output param set to success/failure code on exit. If any value - * previously set in the time field is invalid, this will be set to - * an error status. - * @draft ICU 2.6. - */ - virtual void add(UCalendarDateFields field, int32_t amount, UErrorCode& status); - /** * (Overrides Calendar) Rolls up or down by the given amount in the specified field. * For more information, see the documentation for Calendar::roll(). @@ -388,104 +370,42 @@ public: * @param status Output param set to success/failure code on exit. If any value * previously set in the time field is invalid, this will be set to * an error status. - * @draft ICU 2.6. + * @stable ICU 2.6. */ virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status); +#ifndef U_HIDE_DEPRECATED_API /** - * (Overrides Calendar) Returns minimum value for the given field. e.g. for - * Gregorian DAY_OF_MONTH, 1. - * @param field the time field. - * @return minimum value for the given field - * @deprecated ICU 2.6. Use getMinimum(UCalendarDateFields field) instead. - */ - virtual int32_t getMinimum(EDateFields field) const; - - /** - * (Overrides Calendar) Returns minimum value for the given field. e.g. for - * Gregorian DAY_OF_MONTH, 1. - * @param field the time field. - * @return minimum value for the given field - * @draft ICU 2.6. - */ - virtual int32_t getMinimum(UCalendarDateFields field) const; - - /** - * (Overrides Calendar) Returns maximum value for the given field. e.g. for - * Gregorian DAY_OF_MONTH, 31. - * @param field the time field. - * @return maximum value for the given field - * @deprecated ICU 2.6. Use getMaximum(UCalendarDateFields field) instead. - */ - virtual int32_t getMaximum(EDateFields field) const; - - /** - * (Overrides Calendar) Returns maximum value for the given field. e.g. for - * Gregorian DAY_OF_MONTH, 31. - * @param field the time field. - * @return maximum value for the given field - * @draft ICU 2.6. - */ - virtual int32_t getMaximum(UCalendarDateFields field) const; - - /** - * (Overrides Calendar) Returns highest minimum value for the given field if varies. - * Otherwise same as getMinimum(). For Gregorian, no difference. - * @param field the time field. - * @return highest minimum value for the given field if varies. - * Otherwise same as getMinimum(). - * @deprecated ICU 2.6. Use getGreatestMinimum(UCalendarDateFields field) instead. - */ - virtual int32_t getGreatestMinimum(EDateFields field) const; - - /** - * (Overrides Calendar) Returns highest minimum value for the given field if varies. - * Otherwise same as getMinimum(). For Gregorian, no difference. - * @param field the time field. - * @return highest minimum value for the given field if varies. - * Otherwise same as getMinimum(). - * @draft ICU 2.6. - */ - virtual int32_t getGreatestMinimum(UCalendarDateFields field) const; - - /** - * (Overrides Calendar) Returns lowest maximum value for the given field if varies. - * Otherwise same as getMaximum(). For Gregorian DAY_OF_MONTH, 28. - * @param field the time field. - * @return lowest maximum value for the given field if varies. - * Otherwise same as getMaximum(). - * @deprecated ICU 2.6. Use getLeastMaximum(UCalendarDateFields field) instead. - */ - virtual int32_t getLeastMaximum(EDateFields field) const; - - /** - * (Overrides Calendar) Returns lowest maximum value for the given field if varies. - * Otherwise same as getMaximum(). For Gregorian DAY_OF_MONTH, 28. + * Return the minimum value that this field could have, given the current date. + * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum(). * @param field the time field. - * @return lowest maximum value for the given field if varies. - * Otherwise same as getMaximum(). - * @draft ICU 2.6. + * @return the minimum value that this field could have, given the current date. + * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead. */ - virtual int32_t getLeastMaximum(UCalendarDateFields field) const; + int32_t getActualMinimum(EDateFields field) const; /** * Return the minimum value that this field could have, given the current date. * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum(). * @param field the time field. + * @param status * @return the minimum value that this field could have, given the current date. - * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead. + * @deprecated ICU 2.6. Use getActualMinimum(UCalendarDateFields field) instead. (Added to ICU 3.0 for signature consistency) */ - int32_t getActualMinimum(EDateFields field) const; + int32_t getActualMinimum(EDateFields field, UErrorCode& status) const; +#endif /* U_HIDE_DEPRECATED_API */ /** * Return the minimum value that this field could have, given the current date. * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum(). * @param field the time field. + * @param status error result. * @return the minimum value that this field could have, given the current date. - * @draft ICU 2.6. + * @stable ICU 3.0 */ - int32_t getActualMinimum(UCalendarDateFields field) const; + int32_t getActualMinimum(UCalendarDateFields field, UErrorCode &status) const; +#ifndef U_HIDE_DEPRECATED_API /** * Return the maximum value that this field could have, given the current date. * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual @@ -496,6 +416,7 @@ public: * @deprecated ICU 2.6. Use getActualMaximum(UCalendarDateFields field) instead. */ int32_t getActualMaximum(EDateFields field) const; +#endif /* U_HIDE_DEPRECATED_API */ /** * Return the maximum value that this field could have, given the current date. @@ -503,10 +424,11 @@ public: * maximum would be 28; for "Feb 3, 1996" it s 29. Similarly for a Hebrew calendar, * for some years the actual maximum for MONTH is 12, and for others 13. * @param field the time field. + * @param status returns any errors that may result from this function call. * @return the maximum value that this field could have, given the current date. - * @draft ICU 2.6. + * @stable ICU 2.6 */ - int32_t getActualMaximum(UCalendarDateFields field) const; + virtual int32_t getActualMaximum(UCalendarDateFields field, UErrorCode& status) const; /** * (Overrides Calendar) Return true if the current date for this Calendar is in @@ -544,69 +466,75 @@ public: * @return The class ID for all objects of this class. * @stable ICU 2.0 */ - static inline UClassID getStaticClassID(void); + static UClassID U_EXPORT2 getStaticClassID(void); /** - * Get the calendar type, "gregorian", for use in DateFormatSymbols. + * Returns the calendar type name string for this Calendar object. + * The returned string is the legacy ICU calendar attribute value, + * for example, "gregorian" or "japanese". * - * @return calendar type - * @internal + * For more details see the Calendar::getType() documentation. + * + * @return legacy calendar type name string + * @stable ICU 49 */ virtual const char * getType() const; -protected: + private: + GregorianCalendar(); // default constructor not implemented + protected: /** - * Called by computeFields. Converts calendar's year into Gregorian Extended Year (where negative = BC) - * @return Current year in Gregorian years, where -3 means 4 BC (1-bcyear) + * Return the ERA. We need a special method for this because the + * default ERA is AD, but a zero (unset) ERA is BC. + * @return the ERA. * @internal */ - virtual int32_t getGregorianYear(UErrorCode &status) const; + virtual int32_t internalGetEra() const; /** - * Called by computeJulianDay. Returns the default month (0-based) for the year, - * taking year and era into account. Defaults to 0 for Gregorian, which doesn't care. + * Return the Julian day number of day before the first day of the + * given month in the given extended year. Subclasses should override + * this method to implement their calendar system. + * @param eyear the extended year + * @param month the zero-based month, or 0 if useMonth is false + * @param useMonth if false, compute the day before the first day of + * the given year, otherwise, compute the day before the first day of + * the given month + * @return the Julian day number of the day before the first + * day of the given month and year * @internal */ - virtual inline int32_t getDefaultMonthInYear() const { return 0; } - + virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, + UBool useMonth) const; /** - * Called by computeJulianDay. Returns the default day (1-based) for the month, - * taking currently-set year and era into account. Defaults to 1 for Gregorian, which doesn't care. + * Subclasses may override this. This method calls + * handleGetMonthLength() to obtain the calendar-specific month + * length. + * @param bestField which field to use to calculate the date + * @return julian day specified by calendar fields. * @internal */ - virtual inline int32_t getDefaultDayInMonth(int32_t /*month*/) const { return 1; } + virtual int32_t handleComputeJulianDay(UCalendarDateFields bestField) ; /** - * (Overrides Calendar) Converts GMT as milliseconds to time field values. - * @param status Fill-in parameter which receives the status of this operation. - * @stable ICU 2.0 + * Return the number of days in the given month of the given extended + * year of this calendar system. Subclasses should override this + * method if they can provide a more correct or more efficient + * implementation than the default implementation in Calendar. + * @internal */ - virtual void computeFields(UErrorCode& status); + virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const; /** - * (Overrides Calendar) Converts Calendar's time field values to GMT as - * milliseconds. - * - * @param status Output param set to success/failure code on exit. If any value - * previously set in the time field is invalid, this will be set to - * an error status. + * Return the number of days in the given extended year of this + * calendar system. Subclasses should override this method if they can + * provide a more correct or more efficient implementation than the + * default implementation in Calendar. * @stable ICU 2.0 */ - virtual void computeTime(UErrorCode& status); - - private: - GregorianCalendar(); // default constructor not implemented - - protected: - /** - * Return the ERA. We need a special method for this because the - * default ERA is AD, but a zero (unset) ERA is BC. - * @return the ERA. - * @internal - */ - virtual int32_t internalGetEra() const; + virtual int32_t handleGetYearLength(int32_t eyear) const; /** * return the length of the given month. @@ -624,7 +552,8 @@ protected: * @internal */ virtual int32_t monthLength(int32_t month, int32_t year) const; - + +#ifndef U_HIDE_INTERNAL_API /** * return the length of the given year. * @param year the given year. @@ -648,6 +577,7 @@ protected: * @internal */ void pinDayOfMonth(void); +#endif /* U_HIDE_INTERNAL_API */ /** * Return the day number with respect to the epoch. January 1, 1970 (Gregorian) @@ -659,17 +589,65 @@ protected: virtual UDate getEpochDay(UErrorCode& status); /** - * Compute the date-based fields given the milliseconds since the epoch start. Do - * not compute the time-based fields (HOUR, MINUTE, etc.). + * Subclass API for defining limits of different types. + * Subclasses must implement this method to return limits for the + * following fields: * - * @param theTime the time in wall millis (either Standard or DST), - * whichever is in effect - * @param quick if true, only compute the ERA, YEAR, MONTH, DATE, - * DAY_OF_WEEK, and DAY_OF_YEAR. - * @param status Fill-in parameter which receives the status of this operation. + *
UCAL_ERA
+     * UCAL_YEAR
+     * UCAL_MONTH
+     * UCAL_WEEK_OF_YEAR
+     * UCAL_WEEK_OF_MONTH
+     * UCAL_DATE (DAY_OF_MONTH on Java)
+     * UCAL_DAY_OF_YEAR
+     * UCAL_DAY_OF_WEEK_IN_MONTH
+     * UCAL_YEAR_WOY
+     * UCAL_EXTENDED_YEAR
+ * + * @param field one of the above field numbers + * @param limitType one of MINIMUM, GREATEST_MINIMUM, + * LEAST_MAXIMUM, or MAXIMUM + * @internal + */ + virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const; + + /** + * Return the extended year defined by the current fields. This will + * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such + * as UCAL_ERA) specific to the calendar system, depending on which set of + * fields is newer. + * @return the extended year * @internal */ - virtual void timeToFields(UDate theTime, UBool quick, UErrorCode& status); + virtual int32_t handleGetExtendedYear(); + + /** + * Subclasses may override this to convert from week fields + * (YEAR_WOY and WEEK_OF_YEAR) to an extended year in the case + * where YEAR, EXTENDED_YEAR are not set. + * The Gregorian implementation assumes a yearWoy in gregorian format, according to the current era. + * @return the extended year, UCAL_EXTENDED_YEAR + * @internal + */ + virtual int32_t handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy); + + + /** + * Subclasses may override this method to compute several fields + * specific to each calendar system. These are: + * + * + * + *

The GregorianCalendar implementation implements + * a calendar with the specified Julian/Gregorian cutover date. + * @internal + */ + virtual void handleComputeFields(int32_t julianDay, UErrorCode &status); private: /** @@ -682,59 +660,6 @@ protected: static double computeJulianDayOfYear(UBool isGregorian, int32_t year, UBool& isLeap); - /** - * Compute the day of week, relative to the first day of week, from - * 0..6, of the current DOW_LOCAL or DAY_OF_WEEK fields. This is - * equivalent to get(DOW_LOCAL) - 1. - * @return the day of week, relative to the first day of week. - */ - int32_t computeRelativeDOW() const; - - /** - * Compute the day of week, relative to the first day of week, - * from 0..6 of the given julian day. - * @param julianDay the given julian day. - * @return the day of week, relative to the first day of week. - */ - int32_t computeRelativeDOW(double julianDay) const; - - /** - * Compute the DOY using the WEEK_OF_YEAR field and the julian day - * of the day BEFORE January 1 of a year (a return value from - * computeJulianDayOfYear). - * @param julianDayOfYear the given julian day of the day BEFORE - * January 1 of a year. - * @return the DOY using the WEEK_OF_YEAR field. - */ - int32_t computeDOYfromWOY(double julianDayOfYear) const; - - /** - * Compute the Julian day number under either the Gregorian or the - * Julian calendar, using the given year and the remaining fields. - * @param isGregorian if true, use the Gregorian calendar - * @param year the adjusted year number, with 0 indicating the - * year 1 BC, -1 indicating 2 BC, etc. - * @return the Julian day number - */ - double computeJulianDay(UBool isGregorian, int32_t year); - - - /** - * Return the week number of a day, within a period. This may be the week number in - * a year, or the week number in a month. Usually this will be a value >= 1, but if - * some initial days of the period are excluded from week 1, because - * minimalDaysInFirstWeek is > 1, then the week number will be zero for those - * initial days. Requires the day of week for the given date in order to determine - * the day of week of the first day of the period. - * - * @param date Day-of-year or day-of-month. Should be 1 for first day of period. - * @param day Day-of-week for given dayOfPeriod. 1-based with 1=Sunday. - * @return Week number, one-based, or zero if the day falls in part of the - * month before the first week, when there are days before the first - * week because the minimum days in the first week is more than one. - */ - int32_t weekNumber(int32_t date, int32_t day); - /** * Validates the values of the set time fields. True if they're all valid. * @return True if the set time fields are all valid. @@ -762,11 +687,15 @@ protected: * milliseconds from the standard epoch. Default is October 15, 1582 * (Gregorian) 00:00:00 UTC, that is, October 4, 1582 (Julian) is followed * by October 15, 1582 (Gregorian). This corresponds to Julian day number - * 2299161. + * 2299161. This is measured from the standard epoch, not in Julian Days. */ - // This is measured from the standard epoch, not in Julian Days. UDate fGregorianCutover; + /** + * Julian day number of the Gregorian cutover + */ + int32_t fCutoverJulianDay; + /** * Midnight, local time (using this Calendar's TimeZone) at or before the * gregorianCutover. This is a pure date value with no time of day or @@ -780,7 +709,11 @@ protected: */ int32_t fGregorianCutoverYear;// = 1582; - static const char fgClassID; + /** + * The year of the gregorianCutover, with 0 representing + * 1 BC, -1 representing 2 BC, etc. + */ + int32_t fGregorianCutoverJulianDay;// = 2299161; /** * Converts time as milliseconds to Julian date. The Julian date used here is not a @@ -801,157 +734,40 @@ protected: static UDate julianDayToMillis(double julian); /** - * Convert a quasi Julian date to the day of the week. The Julian date used here is - * not a true Julian date, since it is measured from midnight, not noon. Return - * value is one-based. - * - * @param julian The given Julian date number. - * @return Day number from 1..7 (SUN..SAT). - */ - static uint8_t julianDayToDayOfWeek(double julian); - - /** - * Divide two long integers, returning the floor of the quotient. - *

- * Unlike the built-in division, this is mathematically well-behaved. - * E.g., -1/4 => 0 - * but floorDivide(-1,4) => -1. - * @param numerator the numerator - * @param denominator a divisor which must be > 0 - * @return the floor of the quotient. - */ - static double floorDivide(double numerator, double denominator); - - /** - * Divide two integers, returning the floor of the quotient. - *

- * Unlike the built-in division, this is mathematically well-behaved. - * E.g., -1/4 => 0 - * but floorDivide(-1,4) => -1. - * @param numerator the numerator - * @param denominator a divisor which must be > 0 - * @return the floor of the quotient. - */ - static int32_t floorDivide(int32_t numerator, int32_t denominator); - - /** - * Divide two integers, returning the floor of the quotient, and - * the modulus remainder. - *

- * Unlike the built-in division, this is mathematically well-behaved. - * E.g., -1/4 => 0 and -1%4 => -1, - * but floorDivide(-1,4) => -1 with remainder[0] => 3. - * @param numerator the numerator - * @param denominator a divisor which must be > 0 - * @param remainder an array of at least one element in which the value - * numerator mod denominator is returned. Unlike numerator - * % denominator, this will always be non-negative. - * @return the floor of the quotient. - */ - static int32_t floorDivide(int32_t numerator, int32_t denominator, int32_t remainder[]); - - /** - * Divide two integers, returning the floor of the quotient, and - * the modulus remainder. - *

- * Unlike the built-in division, this is mathematically well-behaved. - * E.g., -1/4 => 0 and -1%4 => -1, - * but floorDivide(-1,4) => -1 with remainder[0] => 3. - * @param numerator the numerator - * @param denominator a divisor which must be > 0 - * @param remainder an array of at least one element in which the value - * numerator mod denominator is returned. Unlike numerator - * % denominator, this will always be non-negative. - * @return the floor of the quotient. - */ - static int32_t floorDivide(double numerator, int32_t denominator, int32_t remainder[]); + * Used by handleComputeJulianDay() and handleComputeMonthStart(). + * Temporary field indicating whether the calendar is currently Gregorian as opposed to Julian. + */ + UBool fIsGregorian; + + /** + * Used by handleComputeJulianDay() and handleComputeMonthStart(). + * Temporary field indicating that the sense of the gregorian cutover should be inverted + * to handle certain calculations on and around the cutover date. + */ + UBool fInvertGregorian; + public: // internal implementation /** - * @internal * @return TRUE if this calendar has the notion of a default century + * @internal */ virtual UBool haveDefaultCentury() const; /** - * @internal * @return the start of the default century + * @internal */ virtual UDate defaultCenturyStart() const; /** - * @internal * @return the beginning year of the default century + * @internal */ virtual int32_t defaultCenturyStartYear() const; - - private: - /** - * The system maintains a static default century start date. This is initialized - * the first time it is used. Before then, it is set to SYSTEM_DEFAULT_CENTURY to - * indicate an uninitialized state. Once the system default century date and year - * are set, they do not change. - */ - static UDate fgSystemDefaultCenturyStart; - - /** - * See documentation for systemDefaultCenturyStart. - */ - static int32_t fgSystemDefaultCenturyStartYear; - - /** - * Default value that indicates the defaultCenturyStartYear is unitialized - */ - static const int32_t fgSystemDefaultCenturyYear; - - /** - * TODO: (ICU 2.8) use this value instead of SimpleDateFormat::fgSystemDefaultCentury - */ - //static const UDate fgSystemDefaultCentury; - - /** - * Returns the beginning date of the 100-year window that dates with 2-digit years - * are considered to fall within. - * @return the beginning date of the 100-year window that dates with 2-digit years - * are considered to fall within. - */ - UDate internalGetDefaultCenturyStart(void) const; - - /** - * Returns the first year of the 100-year window that dates with 2-digit years - * are considered to fall within. - * @return the first year of the 100-year window that dates with 2-digit years - * are considered to fall within. - */ - int32_t internalGetDefaultCenturyStartYear(void) const; - - /** - * Initializes the 100-year window that dates with 2-digit years are considered - * to fall within so that its start date is 80 years before the current time. - */ - static void initializeSystemDefaultCentury(void); - }; -inline UClassID -GregorianCalendar::getStaticClassID(void) -{ return (UClassID)&fgClassID; } - -inline UClassID -GregorianCalendar::getDynamicClassID(void) const -{ return GregorianCalendar::getStaticClassID(); } - -inline uint8_t GregorianCalendar::julianDayToDayOfWeek(double julian) -{ - // If julian is negative, then julian%7 will be negative, so we adjust - // accordingly. We add 1 because Julian day 0 is Monday. - int8_t dayOfWeek = (int8_t) uprv_fmod(julian + 1, 7); - - uint8_t result = (uint8_t)(dayOfWeek + ((dayOfWeek < 0) ? (7 + UCAL_SUNDAY) : UCAL_SUNDAY)); - return result; -} - U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */