зеркало из https://github.com/mozilla/gecko-dev.git
443 строки
18 KiB
C
443 строки
18 KiB
C
|
/*
|
||
|
********************************************************************************
|
||
|
* *
|
||
|
* COPYRIGHT: *
|
||
|
* (C) Copyright Taligent, Inc., 1997 *
|
||
|
* (C) Copyright International Business Machines Corporation, 1997 *
|
||
|
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
|
||
|
* US Government Users Restricted Rights - Use, duplication, or disclosure *
|
||
|
* restricted by GSA ADP Schedule Contract with IBM Corp. *
|
||
|
* *
|
||
|
********************************************************************************
|
||
|
*
|
||
|
* File GREGOCAL.H
|
||
|
*
|
||
|
* Modification History:
|
||
|
*
|
||
|
* Date Name Description
|
||
|
* 04/22/97 aliu Overhauled header.
|
||
|
********************************************************************************
|
||
|
*/
|
||
|
|
||
|
#ifndef _GREGOCAL
|
||
|
#define _GREGOCAL
|
||
|
|
||
|
#ifndef _CALENDAR
|
||
|
#include "calendar.h"
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* Concrete class which provides the standard calendar used by most of the world.
|
||
|
* <P>
|
||
|
* The standard (Gregorian) calendar has 2 eras, BC and AD.
|
||
|
* <P>
|
||
|
* This implementation handles a single discontinuity, which corresponds by default to
|
||
|
* the date the Gregorian calendar was originally instituted (October 15, 1582). Not all
|
||
|
* countries adopted the Gregorian calendar then, so this cutover date may be changed by
|
||
|
* the caller.
|
||
|
* <P>
|
||
|
* Prior to the institution of the Gregorian Calendar, New Year's Day was March 25. To
|
||
|
* avoid confusion, this Calendar always uses January 1. A manual adjustment may be made
|
||
|
* if desired for dates that are prior to the Gregorian changeover and which fall
|
||
|
* between January 1 and March 24.
|
||
|
*/
|
||
|
#ifdef NLS_MAC
|
||
|
#pragma export on
|
||
|
#endif
|
||
|
|
||
|
class T_FORMAT_API GregorianCalendar: public Calendar {
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* Useful constants for GregorianCalendar and TimeZone.
|
||
|
*/
|
||
|
enum EEras {
|
||
|
BC,
|
||
|
AD
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Constructs a default GregorianCalendar using the current time in the default time
|
||
|
* zone with the default locale.
|
||
|
*
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar based on the current time in the given time zone
|
||
|
* with the default locale. Clients are no longer responsible for deleting the given
|
||
|
* time zone object after it's adopted.
|
||
|
*
|
||
|
* @param zoneToAdopt The given timezone.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(TimeZone* zoneToAdopt, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar based on the current time in the given time zone
|
||
|
* with the default locale.
|
||
|
*
|
||
|
* @param zone The given timezone.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(const TimeZone& zone, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar based on the current time in the default time zone
|
||
|
* with the given locale.
|
||
|
*
|
||
|
* @param aLocale The given locale.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(const Locale& aLocale, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar based on the current time in the given time zone
|
||
|
* with the given locale. Clients are no longer responsible for deleting the given
|
||
|
* time zone object after it's adopted.
|
||
|
*
|
||
|
* @param zoneToAdopt The given timezone.
|
||
|
* @param aLocale The given locale.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(TimeZone* zoneToAdopt, const Locale& aLocale, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar based on the current time in the given time zone
|
||
|
* with the given locale.
|
||
|
*
|
||
|
* @param zone The given timezone.
|
||
|
* @param aLocale The given locale.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(const TimeZone& zone, const Locale& aLocale, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar with the given AD date set in the default time
|
||
|
* zone with the default locale.
|
||
|
*
|
||
|
* @param year The value used to set the YEAR time field in the calendar.
|
||
|
* @param month The value used to set the MONTH time field in the calendar. Month
|
||
|
* value is 0-based. e.g., 0 for January.
|
||
|
* @param date The value used to set the DATE time field in the calendar.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(t_int32 year, t_int32 month, t_int32 date, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar with the given AD date and time set for the
|
||
|
* default time zone with the default locale.
|
||
|
*
|
||
|
* @param year The value used to set the YEAR time field in the calendar.
|
||
|
* @param month The value used to set the MONTH time field in the calendar. Month
|
||
|
* value is 0-based. e.g., 0 for January.
|
||
|
* @param date The value used to set the DATE time field in the calendar.
|
||
|
* @param hour The value used to set the HOUR_OF_DAY time field in the calendar.
|
||
|
* @param minute The value used to set the MINUTE time field in the calendar.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(t_int32 year, t_int32 month, t_int32 date, t_int32 hour, t_int32 minute, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Constructs a GregorianCalendar with the given AD date and time set for the
|
||
|
* default time zone with the default locale.
|
||
|
*
|
||
|
* @param year The value used to set the YEAR time field in the calendar.
|
||
|
* @param month The value used to set the MONTH time field in the calendar. Month
|
||
|
* value is 0-based. e.g., 0 for January.
|
||
|
* @param date The value used to set the DATE time field in the calendar.
|
||
|
* @param hour The value used to set the HOUR_OF_DAY time field in the calendar.
|
||
|
* @param minute The value used to set the MINUTE time field in the calendar.
|
||
|
* @param second The value used to set the SECOND time field in the calendar.
|
||
|
* @param success Indicates the status of GregorianCalendar object construction.
|
||
|
* Returns ZERO_ERROR if constructed successfully.
|
||
|
*/
|
||
|
GregorianCalendar(t_int32 year, t_int32 month, t_int32 date, t_int32 hour, t_int32 minute, t_int32 second, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Destructor
|
||
|
*/
|
||
|
virtual ~GregorianCalendar();
|
||
|
|
||
|
/**
|
||
|
* Copy constructor
|
||
|
*/
|
||
|
GregorianCalendar(const GregorianCalendar& source);
|
||
|
|
||
|
/**
|
||
|
* Default assignment operator
|
||
|
*/
|
||
|
GregorianCalendar& operator=(const GregorianCalendar& right);
|
||
|
|
||
|
/**
|
||
|
* Create and return a polymorphic copy of this calendar.
|
||
|
*/
|
||
|
virtual Calendar* clone() const;
|
||
|
|
||
|
/**
|
||
|
* Sets the GregorianCalendar change date. This is the point when the switch from
|
||
|
* Julian dates to Gregorian dates occurred. Default is 00:00:00 local time, October
|
||
|
* 15, 1582. Previous to this time and date will be Julian dates.
|
||
|
*
|
||
|
* @param date The given Gregorian cutover date.
|
||
|
* @param success Output param set to success/failure code on exit.
|
||
|
*/
|
||
|
void setGregorianChange(Date date, ErrorCode& success);
|
||
|
|
||
|
/**
|
||
|
* Gets the Gregorian Calendar change date. This is the point when the switch from
|
||
|
* Julian dates to Gregorian dates occurred. Default is 00:00:00 local time, October
|
||
|
* 15, 1582. Previous to this time and date will be Julian dates.
|
||
|
*
|
||
|
* @return The Gregorian cutover time for this calendar.
|
||
|
*/
|
||
|
Date getGregorianChange() const;
|
||
|
|
||
|
/**
|
||
|
* Return true if the given year is a leap year. Determination of whether a year is
|
||
|
* a leap year is actually very complicated. We do something crude and mostly
|
||
|
* correct here, but for a real determination you need a lot of contextual
|
||
|
* information. For example, in Sweden, the change from Julian to Gregorian happened
|
||
|
* in a complex way resulting in missed leap years and double leap years between
|
||
|
* 1700 and 1753. Another example is that after the start of the Julian calendar in
|
||
|
* 45 B.C., the leap years did not regularize until 8 A.D. This method ignores these
|
||
|
* quirks, and pays attention only to the Julian onset date and the Gregorian
|
||
|
* cutover (which can be changed).
|
||
|
*
|
||
|
* @param year The given year.
|
||
|
* @return True if the given year is a leap year; false otherwise.
|
||
|
*/
|
||
|
t_bool isLeapYear(t_int32 year) const;
|
||
|
|
||
|
/**
|
||
|
* Compares the equality of two GregorianCalendar objects. Objects of different
|
||
|
* subclasses are considered unequal. This is a strict equality test; see the
|
||
|
* documentation for Calendar::operator==().
|
||
|
*
|
||
|
* @param that The GregorianCalendar object to be compared with.
|
||
|
* @return True if the given GregorianCalendar is the same as this
|
||
|
* GregorianCalendar; false otherwise.
|
||
|
*/
|
||
|
virtual t_bool operator==(const Calendar& that) const;
|
||
|
|
||
|
/**
|
||
|
* Calendar override.
|
||
|
* Return true if another Calendar object is equivalent to this one. An equivalent
|
||
|
* Calendar will behave exactly as this one does, but may be set to a different time.
|
||
|
*/
|
||
|
virtual t_bool equivalentTo(const Calendar& other) const;
|
||
|
|
||
|
/**
|
||
|
* (Overrides Calendar) Date 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.
|
||
|
*/
|
||
|
virtual void add(EDateFields field, t_int32 amount, ErrorCode& 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 field The time field.
|
||
|
* @param amount Indicates amount to 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.
|
||
|
*/
|
||
|
virtual void roll(EDateFields field, int amount, ErrorCode& status);
|
||
|
|
||
|
/**
|
||
|
* (Overrides Calendar) Returns minimum value for the given field. e.g. for
|
||
|
* Gregorian DAY_OF_MONTH, 1.
|
||
|
*/
|
||
|
virtual t_int32 getMinimum(EDateFields field) const;
|
||
|
|
||
|
/**
|
||
|
* (Overrides Calendar) Returns maximum value for the given field. e.g. for
|
||
|
* Gregorian DAY_OF_MONTH, 31.
|
||
|
*/
|
||
|
virtual t_int32 getMaximum(EDateFields field) const;
|
||
|
|
||
|
/**
|
||
|
* (Overrides Calendar) Returns highest minimum value for the given field if varies.
|
||
|
* Otherwise same as getMinimum(). For Gregorian, no difference.
|
||
|
*/
|
||
|
virtual t_int32 getGreatestMinimum(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.
|
||
|
*/
|
||
|
virtual t_int32 getLeastMaximum(EDateFields field) const;
|
||
|
|
||
|
/**
|
||
|
* (Overrides Calendar) Return true if the current date for this Calendar is in
|
||
|
* Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
|
||
|
*
|
||
|
* @param status Fill-in parameter which receives the status of this operation.
|
||
|
* @return True if the current date for this Calendar is in Daylight Savings Time,
|
||
|
* false, otherwise.
|
||
|
*/
|
||
|
virtual t_bool inDaylightTime(ErrorCode& status) const;
|
||
|
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
|
||
|
* override. This method is to implement a simple version of RTTI, since not all C++
|
||
|
* compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
|
||
|
* this method.
|
||
|
*
|
||
|
* @return The class ID for this object. All objects of a given class have the
|
||
|
* same class ID. Objects of other classes have different class IDs.
|
||
|
*/
|
||
|
virtual ClassID getDynamicClassID() const { return (ClassID)&fgClassID; }
|
||
|
|
||
|
/**
|
||
|
* Return the class ID for this class. This is useful only for comparing to a return
|
||
|
* value from getDynamicClassID(). For example:
|
||
|
*
|
||
|
* Base* polymorphic_pointer = createPolymorphicObject();
|
||
|
* if (polymorphic_pointer->getDynamicClassID() ==
|
||
|
* Derived::getStaticClassID()) ...
|
||
|
*
|
||
|
* @return The class ID for all objects of this class.
|
||
|
*/
|
||
|
static ClassID getStaticClassID() { return (ClassID)&fgClassID; }
|
||
|
|
||
|
protected:
|
||
|
|
||
|
/**
|
||
|
* (Overrides Calendar) Converts GMT as milliseconds to time field values.
|
||
|
*/
|
||
|
virtual void computeFields(ErrorCode& status);
|
||
|
|
||
|
/**
|
||
|
* (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.
|
||
|
*/
|
||
|
virtual void computeTime(ErrorCode& status);
|
||
|
|
||
|
private:
|
||
|
|
||
|
/**
|
||
|
* Return the length of the given month in the given year, accounting for Gregorian
|
||
|
* leap years.
|
||
|
*/
|
||
|
int monthLength(int month, int year) const;
|
||
|
|
||
|
/**
|
||
|
* Converts time as milliseconds to Julian date. The Julian date used here is not a
|
||
|
* true Julian date, since it is measured from midnight, not noon.
|
||
|
*
|
||
|
* @param millis The given milliseconds.
|
||
|
* @return The Julian date number.
|
||
|
*/
|
||
|
static long millisToJulianDay(Date millis);
|
||
|
|
||
|
/**
|
||
|
* Converts Julian date to time as milliseconds. The Julian date used here is not a
|
||
|
* true Julian date, since it is measured from midnight, not noon.
|
||
|
*
|
||
|
* @param julian The given Julian date number.
|
||
|
* @return Time as milliseconds.
|
||
|
*/
|
||
|
static Date julianDayToMillis(long 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.
|
||
|
*
|
||
|
* @return Day number from 1..7 (SUN..SAT).
|
||
|
*/
|
||
|
static int julianDayToDayOfWeek(long julian);
|
||
|
|
||
|
/**
|
||
|
* Compute the date-based fields given the milliseconds since the epoch start. Do
|
||
|
* not compute the time-based fields (HOUR, MINUTE, etc.).
|
||
|
*
|
||
|
* @param theTime The given time as LOCAL milliseconds, not UTC.
|
||
|
*/
|
||
|
void timeToFields(Date theTime, ErrorCode& status);
|
||
|
|
||
|
/**
|
||
|
* 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.
|
||
|
*/
|
||
|
int weekNumber(int date, int day);
|
||
|
|
||
|
/**
|
||
|
* Validates the values of the set time fields. True if they're all valid.
|
||
|
*/
|
||
|
t_bool validateFields() const;
|
||
|
|
||
|
/**
|
||
|
* Validates the value of the given time field. True if it's valid.
|
||
|
*/
|
||
|
t_bool boundsCheck(t_int32 value, EDateFields field) const;
|
||
|
|
||
|
// This is measured from the standard epoch, not in Julian Days.
|
||
|
Date fGregorianCutover;
|
||
|
|
||
|
static char fgClassID;
|
||
|
|
||
|
static const Date kPapalCutover; // Cutover decreed by Pope Gregory
|
||
|
static const Date kJulianOnset; // Onset of Julian calendar, 45 B.C.
|
||
|
static const long kEpochStartAsJulianDay; // 1970-01-01 as Julian Day
|
||
|
static const int kMonthLength[]; // lengths of months in non-leap year
|
||
|
static const int kLeapMonthLength[]; // lengths of months in leap year
|
||
|
static const int NUM_DAYS[]; // day-in-year numbers for the first of each month in non-leap years
|
||
|
static const int LEAP_NUM_DAYS[]; // day-in-year numbers for the firstof each month in leap years
|
||
|
static const Date EARLIEST_USABLE_MILLIS; // earliest Data value for which we can compute fields
|
||
|
static const int EARLIEST_USABLE_YEAR; // earliest year for which we can compute dates and fields
|
||
|
static const Date EARLIEST_INVALID_MILLIS; // earliest Date value for which we can't compute fields
|
||
|
// (i.e., high bound of valid range)
|
||
|
static const Date ONE_WEEK; // number of milliseconds in a week
|
||
|
};
|
||
|
|
||
|
#ifdef NLS_MAC
|
||
|
#pragma export off
|
||
|
#endif
|
||
|
|
||
|
|
||
|
inline int GregorianCalendar::julianDayToDayOfWeek(long julian)
|
||
|
{
|
||
|
// If julian is negative, then julian%7 will be negative, so we adjust
|
||
|
// accordingly. We add 1 because Julian day 0 is Monday.
|
||
|
int dayOfWeek = (julian + 1) % 7;
|
||
|
return dayOfWeek + ((dayOfWeek < 0) ? (7 + SUNDAY) : SUNDAY);
|
||
|
}
|
||
|
|
||
|
#endif // _GREGOCAL
|
||
|
//eof
|