]>
git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/gregoimp.h
2 **********************************************************************
3 * Copyright (c) 2003-2004, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
7 * Created: September 2 2003
9 **********************************************************************
13 #include "unicode/utypes.h"
14 #if !UCONFIG_NO_FORMATTING
16 #include "unicode/ures.h"
17 #include "unicode/locid.h"
23 * A utility class providing mathematical functions used by time zone
24 * and calendar code. Do not instantiate.
26 class U_I18N_API Math
{
29 * Divide two integers, returning the floor of the quotient.
30 * Unlike the built-in division, this is mathematically
31 * well-behaved. E.g., <code>-1/4</code> => 0 but
32 * <code>floorDivide(-1,4)</code> => -1.
33 * @param numerator the numerator
34 * @param denominator a divisor which must be != 0
35 * @return the floor of the quotient
37 static int32_t floorDivide(int32_t numerator
, int32_t denominator
);
40 * Divide two numbers, returning the floor of the quotient.
41 * Unlike the built-in division, this is mathematically
42 * well-behaved. E.g., <code>-1/4</code> => 0 but
43 * <code>floorDivide(-1,4)</code> => -1.
44 * @param numerator the numerator
45 * @param denominator a divisor which must be != 0
46 * @return the floor of the quotient
48 static inline double floorDivide(double numerator
, double denominator
);
51 * Divide two numbers, returning the floor of the quotient and
52 * the modulus remainder. Unlike the built-in division, this is
53 * mathematically well-behaved. E.g., <code>-1/4</code> => 0 and
54 * <code>-1%4</code> => -1, but <code>floorDivide(-1,4)</code> =>
55 * -1 with <code>remainder</code> => 3. NOTE: If numerator is
56 * too large, the returned quotient may overflow.
57 * @param numerator the numerator
58 * @param denominator a divisor which must be != 0
59 * @param remainder output parameter to receive the
60 * remainder. Unlike <code>numerator % denominator</code>, this
61 * will always be non-negative, in the half-open range <code>[0,
62 * |denominator|)</code>.
63 * @return the floor of the quotient
65 static int32_t floorDivide(double numerator
, int32_t denominator
,
69 * For a positive divisor, return the quotient and remainder
70 * such that dividend = quotient*divisor + remainder and
71 * 0 <= remainder < divisor.
73 * Works around edge-case bugs. Handles pathological input
74 * (divident >> divisor) reasonably.
76 * Calling with a divisor <= 0 is disallowed.
78 static double floorDivide(double dividend
, double divisor
,
82 // Useful millisecond constants
83 #define kOneDay (1.0 * U_MILLIS_PER_DAY) // 86,400,000
84 #define kOneHour (60*60*1000)
85 #define kOneMinute 60000
86 #define kOneSecond 1000
87 #define kOneMillisecond 1
88 #define kOneWeek (7.0 * kOneDay) // 604,800,000
91 #define kJan1_1JulianDay 1721426 // January 1, year 1 (Gregorian)
93 #define kEpochStartAsJulianDay 2440588 // January 1, 1970 (Gregorian)
95 #define kEpochYear 1970
98 #define kEarliestViableMillis -185331720384000000.0 // minimum representable by julian day -1e17
100 #define kLatestViableMillis 185753453990400000.0 // max representable by julian day +1e17
103 * The minimum supported Julian day. This value is equivalent to
106 #define MIN_JULIAN (-0x7F000000)
109 * The minimum supported epoch milliseconds. This value is equivalent
112 #define MIN_MILLIS ((MIN_JULIAN - kEpochStartAsJulianDay) * kOneDay)
115 * The maximum supported Julian day. This value is equivalent to
118 #define MAX_JULIAN (+0x7F000000)
121 * The maximum supported epoch milliseconds. This value is equivalent
124 #define MAX_MILLIS ((MAX_JULIAN - kEpochStartAsJulianDay) * kOneDay)
127 * A utility class providing proleptic Gregorian calendar functions
128 * used by time zone and calendar code. Do not instantiate.
130 * Note: Unlike GregorianCalendar, all computations performed by this
131 * class occur in the pure proleptic GregorianCalendar.
133 class U_I18N_API Grego
{
136 * Return TRUE if the given year is a leap year.
137 * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
138 * @return TRUE if the year is a leap year
140 static inline UBool
isLeapYear(int32_t year
);
143 * Return the number of days in the given month.
144 * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
145 * @param month 0-based month, with 0==Jan
146 * @return the number of days in the given month
148 static inline int8_t monthLength(int32_t year
, int32_t month
);
151 * Return the length of a previous month of the Gregorian calendar.
152 * @param y the extended year
153 * @param m the 0-based month number
154 * @return the number of days in the month previous to the given month
156 static inline int8_t previousMonthLength(int y
, int m
);
159 * Convert a year, month, and day-of-month, given in the proleptic
160 * Gregorian calendar, to 1970 epoch days.
161 * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
162 * @param month 0-based month, with 0==Jan
163 * @param dom 1-based day of month
164 * @return the day number, with day 0 == Jan 1 1970
166 static double fieldsToDay(int32_t year
, int32_t month
, int32_t dom
);
169 * Convert a 1970-epoch day number to proleptic Gregorian year,
170 * month, day-of-month, and day-of-week.
171 * @param day 1970-epoch day (integral value)
172 * @param year output parameter to receive year
173 * @param month output parameter to receive month (0-based, 0==Jan)
174 * @param dom output parameter to receive day-of-month (1-based)
175 * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
176 * @param doy output parameter to receive day-of-year (1-based)
178 static void dayToFields(double day
, int32_t& year
, int32_t& month
,
179 int32_t& dom
, int32_t& dow
, int32_t& doy
);
182 * Convert a 1970-epoch day number to proleptic Gregorian year,
183 * month, day-of-month, and day-of-week.
184 * @param day 1970-epoch day (integral value)
185 * @param year output parameter to receive year
186 * @param month output parameter to receive month (0-based, 0==Jan)
187 * @param dom output parameter to receive day-of-month (1-based)
188 * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
190 static inline void dayToFields(double day
, int32_t& year
, int32_t& month
,
191 int32_t& dom
, int32_t& dow
);
194 * Converts Julian day to time as milliseconds.
195 * @param julian the given Julian day number.
196 * @return time as milliseconds.
199 static inline double julianDayToMillis(int32_t julian
);
202 * Converts time as milliseconds to Julian day.
203 * @param millis the given milliseconds.
204 * @return the Julian day number.
207 static inline int32_t millisToJulianDay(double millis
);
210 * Calculates the Gregorian day shift value for an extended year.
211 * @param eyear Extended year
212 * @returns number of days to ADD to Julian in order to convert from J->G
214 static inline int32_t gregorianShift(int32_t eyear
);
217 static const int16_t DAYS_BEFORE
[24];
218 static const int8_t MONTH_LENGTH
[24];
221 inline double Math::floorDivide(double numerator
, double denominator
) {
222 return uprv_floor(numerator
/ denominator
);
225 inline UBool
Grego::isLeapYear(int32_t year
) {
226 // year&0x3 == year%4
227 return ((year
&0x3) == 0) && ((year%100
!= 0) || (year%400
== 0));
231 Grego::monthLength(int32_t year
, int32_t month
) {
232 return MONTH_LENGTH
[month
+ isLeapYear(year
)?12:0];
236 Grego::previousMonthLength(int y
, int m
) {
237 return (m
> 0) ? monthLength(y
, m
-1) : 31;
240 inline void Grego::dayToFields(double day
, int32_t& year
, int32_t& month
,
241 int32_t& dom
, int32_t& dow
) {
243 dayToFields(day
,year
,month
,dom
,dow
,doy_unused
);
246 inline double Grego::julianDayToMillis(int32_t julian
)
248 return (julian
- kEpochStartAsJulianDay
) * kOneDay
;
251 inline int32_t Grego::millisToJulianDay(double millis
) {
252 return (int32_t) (kEpochStartAsJulianDay
+ Math::floorDivide(millis
, (double)kOneDay
));
255 inline int32_t Grego::gregorianShift(int32_t eyear
) {
257 int32_t gregShift
= Math::floorDivide(y
, 400) - Math::floorDivide(y
, 100) + 2;
262 * This class provides convenient access to the data needed for a calendar.
265 class U_I18N_API CalendarData
: public UObject
{
268 * Construct a CalendarData from the given locale.
269 * @param loc locale to use. The 'calendar' keyword will be ignored.
270 * @param type calendar type. NULL indicates the gregorian calendar.
271 * No default lookup is done.
272 * @param status error code
274 CalendarData(const Locale
& loc
, const char *type
, UErrorCode
& status
);
277 * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
278 * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
280 * @param key Resource key to data
281 * @param status Error Status
284 UResourceBundle
* getByKey(const char *key
, UErrorCode
& status
);
287 * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
288 * There is an implicit key of 'format'
289 * data is located in: "calendar/key/format/subKey"
290 * for example, calendar/dayNames/format/abbreviated
291 * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
293 * @param key Resource key to data
294 * @param subKey Resource key to data
295 * @param status Error Status
298 UResourceBundle
* getByKey2(const char *key
, const char *subKey
, UErrorCode
& status
);
303 * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
304 * override. This method is to implement a simple version of RTTI, since not all C++
305 * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
308 * @return The class ID for this object. All objects of a given class have the
309 * same class ID. Objects of other classes have different class IDs.
312 virtual UClassID
getDynamicClassID(void) const;
315 * Return the class ID for this class. This is useful only for comparing to a return
316 * value from getDynamicClassID(). For example:
318 * Base* polymorphic_pointer = createPolymorphicObject();
319 * if (polymorphic_pointer->getDynamicClassID() ==
320 * Derived::getStaticClassID()) ...
322 * @return The class ID for all objects of this class.
325 static UClassID U_EXPORT2
getStaticClassID(void);
328 void initData(const char *locale
, const char *type
, UErrorCode
& status
);
330 UResourceBundle
*fFillin
;
331 UResourceBundle
*fOtherFillin
;
332 UResourceBundle
*fBundle
;
333 UResourceBundle
*fFallback
;
334 CalendarData(); // Not implemented.
339 #endif // !UCONFIG_NO_FORMATTING