1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/chnsecal.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,281 @@ 1.4 +/* 1.5 + ***************************************************************************** 1.6 + * Copyright (C) 2007-2013, International Business Machines Corporation 1.7 + * and others. All Rights Reserved. 1.8 + ***************************************************************************** 1.9 + * 1.10 + * File CHNSECAL.H 1.11 + * 1.12 + * Modification History: 1.13 + * 1.14 + * Date Name Description 1.15 + * 9/18/2007 ajmacher ported from java ChineseCalendar 1.16 + ***************************************************************************** 1.17 + */ 1.18 + 1.19 +#ifndef CHNSECAL_H 1.20 +#define CHNSECAL_H 1.21 + 1.22 +#include "unicode/utypes.h" 1.23 + 1.24 +#if !UCONFIG_NO_FORMATTING 1.25 + 1.26 +#include "unicode/calendar.h" 1.27 +#include "unicode/timezone.h" 1.28 + 1.29 +U_NAMESPACE_BEGIN 1.30 + 1.31 +/** 1.32 + * <code>ChineseCalendar</code> is a concrete subclass of {@link Calendar} 1.33 + * that implements a traditional Chinese calendar. The traditional Chinese 1.34 + * calendar is a lunisolar calendar: Each month starts on a new moon, and 1.35 + * the months are numbered according to solar events, specifically, to 1.36 + * guarantee that month 11 always contains the winter solstice. In order 1.37 + * to accomplish this, leap months are inserted in certain years. Leap 1.38 + * months are numbered the same as the month they follow. The decision of 1.39 + * which month is a leap month depends on the relative movements of the sun 1.40 + * and moon. 1.41 + * 1.42 + * <p>This class defines one addition field beyond those defined by 1.43 + * <code>Calendar</code>: The <code>IS_LEAP_MONTH</code> field takes the 1.44 + * value of 0 for normal months, or 1 for leap months. 1.45 + * 1.46 + * <p>All astronomical computations are performed with respect to a time 1.47 + * zone of GMT+8:00 and a longitude of 120 degrees east. Although some 1.48 + * calendars implement a historically more accurate convention of using 1.49 + * Beijing's local longitude (116 degrees 25 minutes east) and time zone 1.50 + * (GMT+7:45:40) for dates before 1929, we do not implement this here. 1.51 + * 1.52 + * <p>Years are counted in two different ways in the Chinese calendar. The 1.53 + * first method is by sequential numbering from the 61st year of the reign 1.54 + * of Huang Di, 2637 BCE, which is designated year 1 on the Chinese 1.55 + * calendar. The second method uses 60-year cycles from the same starting 1.56 + * point, which is designated year 1 of cycle 1. In this class, the 1.57 + * <code>EXTENDED_YEAR</code> field contains the sequential year count. 1.58 + * The <code>ERA</code> field contains the cycle number, and the 1.59 + * <code>YEAR</code> field contains the year of the cycle, a value between 1.60 + * 1 and 60. 1.61 + * 1.62 + * <p>There is some variation in what is considered the starting point of 1.63 + * the calendar, with some sources starting in the first year of the reign 1.64 + * of Huang Di, rather than the 61st. This gives continuous year numbers 1.65 + * 60 years greater and cycle numbers one greater than what this class 1.66 + * implements. 1.67 + * 1.68 + * <p>Because <code>ChineseCalendar</code> defines an additional field and 1.69 + * redefines the way the <code>ERA</code> field is used, it requires a new 1.70 + * format class, <code>ChineseDateFormat</code>. As always, use the 1.71 + * methods <code>DateFormat.getXxxInstance(Calendar cal,...)</code> to 1.72 + * obtain a formatter for this calendar. 1.73 + * 1.74 + * <p>References:<ul> 1.75 + * 1.76 + * <li>Dershowitz and Reingold, <i>Calendrical Calculations</i>, 1.77 + * Cambridge University Press, 1997</li> 1.78 + * 1.79 + * <li>Helmer Aslaksen's 1.80 + * <a href="http://www.math.nus.edu.sg/aslaksen/calendar/chinese.shtml"> 1.81 + * Chinese Calendar page</a></li> 1.82 + * 1.83 + * <li>The <a href="http://www.tondering.dk/claus/calendar.html"> 1.84 + * Calendar FAQ</a></li> 1.85 + * 1.86 + * </ul> 1.87 + * 1.88 + * <p> 1.89 + * This class should only be subclassed to implement variants of the Chinese lunar calendar.</p> 1.90 + * <p> 1.91 + * ChineseCalendar usually should be instantiated using 1.92 + * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code> 1.93 + * with the tag <code>"@calendar=chinese"</code>.</p> 1.94 + * 1.95 + * @see com.ibm.icu.text.ChineseDateFormat 1.96 + * @see com.ibm.icu.util.Calendar 1.97 + * @author Alan Liu 1.98 + * @internal 1.99 + */ 1.100 +class U_I18N_API ChineseCalendar : public Calendar { 1.101 + public: 1.102 + //------------------------------------------------------------------------- 1.103 + // Constructors... 1.104 + //------------------------------------------------------------------------- 1.105 + 1.106 + /** 1.107 + * Constructs a ChineseCalendar based on the current time in the default time zone 1.108 + * with the given locale. 1.109 + * 1.110 + * @param aLocale The given locale. 1.111 + * @param success Indicates the status of ChineseCalendar object construction. 1.112 + * Returns U_ZERO_ERROR if constructed successfully. 1.113 + * @internal 1.114 + */ 1.115 + ChineseCalendar(const Locale& aLocale, UErrorCode &success); 1.116 + 1.117 + protected: 1.118 + 1.119 + /** 1.120 + * Constructs a ChineseCalendar based on the current time in the default time zone 1.121 + * with the given locale, using the specified epoch year and time zone for 1.122 + * astronomical calculations. 1.123 + * 1.124 + * @param aLocale The given locale. 1.125 + * @param epochYear The epoch year to use for calculation. 1.126 + * @param zoneAstroCalc The TimeZone to use for astronomical calculations. If null, 1.127 + * will be set appropriately for Chinese calendar (UTC + 8:00). 1.128 + * @param success Indicates the status of ChineseCalendar object construction; 1.129 + * if successful, will not be changed to an error value. 1.130 + * @internal 1.131 + */ 1.132 + ChineseCalendar(const Locale& aLocale, int32_t epochYear, const TimeZone* zoneAstroCalc, UErrorCode &success); 1.133 + 1.134 + public: 1.135 + /** 1.136 + * Copy Constructor 1.137 + * @internal 1.138 + */ 1.139 + ChineseCalendar(const ChineseCalendar& other); 1.140 + 1.141 + /** 1.142 + * Destructor. 1.143 + * @internal 1.144 + */ 1.145 + virtual ~ChineseCalendar(); 1.146 + 1.147 + // clone 1.148 + virtual Calendar* clone() const; 1.149 + 1.150 + private: 1.151 + 1.152 + //------------------------------------------------------------------------- 1.153 + // Internal data.... 1.154 + //------------------------------------------------------------------------- 1.155 + 1.156 + UBool isLeapYear; 1.157 + int32_t fEpochYear; // Start year of this Chinese calendar instance. 1.158 + const TimeZone* fZoneAstroCalc; // Zone used for the astronomical calculation 1.159 + // of this Chinese calendar instance. 1.160 + 1.161 + //---------------------------------------------------------------------- 1.162 + // Calendar framework 1.163 + //---------------------------------------------------------------------- 1.164 + 1.165 + protected: 1.166 + virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const; 1.167 + virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const; 1.168 + virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const; 1.169 + virtual int32_t handleGetExtendedYear(); 1.170 + virtual void handleComputeFields(int32_t julianDay, UErrorCode &status); 1.171 + virtual const UFieldResolutionTable* getFieldResolutionTable() const; 1.172 + 1.173 + public: 1.174 + virtual void add(UCalendarDateFields field, int32_t amount, UErrorCode &status); 1.175 + virtual void add(EDateFields field, int32_t amount, UErrorCode &status); 1.176 + virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode &status); 1.177 + virtual void roll(EDateFields field, int32_t amount, UErrorCode &status); 1.178 + 1.179 + //---------------------------------------------------------------------- 1.180 + // Internal methods & astronomical calculations 1.181 + //---------------------------------------------------------------------- 1.182 + 1.183 + private: 1.184 + 1.185 + static const UFieldResolutionTable CHINESE_DATE_PRECEDENCE[]; 1.186 + 1.187 + double daysToMillis(double days) const; 1.188 + double millisToDays(double millis) const; 1.189 + virtual int32_t winterSolstice(int32_t gyear) const; 1.190 + virtual int32_t newMoonNear(double days, UBool after) const; 1.191 + virtual int32_t synodicMonthsBetween(int32_t day1, int32_t day2) const; 1.192 + virtual int32_t majorSolarTerm(int32_t days) const; 1.193 + virtual UBool hasNoMajorSolarTerm(int32_t newMoon) const; 1.194 + virtual UBool isLeapMonthBetween(int32_t newMoon1, int32_t newMoon2) const; 1.195 + virtual void computeChineseFields(int32_t days, int32_t gyear, 1.196 + int32_t gmonth, UBool setAllFields); 1.197 + virtual int32_t newYear(int32_t gyear) const; 1.198 + virtual void offsetMonth(int32_t newMoon, int32_t dom, int32_t delta); 1.199 + const TimeZone* getChineseCalZoneAstroCalc(void) const; 1.200 + 1.201 + // UObject stuff 1.202 + public: 1.203 + /** 1.204 + * @return The class ID for this object. All objects of a given class have the 1.205 + * same class ID. Objects of other classes have different class IDs. 1.206 + * @internal 1.207 + */ 1.208 + virtual UClassID getDynamicClassID(void) const; 1.209 + 1.210 + /** 1.211 + * Return the class ID for this class. This is useful only for comparing to a return 1.212 + * value from getDynamicClassID(). For example: 1.213 + * 1.214 + * Base* polymorphic_pointer = createPolymorphicObject(); 1.215 + * if (polymorphic_pointer->getDynamicClassID() == 1.216 + * Derived::getStaticClassID()) ... 1.217 + * 1.218 + * @return The class ID for all objects of this class. 1.219 + * @internal 1.220 + */ 1.221 + static UClassID U_EXPORT2 getStaticClassID(void); 1.222 + 1.223 + /** 1.224 + * return the calendar type, "chinese". 1.225 + * 1.226 + * @return calendar type 1.227 + * @internal 1.228 + */ 1.229 + virtual const char * getType() const; 1.230 + 1.231 + 1.232 + protected: 1.233 + /** 1.234 + * (Overrides Calendar) Return true if the current date for this Calendar is in 1.235 + * Daylight Savings Time. Recognizes DST_OFFSET, if it is set. 1.236 + * 1.237 + * @param status Fill-in parameter which receives the status of this operation. 1.238 + * @return True if the current date for this Calendar is in Daylight Savings Time, 1.239 + * false, otherwise. 1.240 + * @internal 1.241 + */ 1.242 + virtual UBool inDaylightTime(UErrorCode& status) const; 1.243 + 1.244 + 1.245 + /** 1.246 + * Returns TRUE because the Islamic Calendar does have a default century 1.247 + * @internal 1.248 + */ 1.249 + virtual UBool haveDefaultCentury() const; 1.250 + 1.251 + /** 1.252 + * Returns the date of the start of the default century 1.253 + * @return start of century - in milliseconds since epoch, 1970 1.254 + * @internal 1.255 + */ 1.256 + virtual UDate defaultCenturyStart() const; 1.257 + 1.258 + /** 1.259 + * Returns the year in which the default century begins 1.260 + * @internal 1.261 + */ 1.262 + virtual int32_t defaultCenturyStartYear() const; 1.263 + 1.264 + private: // default century stuff. 1.265 + 1.266 + /** 1.267 + * Returns the beginning date of the 100-year window that dates 1.268 + * with 2-digit years are considered to fall within. 1.269 + */ 1.270 + UDate internalGetDefaultCenturyStart(void) const; 1.271 + 1.272 + /** 1.273 + * Returns the first year of the 100-year window that dates with 1.274 + * 2-digit years are considered to fall within. 1.275 + */ 1.276 + int32_t internalGetDefaultCenturyStartYear(void) const; 1.277 + 1.278 + ChineseCalendar(); // default constructor not implemented 1.279 +}; 1.280 + 1.281 +U_NAMESPACE_END 1.282 + 1.283 +#endif 1.284 +#endif