1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker /*
4*0e209d39SAndroid Build Coastguard Worker **********************************************************************
5*0e209d39SAndroid Build Coastguard Worker * Copyright (c) 2003-2008, International Business Machines
6*0e209d39SAndroid Build Coastguard Worker * Corporation and others. All Rights Reserved.
7*0e209d39SAndroid Build Coastguard Worker **********************************************************************
8*0e209d39SAndroid Build Coastguard Worker * Author: Alan Liu
9*0e209d39SAndroid Build Coastguard Worker * Created: September 2 2003
10*0e209d39SAndroid Build Coastguard Worker * Since: ICU 2.8
11*0e209d39SAndroid Build Coastguard Worker **********************************************************************
12*0e209d39SAndroid Build Coastguard Worker */
13*0e209d39SAndroid Build Coastguard Worker
14*0e209d39SAndroid Build Coastguard Worker #ifndef GREGOIMP_H
15*0e209d39SAndroid Build Coastguard Worker #define GREGOIMP_H
16*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h"
17*0e209d39SAndroid Build Coastguard Worker #include "unicode/calendar.h"
18*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_FORMATTING
19*0e209d39SAndroid Build Coastguard Worker
20*0e209d39SAndroid Build Coastguard Worker #include "unicode/ures.h"
21*0e209d39SAndroid Build Coastguard Worker #include "unicode/locid.h"
22*0e209d39SAndroid Build Coastguard Worker #include "putilimp.h"
23*0e209d39SAndroid Build Coastguard Worker
24*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN
25*0e209d39SAndroid Build Coastguard Worker
26*0e209d39SAndroid Build Coastguard Worker /**
27*0e209d39SAndroid Build Coastguard Worker * A utility class providing mathematical functions used by time zone
28*0e209d39SAndroid Build Coastguard Worker * and calendar code. Do not instantiate. Formerly just named 'Math'.
29*0e209d39SAndroid Build Coastguard Worker * @internal
30*0e209d39SAndroid Build Coastguard Worker */
31*0e209d39SAndroid Build Coastguard Worker class ClockMath {
32*0e209d39SAndroid Build Coastguard Worker public:
33*0e209d39SAndroid Build Coastguard Worker /**
34*0e209d39SAndroid Build Coastguard Worker * Divide two integers, returning the floor of the quotient.
35*0e209d39SAndroid Build Coastguard Worker * Unlike the built-in division, this is mathematically
36*0e209d39SAndroid Build Coastguard Worker * well-behaved. E.g., <code>-1/4</code> => 0 but
37*0e209d39SAndroid Build Coastguard Worker * <code>floorDivide(-1,4)</code> => -1.
38*0e209d39SAndroid Build Coastguard Worker * @param numerator the numerator
39*0e209d39SAndroid Build Coastguard Worker * @param denominator a divisor which must be != 0
40*0e209d39SAndroid Build Coastguard Worker * @return the floor of the quotient
41*0e209d39SAndroid Build Coastguard Worker */
42*0e209d39SAndroid Build Coastguard Worker static int32_t floorDivide(int32_t numerator, int32_t denominator);
43*0e209d39SAndroid Build Coastguard Worker
44*0e209d39SAndroid Build Coastguard Worker /**
45*0e209d39SAndroid Build Coastguard Worker * Divide two integers, returning the floor of the quotient.
46*0e209d39SAndroid Build Coastguard Worker * Unlike the built-in division, this is mathematically
47*0e209d39SAndroid Build Coastguard Worker * well-behaved. E.g., <code>-1/4</code> => 0 but
48*0e209d39SAndroid Build Coastguard Worker * <code>floorDivide(-1,4)</code> => -1.
49*0e209d39SAndroid Build Coastguard Worker * @param numerator the numerator
50*0e209d39SAndroid Build Coastguard Worker * @param denominator a divisor which must be != 0
51*0e209d39SAndroid Build Coastguard Worker * @return the floor of the quotient
52*0e209d39SAndroid Build Coastguard Worker */
53*0e209d39SAndroid Build Coastguard Worker static int64_t floorDivideInt64(int64_t numerator, int64_t denominator);
54*0e209d39SAndroid Build Coastguard Worker
55*0e209d39SAndroid Build Coastguard Worker /**
56*0e209d39SAndroid Build Coastguard Worker * Divide two numbers, returning the floor of the quotient.
57*0e209d39SAndroid Build Coastguard Worker * Unlike the built-in division, this is mathematically
58*0e209d39SAndroid Build Coastguard Worker * well-behaved. E.g., <code>-1/4</code> => 0 but
59*0e209d39SAndroid Build Coastguard Worker * <code>floorDivide(-1,4)</code> => -1.
60*0e209d39SAndroid Build Coastguard Worker * @param numerator the numerator
61*0e209d39SAndroid Build Coastguard Worker * @param denominator a divisor which must be != 0
62*0e209d39SAndroid Build Coastguard Worker * @return the floor of the quotient
63*0e209d39SAndroid Build Coastguard Worker */
64*0e209d39SAndroid Build Coastguard Worker static inline double floorDivide(double numerator, double denominator);
65*0e209d39SAndroid Build Coastguard Worker
66*0e209d39SAndroid Build Coastguard Worker /**
67*0e209d39SAndroid Build Coastguard Worker * Divide two numbers, returning the floor of the quotient and
68*0e209d39SAndroid Build Coastguard Worker * the modulus remainder. Unlike the built-in division, this is
69*0e209d39SAndroid Build Coastguard Worker * mathematically well-behaved. E.g., <code>-1/4</code> => 0 and
70*0e209d39SAndroid Build Coastguard Worker * <code>-1%4</code> => -1, but <code>floorDivide(-1,4)</code> =>
71*0e209d39SAndroid Build Coastguard Worker * -1 with <code>remainder</code> => 3. NOTE: If numerator is
72*0e209d39SAndroid Build Coastguard Worker * too large, the returned quotient may overflow.
73*0e209d39SAndroid Build Coastguard Worker * @param numerator the numerator
74*0e209d39SAndroid Build Coastguard Worker * @param denominator a divisor which must be != 0
75*0e209d39SAndroid Build Coastguard Worker * @param remainder output parameter to receive the
76*0e209d39SAndroid Build Coastguard Worker * remainder. Unlike <code>numerator % denominator</code>, this
77*0e209d39SAndroid Build Coastguard Worker * will always be non-negative, in the half-open range <code>[0,
78*0e209d39SAndroid Build Coastguard Worker * |denominator|)</code>.
79*0e209d39SAndroid Build Coastguard Worker * @return the floor of the quotient
80*0e209d39SAndroid Build Coastguard Worker */
81*0e209d39SAndroid Build Coastguard Worker static int32_t floorDivide(int32_t numerator, int32_t denominator,
82*0e209d39SAndroid Build Coastguard Worker int32_t* remainder);
83*0e209d39SAndroid Build Coastguard Worker
84*0e209d39SAndroid Build Coastguard Worker /**
85*0e209d39SAndroid Build Coastguard Worker * Divide two numbers, returning the floor of the quotient and
86*0e209d39SAndroid Build Coastguard Worker * the modulus remainder. Unlike the built-in division, this is
87*0e209d39SAndroid Build Coastguard Worker * mathematically well-behaved. E.g., <code>-1/4</code> => 0 and
88*0e209d39SAndroid Build Coastguard Worker * <code>-1%4</code> => -1, but <code>floorDivide(-1,4)</code> =>
89*0e209d39SAndroid Build Coastguard Worker * -1 with <code>remainder</code> => 3. NOTE: If numerator is
90*0e209d39SAndroid Build Coastguard Worker * too large, the returned quotient may overflow.
91*0e209d39SAndroid Build Coastguard Worker * @param numerator the numerator
92*0e209d39SAndroid Build Coastguard Worker * @param denominator a divisor which must be != 0
93*0e209d39SAndroid Build Coastguard Worker * @param remainder output parameter to receive the
94*0e209d39SAndroid Build Coastguard Worker * remainder. Unlike <code>numerator % denominator</code>, this
95*0e209d39SAndroid Build Coastguard Worker * will always be non-negative, in the half-open range <code>[0,
96*0e209d39SAndroid Build Coastguard Worker * |denominator|)</code>.
97*0e209d39SAndroid Build Coastguard Worker * @return the floor of the quotient
98*0e209d39SAndroid Build Coastguard Worker */
99*0e209d39SAndroid Build Coastguard Worker static double floorDivide(double numerator, int32_t denominator,
100*0e209d39SAndroid Build Coastguard Worker int32_t* remainder);
101*0e209d39SAndroid Build Coastguard Worker
102*0e209d39SAndroid Build Coastguard Worker /**
103*0e209d39SAndroid Build Coastguard Worker * For a positive divisor, return the quotient and remainder
104*0e209d39SAndroid Build Coastguard Worker * such that dividend = quotient*divisor + remainder and
105*0e209d39SAndroid Build Coastguard Worker * 0 <= remainder < divisor.
106*0e209d39SAndroid Build Coastguard Worker *
107*0e209d39SAndroid Build Coastguard Worker * Works around edge-case bugs. Handles pathological input
108*0e209d39SAndroid Build Coastguard Worker * (dividend >> divisor) reasonably.
109*0e209d39SAndroid Build Coastguard Worker *
110*0e209d39SAndroid Build Coastguard Worker * Calling with a divisor <= 0 is disallowed.
111*0e209d39SAndroid Build Coastguard Worker */
112*0e209d39SAndroid Build Coastguard Worker static double floorDivide(double dividend, double divisor,
113*0e209d39SAndroid Build Coastguard Worker double* remainder);
114*0e209d39SAndroid Build Coastguard Worker };
115*0e209d39SAndroid Build Coastguard Worker
116*0e209d39SAndroid Build Coastguard Worker // Useful millisecond constants
117*0e209d39SAndroid Build Coastguard Worker #define kOneDay (1.0 * U_MILLIS_PER_DAY) // 86,400,000
118*0e209d39SAndroid Build Coastguard Worker #define kOneHour (60*60*1000)
119*0e209d39SAndroid Build Coastguard Worker #define kOneMinute 60000
120*0e209d39SAndroid Build Coastguard Worker #define kOneSecond 1000
121*0e209d39SAndroid Build Coastguard Worker #define kOneMillisecond 1
122*0e209d39SAndroid Build Coastguard Worker #define kOneWeek (7.0 * kOneDay) // 604,800,000
123*0e209d39SAndroid Build Coastguard Worker
124*0e209d39SAndroid Build Coastguard Worker // Epoch constants
125*0e209d39SAndroid Build Coastguard Worker #define kJan1_1JulianDay 1721426 // January 1, year 1 (Gregorian)
126*0e209d39SAndroid Build Coastguard Worker
127*0e209d39SAndroid Build Coastguard Worker #define kEpochStartAsJulianDay 2440588 // January 1, 1970 (Gregorian)
128*0e209d39SAndroid Build Coastguard Worker
129*0e209d39SAndroid Build Coastguard Worker #define kEpochYear 1970
130*0e209d39SAndroid Build Coastguard Worker
131*0e209d39SAndroid Build Coastguard Worker
132*0e209d39SAndroid Build Coastguard Worker #define kEarliestViableMillis -185331720384000000.0 // minimum representable by julian day -1e17
133*0e209d39SAndroid Build Coastguard Worker
134*0e209d39SAndroid Build Coastguard Worker #define kLatestViableMillis 185753453990400000.0 // max representable by julian day +1e17
135*0e209d39SAndroid Build Coastguard Worker
136*0e209d39SAndroid Build Coastguard Worker /**
137*0e209d39SAndroid Build Coastguard Worker * The minimum supported Julian day. This value is equivalent to
138*0e209d39SAndroid Build Coastguard Worker * MIN_MILLIS.
139*0e209d39SAndroid Build Coastguard Worker */
140*0e209d39SAndroid Build Coastguard Worker #define MIN_JULIAN (-0x7F000000)
141*0e209d39SAndroid Build Coastguard Worker
142*0e209d39SAndroid Build Coastguard Worker /**
143*0e209d39SAndroid Build Coastguard Worker * The minimum supported epoch milliseconds. This value is equivalent
144*0e209d39SAndroid Build Coastguard Worker * to MIN_JULIAN.
145*0e209d39SAndroid Build Coastguard Worker */
146*0e209d39SAndroid Build Coastguard Worker #define MIN_MILLIS ((MIN_JULIAN - kEpochStartAsJulianDay) * kOneDay)
147*0e209d39SAndroid Build Coastguard Worker
148*0e209d39SAndroid Build Coastguard Worker /**
149*0e209d39SAndroid Build Coastguard Worker * The maximum supported Julian day. This value is equivalent to
150*0e209d39SAndroid Build Coastguard Worker * MAX_MILLIS.
151*0e209d39SAndroid Build Coastguard Worker */
152*0e209d39SAndroid Build Coastguard Worker #define MAX_JULIAN (+0x7F000000)
153*0e209d39SAndroid Build Coastguard Worker
154*0e209d39SAndroid Build Coastguard Worker /**
155*0e209d39SAndroid Build Coastguard Worker * The maximum supported epoch milliseconds. This value is equivalent
156*0e209d39SAndroid Build Coastguard Worker * to MAX_JULIAN.
157*0e209d39SAndroid Build Coastguard Worker */
158*0e209d39SAndroid Build Coastguard Worker #define MAX_MILLIS ((MAX_JULIAN - kEpochStartAsJulianDay) * kOneDay)
159*0e209d39SAndroid Build Coastguard Worker
160*0e209d39SAndroid Build Coastguard Worker /**
161*0e209d39SAndroid Build Coastguard Worker * A utility class providing proleptic Gregorian calendar functions
162*0e209d39SAndroid Build Coastguard Worker * used by time zone and calendar code. Do not instantiate.
163*0e209d39SAndroid Build Coastguard Worker *
164*0e209d39SAndroid Build Coastguard Worker * Note: Unlike GregorianCalendar, all computations performed by this
165*0e209d39SAndroid Build Coastguard Worker * class occur in the pure proleptic GregorianCalendar.
166*0e209d39SAndroid Build Coastguard Worker */
167*0e209d39SAndroid Build Coastguard Worker class Grego {
168*0e209d39SAndroid Build Coastguard Worker public:
169*0e209d39SAndroid Build Coastguard Worker /**
170*0e209d39SAndroid Build Coastguard Worker * Return true if the given year is a leap year.
171*0e209d39SAndroid Build Coastguard Worker * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
172*0e209d39SAndroid Build Coastguard Worker * @return true if the year is a leap year
173*0e209d39SAndroid Build Coastguard Worker */
174*0e209d39SAndroid Build Coastguard Worker static inline UBool isLeapYear(int32_t year);
175*0e209d39SAndroid Build Coastguard Worker
176*0e209d39SAndroid Build Coastguard Worker /**
177*0e209d39SAndroid Build Coastguard Worker * Return the number of days in the given month.
178*0e209d39SAndroid Build Coastguard Worker * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
179*0e209d39SAndroid Build Coastguard Worker * @param month 0-based month, with 0==Jan
180*0e209d39SAndroid Build Coastguard Worker * @return the number of days in the given month
181*0e209d39SAndroid Build Coastguard Worker */
182*0e209d39SAndroid Build Coastguard Worker static inline int8_t monthLength(int32_t year, int32_t month);
183*0e209d39SAndroid Build Coastguard Worker
184*0e209d39SAndroid Build Coastguard Worker /**
185*0e209d39SAndroid Build Coastguard Worker * Return the length of a previous month of the Gregorian calendar.
186*0e209d39SAndroid Build Coastguard Worker * @param y the extended year
187*0e209d39SAndroid Build Coastguard Worker * @param m the 0-based month number
188*0e209d39SAndroid Build Coastguard Worker * @return the number of days in the month previous to the given month
189*0e209d39SAndroid Build Coastguard Worker */
190*0e209d39SAndroid Build Coastguard Worker static inline int8_t previousMonthLength(int y, int m);
191*0e209d39SAndroid Build Coastguard Worker
192*0e209d39SAndroid Build Coastguard Worker /**
193*0e209d39SAndroid Build Coastguard Worker * Convert a year, month, and day-of-month, given in the proleptic
194*0e209d39SAndroid Build Coastguard Worker * Gregorian calendar, to 1970 epoch days.
195*0e209d39SAndroid Build Coastguard Worker * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
196*0e209d39SAndroid Build Coastguard Worker * @param month 0-based month, with 0==Jan
197*0e209d39SAndroid Build Coastguard Worker * @param dom 1-based day of month
198*0e209d39SAndroid Build Coastguard Worker * @return the day number, with day 0 == Jan 1 1970
199*0e209d39SAndroid Build Coastguard Worker */
200*0e209d39SAndroid Build Coastguard Worker static int64_t fieldsToDay(int32_t year, int32_t month, int32_t dom);
201*0e209d39SAndroid Build Coastguard Worker
202*0e209d39SAndroid Build Coastguard Worker /**
203*0e209d39SAndroid Build Coastguard Worker * Convert a 1970-epoch day number to proleptic Gregorian year,
204*0e209d39SAndroid Build Coastguard Worker * month, day-of-month, and day-of-week.
205*0e209d39SAndroid Build Coastguard Worker * @param day 1970-epoch day
206*0e209d39SAndroid Build Coastguard Worker * @param year output parameter to receive year
207*0e209d39SAndroid Build Coastguard Worker * @param month output parameter to receive month (0-based, 0==Jan)
208*0e209d39SAndroid Build Coastguard Worker * @param dom output parameter to receive day-of-month (1-based)
209*0e209d39SAndroid Build Coastguard Worker * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
210*0e209d39SAndroid Build Coastguard Worker * @param doy output parameter to receive day-of-year (1-based)
211*0e209d39SAndroid Build Coastguard Worker */
212*0e209d39SAndroid Build Coastguard Worker static void dayToFields(int32_t day, int32_t& year, int32_t& month,
213*0e209d39SAndroid Build Coastguard Worker int32_t& dom, int32_t& dow, int32_t& doy);
214*0e209d39SAndroid Build Coastguard Worker
215*0e209d39SAndroid Build Coastguard Worker /**
216*0e209d39SAndroid Build Coastguard Worker * Convert a 1970-epoch day number to proleptic Gregorian year,
217*0e209d39SAndroid Build Coastguard Worker * month, day-of-month, and day-of-week.
218*0e209d39SAndroid Build Coastguard Worker * @param day 1970-epoch day
219*0e209d39SAndroid Build Coastguard Worker * @param year output parameter to receive year
220*0e209d39SAndroid Build Coastguard Worker * @param month output parameter to receive month (0-based, 0==Jan)
221*0e209d39SAndroid Build Coastguard Worker * @param dom output parameter to receive day-of-month (1-based)
222*0e209d39SAndroid Build Coastguard Worker * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
223*0e209d39SAndroid Build Coastguard Worker */
224*0e209d39SAndroid Build Coastguard Worker static inline void dayToFields(int32_t day, int32_t& year, int32_t& month,
225*0e209d39SAndroid Build Coastguard Worker int32_t& dom, int32_t& dow);
226*0e209d39SAndroid Build Coastguard Worker
227*0e209d39SAndroid Build Coastguard Worker /**
228*0e209d39SAndroid Build Coastguard Worker * Convert a 1970-epoch milliseconds to proleptic Gregorian year,
229*0e209d39SAndroid Build Coastguard Worker * month, day-of-month, and day-of-week, day of year and millis-in-day.
230*0e209d39SAndroid Build Coastguard Worker * @param time 1970-epoch milliseconds
231*0e209d39SAndroid Build Coastguard Worker * @param year output parameter to receive year
232*0e209d39SAndroid Build Coastguard Worker * @param month output parameter to receive month (0-based, 0==Jan)
233*0e209d39SAndroid Build Coastguard Worker * @param dom output parameter to receive day-of-month (1-based)
234*0e209d39SAndroid Build Coastguard Worker * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
235*0e209d39SAndroid Build Coastguard Worker * @param doy output parameter to receive day-of-year (1-based)
236*0e209d39SAndroid Build Coastguard Worker * @param mid output parameter to receive millis-in-day
237*0e209d39SAndroid Build Coastguard Worker */
238*0e209d39SAndroid Build Coastguard Worker static void timeToFields(UDate time, int32_t& year, int32_t& month,
239*0e209d39SAndroid Build Coastguard Worker int32_t& dom, int32_t& dow, int32_t& doy, int32_t& mid);
240*0e209d39SAndroid Build Coastguard Worker
241*0e209d39SAndroid Build Coastguard Worker /**
242*0e209d39SAndroid Build Coastguard Worker * Return the day of week on the 1970-epoch day
243*0e209d39SAndroid Build Coastguard Worker * @param day the 1970-epoch day
244*0e209d39SAndroid Build Coastguard Worker * @return the day of week
245*0e209d39SAndroid Build Coastguard Worker */
246*0e209d39SAndroid Build Coastguard Worker static int32_t dayOfWeek(int32_t day);
247*0e209d39SAndroid Build Coastguard Worker
248*0e209d39SAndroid Build Coastguard Worker /**
249*0e209d39SAndroid Build Coastguard Worker * Returns the ordinal number for the specified day of week within the month.
250*0e209d39SAndroid Build Coastguard Worker * The valid return value is 1, 2, 3, 4 or -1.
251*0e209d39SAndroid Build Coastguard Worker * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
252*0e209d39SAndroid Build Coastguard Worker * @param month 0-based month, with 0==Jan
253*0e209d39SAndroid Build Coastguard Worker * @param dom 1-based day of month
254*0e209d39SAndroid Build Coastguard Worker * @return The ordinal number for the specified day of week within the month
255*0e209d39SAndroid Build Coastguard Worker */
256*0e209d39SAndroid Build Coastguard Worker static int32_t dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom);
257*0e209d39SAndroid Build Coastguard Worker
258*0e209d39SAndroid Build Coastguard Worker /**
259*0e209d39SAndroid Build Coastguard Worker * Converts Julian day to time as milliseconds.
260*0e209d39SAndroid Build Coastguard Worker * @param julian the given Julian day number.
261*0e209d39SAndroid Build Coastguard Worker * @return time as milliseconds.
262*0e209d39SAndroid Build Coastguard Worker * @internal
263*0e209d39SAndroid Build Coastguard Worker */
264*0e209d39SAndroid Build Coastguard Worker static inline double julianDayToMillis(int32_t julian);
265*0e209d39SAndroid Build Coastguard Worker
266*0e209d39SAndroid Build Coastguard Worker /**
267*0e209d39SAndroid Build Coastguard Worker * Converts time as milliseconds to Julian day.
268*0e209d39SAndroid Build Coastguard Worker * @param millis the given milliseconds.
269*0e209d39SAndroid Build Coastguard Worker * @return the Julian day number.
270*0e209d39SAndroid Build Coastguard Worker * @internal
271*0e209d39SAndroid Build Coastguard Worker */
272*0e209d39SAndroid Build Coastguard Worker static inline int32_t millisToJulianDay(double millis);
273*0e209d39SAndroid Build Coastguard Worker
274*0e209d39SAndroid Build Coastguard Worker /**
275*0e209d39SAndroid Build Coastguard Worker * Calculates the Gregorian day shift value for an extended year.
276*0e209d39SAndroid Build Coastguard Worker * @param eyear Extended year
277*0e209d39SAndroid Build Coastguard Worker * @returns number of days to ADD to Julian in order to convert from J->G
278*0e209d39SAndroid Build Coastguard Worker */
279*0e209d39SAndroid Build Coastguard Worker static inline int32_t gregorianShift(int32_t eyear);
280*0e209d39SAndroid Build Coastguard Worker
281*0e209d39SAndroid Build Coastguard Worker private:
282*0e209d39SAndroid Build Coastguard Worker static const int16_t DAYS_BEFORE[24];
283*0e209d39SAndroid Build Coastguard Worker static const int8_t MONTH_LENGTH[24];
284*0e209d39SAndroid Build Coastguard Worker };
285*0e209d39SAndroid Build Coastguard Worker
floorDivide(double numerator,double denominator)286*0e209d39SAndroid Build Coastguard Worker inline double ClockMath::floorDivide(double numerator, double denominator) {
287*0e209d39SAndroid Build Coastguard Worker return uprv_floor(numerator / denominator);
288*0e209d39SAndroid Build Coastguard Worker }
289*0e209d39SAndroid Build Coastguard Worker
isLeapYear(int32_t year)290*0e209d39SAndroid Build Coastguard Worker inline UBool Grego::isLeapYear(int32_t year) {
291*0e209d39SAndroid Build Coastguard Worker // year&0x3 == year%4
292*0e209d39SAndroid Build Coastguard Worker return ((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0));
293*0e209d39SAndroid Build Coastguard Worker }
294*0e209d39SAndroid Build Coastguard Worker
295*0e209d39SAndroid Build Coastguard Worker inline int8_t
monthLength(int32_t year,int32_t month)296*0e209d39SAndroid Build Coastguard Worker Grego::monthLength(int32_t year, int32_t month) {
297*0e209d39SAndroid Build Coastguard Worker return MONTH_LENGTH[month + (isLeapYear(year) ? 12 : 0)];
298*0e209d39SAndroid Build Coastguard Worker }
299*0e209d39SAndroid Build Coastguard Worker
300*0e209d39SAndroid Build Coastguard Worker inline int8_t
previousMonthLength(int y,int m)301*0e209d39SAndroid Build Coastguard Worker Grego::previousMonthLength(int y, int m) {
302*0e209d39SAndroid Build Coastguard Worker return (m > 0) ? monthLength(y, m-1) : 31;
303*0e209d39SAndroid Build Coastguard Worker }
304*0e209d39SAndroid Build Coastguard Worker
dayToFields(int32_t day,int32_t & year,int32_t & month,int32_t & dom,int32_t & dow)305*0e209d39SAndroid Build Coastguard Worker inline void Grego::dayToFields(int32_t day, int32_t& year, int32_t& month,
306*0e209d39SAndroid Build Coastguard Worker int32_t& dom, int32_t& dow) {
307*0e209d39SAndroid Build Coastguard Worker int32_t doy_unused;
308*0e209d39SAndroid Build Coastguard Worker dayToFields(day,year,month,dom,dow,doy_unused);
309*0e209d39SAndroid Build Coastguard Worker }
310*0e209d39SAndroid Build Coastguard Worker
julianDayToMillis(int32_t julian)311*0e209d39SAndroid Build Coastguard Worker inline double Grego::julianDayToMillis(int32_t julian)
312*0e209d39SAndroid Build Coastguard Worker {
313*0e209d39SAndroid Build Coastguard Worker return (static_cast<double>(julian) - kEpochStartAsJulianDay) * kOneDay;
314*0e209d39SAndroid Build Coastguard Worker }
315*0e209d39SAndroid Build Coastguard Worker
millisToJulianDay(double millis)316*0e209d39SAndroid Build Coastguard Worker inline int32_t Grego::millisToJulianDay(double millis) {
317*0e209d39SAndroid Build Coastguard Worker return (int32_t) (kEpochStartAsJulianDay + ClockMath::floorDivide(millis, (double)kOneDay));
318*0e209d39SAndroid Build Coastguard Worker }
319*0e209d39SAndroid Build Coastguard Worker
gregorianShift(int32_t eyear)320*0e209d39SAndroid Build Coastguard Worker inline int32_t Grego::gregorianShift(int32_t eyear) {
321*0e209d39SAndroid Build Coastguard Worker int64_t y = (int64_t)eyear-1;
322*0e209d39SAndroid Build Coastguard Worker int64_t gregShift = ClockMath::floorDivideInt64(y, 400LL) - ClockMath::floorDivideInt64(y, 100LL) + 2;
323*0e209d39SAndroid Build Coastguard Worker return static_cast<int32_t>(gregShift);
324*0e209d39SAndroid Build Coastguard Worker }
325*0e209d39SAndroid Build Coastguard Worker
326*0e209d39SAndroid Build Coastguard Worker #define IMPL_SYSTEM_DEFAULT_CENTURY(T, U) \
327*0e209d39SAndroid Build Coastguard Worker /** \
328*0e209d39SAndroid Build Coastguard Worker * The system maintains a static default century start date and Year. They \
329*0e209d39SAndroid Build Coastguard Worker * are initialized the first time they are used. Once the system default \
330*0e209d39SAndroid Build Coastguard Worker * century date and year are set, they do not change \
331*0e209d39SAndroid Build Coastguard Worker */ \
332*0e209d39SAndroid Build Coastguard Worker namespace { \
333*0e209d39SAndroid Build Coastguard Worker static UDate gSystemDefaultCenturyStart = DBL_MIN; \
334*0e209d39SAndroid Build Coastguard Worker static int32_t gSystemDefaultCenturyStartYear = -1; \
335*0e209d39SAndroid Build Coastguard Worker static icu::UInitOnce gSystemDefaultCenturyInit {}; \
336*0e209d39SAndroid Build Coastguard Worker static void U_CALLCONV \
337*0e209d39SAndroid Build Coastguard Worker initializeSystemDefaultCentury() { \
338*0e209d39SAndroid Build Coastguard Worker UErrorCode status = U_ZERO_ERROR; \
339*0e209d39SAndroid Build Coastguard Worker T calendar(U, status); \
340*0e209d39SAndroid Build Coastguard Worker /* initialize systemDefaultCentury and systemDefaultCenturyYear based */ \
341*0e209d39SAndroid Build Coastguard Worker /* on the current time. They'll be set to 80 years before */ \
342*0e209d39SAndroid Build Coastguard Worker /* the current time. */ \
343*0e209d39SAndroid Build Coastguard Worker if (U_FAILURE(status)) { \
344*0e209d39SAndroid Build Coastguard Worker return; \
345*0e209d39SAndroid Build Coastguard Worker } \
346*0e209d39SAndroid Build Coastguard Worker calendar.setTime(Calendar::getNow(), status); \
347*0e209d39SAndroid Build Coastguard Worker calendar.add(UCAL_YEAR, -80, status); \
348*0e209d39SAndroid Build Coastguard Worker gSystemDefaultCenturyStart = calendar.getTime(status); \
349*0e209d39SAndroid Build Coastguard Worker gSystemDefaultCenturyStartYear = calendar.get(UCAL_YEAR, status); \
350*0e209d39SAndroid Build Coastguard Worker /* We have no recourse upon failure unless we want to propagate the */ \
351*0e209d39SAndroid Build Coastguard Worker /* failure out. */ \
352*0e209d39SAndroid Build Coastguard Worker } \
353*0e209d39SAndroid Build Coastguard Worker } /* namespace */ \
354*0e209d39SAndroid Build Coastguard Worker UDate T::defaultCenturyStart() const { \
355*0e209d39SAndroid Build Coastguard Worker /* lazy-evaluate systemDefaultCenturyStart */ \
356*0e209d39SAndroid Build Coastguard Worker umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); \
357*0e209d39SAndroid Build Coastguard Worker return gSystemDefaultCenturyStart; \
358*0e209d39SAndroid Build Coastguard Worker } \
359*0e209d39SAndroid Build Coastguard Worker int32_t T::defaultCenturyStartYear() const { \
360*0e209d39SAndroid Build Coastguard Worker /* lazy-evaluate systemDefaultCenturyStart */ \
361*0e209d39SAndroid Build Coastguard Worker umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); \
362*0e209d39SAndroid Build Coastguard Worker return gSystemDefaultCenturyStartYear; \
363*0e209d39SAndroid Build Coastguard Worker } \
364*0e209d39SAndroid Build Coastguard Worker UBool T::haveDefaultCentury() const { return true; }
365*0e209d39SAndroid Build Coastguard Worker
366*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END
367*0e209d39SAndroid Build Coastguard Worker
368*0e209d39SAndroid Build Coastguard Worker #endif // !UCONFIG_NO_FORMATTING
369*0e209d39SAndroid Build Coastguard Worker #endif // GREGOIMP_H
370*0e209d39SAndroid Build Coastguard Worker
371*0e209d39SAndroid Build Coastguard Worker //eof
372