1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5 *******************************************************************************
6 * Copyright (C) 2005-2011, International Business Machines Corporation and    *
7 * others. All Rights Reserved.                                                *
8 *******************************************************************************
9 */
10package android.icu.util;
11
12import java.util.Date;
13import java.util.Locale;
14
15import android.icu.util.ULocale.Category;
16
17/**
18 * Base class for EthiopicCalendar and CopticCalendar.
19 */
20abstract class CECalendar extends Calendar {
21    // jdk1.4.2 serialver
22    private static final long serialVersionUID = -999547623066414271L;
23
24    private static final int LIMITS[][] = {
25        // Minimum  Greatest    Least  Maximum
26        //           Minimum  Maximum
27        {        0,        0,       1,       1 }, // ERA
28        {        1,        1, 5000000, 5000000 }, // YEAR
29        {        0,        0,      12,      12 }, // MONTH
30        {        1,        1,      52,      53 }, // WEEK_OF_YEAR
31        {/*                                  */}, // WEEK_OF_MONTH
32        {        1,        1,       5,      30 }, // DAY_OF_MONTH
33        {        1,        1,     365,     366 }, // DAY_OF_YEAR
34        {/*                                  */}, // DAY_OF_WEEK
35        {       -1,       -1,       1,       5 }, // DAY_OF_WEEK_IN_MONTH
36        {/*                                  */}, // AM_PM
37        {/*                                  */}, // HOUR
38        {/*                                  */}, // HOUR_OF_DAY
39        {/*                                  */}, // MINUTE
40        {/*                                  */}, // SECOND
41        {/*                                  */}, // MILLISECOND
42        {/*                                  */}, // ZONE_OFFSET
43        {/*                                  */}, // DST_OFFSET
44        { -5000000, -5000000, 5000000, 5000000 }, // YEAR_WOY
45        {/*                                  */}, // DOW_LOCAL
46        { -5000000, -5000000, 5000000, 5000000 }, // EXTENDED_YEAR
47        {/*                                  */}, // JULIAN_DAY
48        {/*                                  */}, // MILLISECONDS_IN_DAY
49    };
50
51    //-------------------------------------------------------------------------
52    // Constructors...
53    //-------------------------------------------------------------------------
54
55    /**
56     * Constructs a default <code>CECalendar</code> using the current time
57     * in the default time zone with the default <code>FORMAT</code> locale.
58     */
59    protected CECalendar() {
60        this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
61    }
62
63    /**
64     * Constructs a <code>CECalendar</code> based on the current time
65     * in the given time zone with the default <code>FORMAT</code> locale.
66     *
67     * @param zone The time zone for the new calendar.
68     */
69    protected CECalendar(TimeZone zone) {
70        this(zone, ULocale.getDefault(Category.FORMAT));
71    }
72
73    /**
74     * Constructs a <code>CECalendar</code> based on the current time
75     * in the default time zone with the given locale.
76     *
77     * @param aLocale The locale for the new calendar.
78     */
79    protected CECalendar(Locale aLocale) {
80        this(TimeZone.getDefault(), aLocale);
81    }
82
83    /**
84     * Constructs a <code>CECalendar</code> based on the current time
85     * in the default time zone with the given locale.
86     *
87     * @param locale The locale for the new calendar.
88     */
89    protected CECalendar(ULocale locale) {
90        this(TimeZone.getDefault(), locale);
91    }
92
93    /**
94     * Constructs a <code>CECalendar</code> based on the current time
95     * in the given time zone with the given locale.
96     *
97     * @param zone The time zone for the new calendar.
98     *
99     * @param aLocale The locale for the new calendar.
100     */
101    protected CECalendar(TimeZone zone, Locale aLocale) {
102        super(zone, aLocale);
103        setTimeInMillis(System.currentTimeMillis());
104    }
105
106    /**
107     * Constructs a <code>CECalendar</code> based on the current time
108     * in the given time zone with the given locale.
109     *
110     * @param zone The time zone for the new calendar.
111     *
112     * @param locale The locale for the new calendar.
113     */
114    protected CECalendar(TimeZone zone, ULocale locale) {
115        super(zone, locale);
116        setTimeInMillis(System.currentTimeMillis());
117    }
118
119    /**
120     * Constructs a <code>CECalendar</code> with the given date set
121     * in the default time zone with the default <code>FORMAT</code> locale.
122     *
123     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field.
124     *
125     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
126     *                  The value is 0-based. e.g., 0 for Tishri.
127     *
128     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
129     */
130    protected CECalendar(int year, int month, int date) {
131        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
132        this.set(year, month, date);
133    }
134
135    /**
136     * Constructs a <code>CECalendar</code> with the given date set
137     * in the default time zone with the default <code>FORMAT</code> locale.
138     *
139     * @param date      The date to which the new calendar is set.
140     */
141    protected CECalendar(Date date) {
142        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
143        this.setTime(date);
144    }
145
146    /**
147     * Constructs a <code>CECalendar</code> with the given date
148     * and time set for the default time zone with the default <code>FORMAT</code> locale.
149     *
150     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field.
151     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
152     *                  The value is 0-based. e.g., 0 for Tishri.
153     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
154     * @param hour      The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field.
155     * @param minute    The value used to set the calendar's {@link #MINUTE MINUTE} time field.
156     * @param second    The value used to set the calendar's {@link #SECOND SECOND} time field.
157     */
158    protected CECalendar(int year, int month, int date, int hour,
159                         int minute, int second)
160    {
161        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
162        this.set(year, month, date, hour, minute, second);
163    }
164
165    //-------------------------------------------------------------------------
166    // Calendar framework
167    //-------------------------------------------------------------------------
168
169    /**
170     * The Coptic and Ethiopic calendars differ only in their epochs.
171     * This method must be implemented by CECalendar subclasses to
172     * return the date offset from Julian.
173     * @hide unsupported on Android
174     */
175    abstract protected int getJDEpochOffset();
176
177    /**
178     * Return JD of start of given month/extended year
179     */
180    protected int handleComputeMonthStart(int eyear,
181                                          int emonth,
182                                          boolean useMonth) {
183        return ceToJD(eyear, emonth, 0, getJDEpochOffset());
184    }
185
186    /**
187     * Calculate the limit for a specified type of limit and field
188     */
189    protected int handleGetLimit(int field, int limitType) {
190        return LIMITS[field][limitType];
191    }
192
193    // (The following method is not called because all existing subclasses
194    // override it.
195    ///CLOVER:OFF
196    /**
197     * Return the number of days in the given month of the given extended
198     * year of this calendar system.  Subclasses should override this
199     * method if they can provide a more correct or more efficient
200     * implementation than the default implementation in Calendar.
201     */
202    protected int handleGetMonthLength(int extendedYear, int month)
203    {
204
205        // The Ethiopian and Coptic calendars have 13 months, 12 of 30 days each and
206        // an intercalary month at the end of the year of 5 or 6 days, depending whether
207        // the year is a leap year or not. The Leap Year follows the same rules as the
208        // Julian Calendar so that the extra month always has six days in the year before
209        // a Julian Leap Year.
210        if ((month + 1) % 13 != 0)
211        {
212            // not intercalary month
213            return 30;
214        }
215        else
216        {
217            // intercalary month 5 days + possible leap day
218            return ((extendedYear % 4) / 3) + 5;
219        }
220
221    }
222    ///CLOVER:ON
223
224    //-------------------------------------------------------------------------
225    // Calendar framework
226    //-------------------------------------------------------------------------
227
228    /**
229     * Convert an Coptic/Ethiopic year, month and day to a Julian day
230     * @param year the extended year
231     * @param month the month
232     * @param day the day
233     * @return Julian day
234     * @hide unsupported on Android
235     */
236    public static int ceToJD(long year, int month, int day, int jdEpochOffset) {
237
238        // Julian<->Ethiopic algorithms from:
239        // "Calendars in Ethiopia", Berhanu Beyene, Manfred Kudlek, International Conference
240        // of Ethiopian Studies XV, Hamburg, 2003
241
242        // handle month > 12, < 0 (e.g. from add/set)
243        if ( month >= 0 ) {
244            year += month/13;
245            month %= 13;
246        } else {
247            ++month;
248            year += month/13 - 1;
249            month = month%13 + 12;
250        }
251        return (int) (
252            jdEpochOffset           // difference from Julian epoch to 1,1,1
253            + 365 * year            // number of days from years
254            + floorDivide(year, 4)  // extra day of leap year
255            + 30 * month            // number of days from months (months are 0-based)
256            + day - 1               // number of days for present month (1 based)
257            );
258    }
259
260    /**
261     * Convert a Julian day to an Coptic/Ethiopic year, month and day
262     * @hide unsupported on Android
263     */
264    public static void jdToCE(int julianDay, int jdEpochOffset, int[] fields) {
265        int c4; // number of 4 year cycle (1461 days)
266        int[] r4 = new int[1]; // remainder of 4 year cycle, always positive
267
268        c4 = floorDivide(julianDay - jdEpochOffset, 1461, r4);
269
270        // exteded year
271        fields[0] = 4 * c4 + (r4[0]/365 - r4[0]/1460); // 4 * <number of 4year cycle> + <years within the last cycle>
272
273        int doy = (r4[0] == 1460) ? 365 : (r4[0] % 365); // days in present year
274
275        // month
276        fields[1] = doy / 30; // 30 -> Coptic/Ethiopic month length up to 12th month
277        // day
278        fields[2] = (doy % 30) + 1; // 1-based days in a month
279    }
280}
281