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 */