/*
-* 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
* 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.
********************************************************************************
*/
#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.
* <P>
* The standard (Gregorian) calendar has 2 eras, BC and AD.
* <pre>
* \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;
* }
*
* 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
* </pre>
* 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().
* @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
* @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.
* 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
* @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.
* @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.
* @internal
*/
void pinDayOfMonth(void);
+#endif /* U_HIDE_INTERNAL_API */
/**
* Return the day number with respect to the epoch. January 1, 1970 (Gregorian)
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.
+ * <pre>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</pre>
+ *
+ * @param field one of the above field numbers
+ * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
+ * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
+ * @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:
+ *
+ * <ul><li>ERA
+ * <li>YEAR
+ * <li>MONTH
+ * <li>DAY_OF_MONTH
+ * <li>DAY_OF_YEAR
+ * <li>EXTENDED_YEAR</ul>
+ *
+ * <p>The GregorianCalendar implementation implements
+ * a calendar with the specified Julian/Gregorian cutover date.
+ * @internal
+ */
+ virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
private:
/**
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.
* 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
*/
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
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.
- * <p>
- * Unlike the built-in division, this is mathematically well-behaved.
- * E.g., <code>-1/4</code> => 0
- * but <code>floorDivide(-1,4)</code> => -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.
- * <p>
- * Unlike the built-in division, this is mathematically well-behaved.
- * E.g., <code>-1/4</code> => 0
- * but <code>floorDivide(-1,4)</code> => -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.
- * <p>
- * Unlike the built-in division, this is mathematically well-behaved.
- * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
- * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 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
- * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
- * % denominator</code>, 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.
- * <p>
- * Unlike the built-in division, this is mathematically well-behaved.
- * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
- * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 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
- * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
- * % denominator</code>, 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 */