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) 1996-2014, International Business Machines Corporation and    *
7 * others. All Rights Reserved.                                                *
8 *******************************************************************************
9 */
10
11package android.icu.util;
12
13import java.util.Date;
14import java.util.Locale;
15
16import android.icu.util.ULocale.Category;
17
18/**
19 * <code>PersianCalendar</code> is a subclass of <code>Calendar</code> that
20 * that implements the Persian calendar.  It is used as the main civil
21 * calendar in Iran and Afghanistan, and by Iranians and Afghans worldwide.
22 * <p>
23 * The Persian calendar is solar, and is similar to the Gregorian calendar
24 * in various ways, except its leap year rule, which is determined
25 * astronomically.  The Persian year starts around the March equinox.
26 * <p>
27 * The modern Persian calendar (used in Iran since 1925 CE and in
28 * Afghanistan since 1957 CE), has the lengths of the months fixed.  The
29 * first six months are 31 days each, the next five months are 30 days each,
30 * and the final month is 29 days in non-leap years and 30 days in leap
31 * ones.  Historically, the lengths of the month differed in different
32 * years, but they were finally fixed at the times mentioned above.  Partial
33 * information is available about the historical lengths.
34 * <p>
35 * The official rule for determination of the beginning of the Persian year
36 * is locale dependent, but at the same time, it has not specified a locale.
37 * Iranians around the world traditionally follow the calendar authorities
38 * of Iran, which haven't officially specified the locale.  Some
39 * calendarists use some point in Tehran as the locale, while others have
40 * tried the more neutral 52.5 degrees east meridian.  It is not clear which
41 * locale should be used for the Persian calendar of Afghanistan, but it is
42 * expected that for about one year in every twenty-four years, the Afghan
43 * calendar may become different from the Iranian one.
44 * <p>
45 * The exact locale to be used for the Iranian calendar starts to make a
46 * difference at around 2090 CE.  The specific arithmetic method implemented
47 * here, commonly known as the 33-year cycle rule, matches the astronomical
48 * calendar at least for the whole period that the calendar has been both
49 * well-defined and official, from 1925 to around 2090 CE.  The other
50 * commonly known algorithm, the 2820-year cycle, has been incorrectly
51 * designed to follow the tropical year instead of the spring equinoctial
52 * year, and fails to match the astronomical one as early as 2025 CE.
53 * <p>
54 * This class should not be subclassed.</p>
55 * <p>
56 * PersianCalendar usually should be instantiated using
57 * {@link android.icu.util.Calendar#getInstance(ULocale)} passing in a
58 * <code>ULocale</code> with the tag <code>"@calendar=persian"</code>.</p>
59 *
60 * @see android.icu.util.GregorianCalendar
61 * @see android.icu.util.Calendar
62 *
63 * @author Roozbeh Pournader
64 *
65 * @deprecated This API is ICU internal only.
66 * @hide Only a subset of ICU is exposed in Android
67 * @hide draft / provisional / internal are hidden on Android
68 */
69@Deprecated
70public class PersianCalendar extends Calendar {
71    private static final long serialVersionUID = -6727306982975111643L;
72
73    //-------------------------------------------------------------------------
74    // Constants...
75    //-------------------------------------------------------------------------
76
77    private static final int[][] MONTH_COUNT = {
78        //len len2   st
79        {  31,  31,   0 }, // Farvardin
80        {  31,  31,  31 }, // Ordibehesht
81        {  31,  31,  62 }, // Khordad
82        {  31,  31,  93 }, // Tir
83        {  31,  31, 124 }, // Mordad
84        {  31,  31, 155 }, // Shahrivar
85        {  30,  30, 186 }, // Mehr
86        {  30,  30, 216 }, // Aban
87        {  30,  30, 246 }, // Azar
88        {  30,  30, 276 }, // Dey
89        {  30,  30, 306 }, // Bahman
90        {  29,  30, 336 }  // Esfand
91        // len  length of month
92        // len2 length of month in a leap year
93        // st   days in year before start of month
94    };
95
96    private static final int PERSIAN_EPOCH = 1948320;
97
98    //-------------------------------------------------------------------------
99    // Constructors...
100    //-------------------------------------------------------------------------
101
102    /**
103     * Constructs a default <code>PersianCalendar</code> using the current time
104     * in the default time zone with the default <code>FORMAT</code> locale.
105     * @see Category#FORMAT
106     *
107     * @deprecated This API is ICU internal only.
108     * @hide draft / provisional / internal are hidden on Android
109     */
110    @Deprecated
111    public PersianCalendar()
112    {
113        this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
114    }
115
116    /**
117     * Constructs a <code>PersianCalendar</code> based on the current time
118     * in the given time zone with the default <code>FORMAT</code> locale.
119     * @param zone the given time zone.
120     * @see Category#FORMAT
121     *
122     * @deprecated This API is ICU internal only.
123     * @hide draft / provisional / internal are hidden on Android
124     */
125    @Deprecated
126    public PersianCalendar(TimeZone zone)
127    {
128        this(zone, ULocale.getDefault(Category.FORMAT));
129    }
130
131    /**
132     * Constructs a <code>PersianCalendar</code> based on the current time
133     * in the default time zone with the given locale.
134     *
135     * @param aLocale the given locale.
136     *
137     * @deprecated This API is ICU internal only.
138     * @hide draft / provisional / internal are hidden on Android
139     */
140    @Deprecated
141    public PersianCalendar(Locale aLocale)
142    {
143        this(TimeZone.getDefault(), aLocale);
144    }
145
146    /**
147     * Constructs a <code>PersianCalendar</code> based on the current time
148     * in the default time zone with the given locale.
149     *
150     * @param locale the given ulocale.
151     *
152     * @deprecated This API is ICU internal only.
153     * @hide draft / provisional / internal are hidden on Android
154     */
155    @Deprecated
156    public PersianCalendar(ULocale locale)
157    {
158        this(TimeZone.getDefault(), locale);
159    }
160
161    /**
162     * Constructs a <code>PersianCalendar</code> based on the current time
163     * in the given time zone with the given locale.
164     *
165     * @param zone the given time zone.
166     * @param aLocale the given locale.
167     *
168     * @deprecated This API is ICU internal only.
169     * @hide draft / provisional / internal are hidden on Android
170     */
171    @Deprecated
172    public PersianCalendar(TimeZone zone, Locale aLocale)
173    {
174        super(zone, aLocale);
175        setTimeInMillis(System.currentTimeMillis());
176    }
177
178    /**
179     * Constructs a <code>PersianCalendar</code> based on the current time
180     * in the given time zone with the given locale.
181     *
182     * @param zone the given time zone.
183     * @param locale the given ulocale.
184     *
185     * @deprecated This API is ICU internal only.
186     * @hide draft / provisional / internal are hidden on Android
187     */
188    @Deprecated
189    public PersianCalendar(TimeZone zone, ULocale locale)
190    {
191        super(zone, locale);
192        setTimeInMillis(System.currentTimeMillis());
193    }
194
195    /**
196     * Constructs a <code>PersianCalendar</code> with the given date set
197     * in the default time zone with the default <code>FORMAT</code> locale.
198     *
199     * @param date      The date to which the new calendar is set.
200     * @see Category#FORMAT
201     *
202     * @deprecated This API is ICU internal only.
203     * @hide draft / provisional / internal are hidden on Android
204     */
205    @Deprecated
206    public PersianCalendar(Date date) {
207        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
208        this.setTime(date);
209    }
210
211    /**
212     * Constructs a <code>PersianCalendar</code> with the given date set
213     * in the default time zone with the default <code>FORMAT</code> locale.
214     *
215     * @param year the value used to set the {@link #YEAR YEAR} time field in the calendar.
216     * @param month the value used to set the {@link #MONTH MONTH} time field in the calendar.
217     *              Note that the month value is 0-based. e.g., 0 for Farvardin.
218     * @param date the value used to set the {@link #DATE DATE} time field in the calendar.
219     * @see Category#FORMAT
220     *
221     * @deprecated This API is ICU internal only.
222     * @hide draft / provisional / internal are hidden on Android
223     */
224    @Deprecated
225    public PersianCalendar(int year, int month, int date)
226    {
227        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
228        this.set(Calendar.YEAR, year);
229        this.set(Calendar.MONTH, month);
230        this.set(Calendar.DATE, date);
231    }
232
233    /**
234     * Constructs a <code>PersianCalendar</code> with the given date
235     * and time set for the default time zone with the default <code>FORMAT</code> locale.
236     *
237     * @param year  the value used to set the {@link #YEAR YEAR} time field in the calendar.
238     * @param month the value used to set the {@link #MONTH MONTH} time field in the calendar.
239     *              Note that the month value is 0-based. e.g., 0 for Farvardin.
240     * @param date  the value used to set the {@link #DATE DATE} time field in the calendar.
241     * @param hour  the value used to set the {@link #HOUR_OF_DAY HOUR_OF_DAY} time field
242     *              in the calendar.
243     * @param minute the value used to set the {@link #MINUTE MINUTE} time field
244     *              in the calendar.
245     * @param second the value used to set the {@link #SECOND SECOND} time field
246     *              in the calendar.
247     * @see Category#FORMAT
248     *
249     * @deprecated This API is ICU internal only.
250     * @hide draft / provisional / internal are hidden on Android
251     */
252    @Deprecated
253    public PersianCalendar(int year, int month, int date, int hour,
254                           int minute, int second)
255    {
256        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
257        this.set(Calendar.YEAR, year);
258        this.set(Calendar.MONTH, month);
259        this.set(Calendar.DATE, date);
260        this.set(Calendar.HOUR_OF_DAY, hour);
261        this.set(Calendar.MINUTE, minute);
262        this.set(Calendar.SECOND, second);
263    }
264
265    //-------------------------------------------------------------------------
266    // Minimum / Maximum access functions
267    //-------------------------------------------------------------------------
268
269    private static final int LIMITS[][] = {
270        // Minimum  Greatest     Least   Maximum
271        //           Minimum   Maximum
272        {        0,        0,        0,        0}, // ERA
273        { -5000000, -5000000,  5000000,  5000000}, // YEAR
274        {        0,        0,       11,       11}, // MONTH
275        {        1,        1,       52,       53}, // WEEK_OF_YEAR
276        {/*                                   */}, // WEEK_OF_MONTH
277        {        1,        1,       29,       31}, // DAY_OF_MONTH
278        {        1,        1,      365,      366}, // DAY_OF_YEAR
279        {/*                                   */}, // DAY_OF_WEEK
280        {       -1,       -1,        5,        5}, // DAY_OF_WEEK_IN_MONTH
281        {/*                                   */}, // AM_PM
282        {/*                                   */}, // HOUR
283        {/*                                   */}, // HOUR_OF_DAY
284        {/*                                   */}, // MINUTE
285        {/*                                   */}, // SECOND
286        {/*                                   */}, // MILLISECOND
287        {/*                                   */}, // ZONE_OFFSET
288        {/*                                   */}, // DST_OFFSET
289        { -5000000, -5000000,  5000000,  5000000}, // YEAR_WOY
290        {/*                                   */}, // DOW_LOCAL
291        { -5000000, -5000000,  5000000,  5000000}, // EXTENDED_YEAR
292        {/*                                   */}, // JULIAN_DAY
293        {/*                                   */}, // MILLISECONDS_IN_DAY
294    };
295
296    /**
297     * @deprecated This API is ICU internal only.
298     * @hide draft / provisional / internal are hidden on Android
299     */
300    @Deprecated
301    protected int handleGetLimit(int field, int limitType) {
302        return LIMITS[field][limitType];
303    }
304
305    //-------------------------------------------------------------------------
306    // Assorted calculation utilities
307    //
308
309    /**
310     * Determine whether a year is a leap year in the Persian calendar
311     */
312    private final static boolean isLeapYear(int year)
313    {
314        int[] remainder = new int[1];
315        floorDivide(25 * year + 11, 33, remainder);
316        return remainder[0] < 8;
317
318    }
319
320    //----------------------------------------------------------------------
321    // Calendar framework
322    //----------------------------------------------------------------------
323
324    /**
325     * Return the length (in days) of the given month.
326     *
327     * @param extendedYear  The Persian year
328     * @param month The Persian month, 0-based
329     *
330     * @deprecated This API is ICU internal only.
331     * @hide draft / provisional / internal are hidden on Android
332     */
333    @Deprecated
334    protected int handleGetMonthLength(int extendedYear, int month) {
335        // If the month is out of range, adjust it into range, and
336        // modify the extended year value accordingly.
337        if (month < 0 || month > 11) {
338            int[] rem = new int[1];
339            extendedYear += floorDivide(month, 12, rem);
340            month = rem[0];
341        }
342
343        return MONTH_COUNT[month][isLeapYear(extendedYear)?1:0];
344    }
345
346    /**
347     * Return the number of days in the given Persian year
348     *
349     * @deprecated This API is ICU internal only.
350     * @hide draft / provisional / internal are hidden on Android
351     */
352    @Deprecated
353    protected int handleGetYearLength(int extendedYear) {
354        return isLeapYear(extendedYear) ? 366 : 365;
355    }
356
357    //-------------------------------------------------------------------------
358    // Functions for converting from field values to milliseconds....
359    //-------------------------------------------------------------------------
360
361    /**
362     * Return JD of start of given month/year
363     *
364     * @deprecated This API is ICU internal only.
365     * @hide draft / provisional / internal are hidden on Android
366     */
367    @Deprecated
368    protected int handleComputeMonthStart(int eyear, int month, boolean useMonth) {
369        // If the month is out of range, adjust it into range, and
370        // modify the extended year value accordingly.
371        if (month < 0 || month > 11) {
372            int[] rem = new int[1];
373            eyear += floorDivide(month, 12, rem);
374            month = rem[0];
375        }
376
377        int julianDay = PERSIAN_EPOCH - 1 + 365 * (eyear - 1) + floorDivide(8 * eyear + 21, 33);
378        if (month != 0) {
379            julianDay += MONTH_COUNT[month][2];
380        }
381        return julianDay;
382    }
383
384    //-------------------------------------------------------------------------
385    // Functions for converting from milliseconds to field values
386    //-------------------------------------------------------------------------
387
388    /**
389     * @deprecated This API is ICU internal only.
390     * @hide draft / provisional / internal are hidden on Android
391     */
392    @Deprecated
393    protected int handleGetExtendedYear() {
394        int year;
395        if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) {
396            year = internalGet(EXTENDED_YEAR, 1); // Default to year 1
397        } else {
398            year = internalGet(YEAR, 1); // Default to year 1
399        }
400        return year;
401    }
402
403    /**
404     * Override Calendar to compute several fields specific to the Persian
405     * calendar system.  These are:
406     *
407     * <ul><li>ERA
408     * <li>YEAR
409     * <li>MONTH
410     * <li>DAY_OF_MONTH
411     * <li>DAY_OF_YEAR
412     * <li>EXTENDED_YEAR</ul>
413     *
414     * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
415     * method is called.
416     *
417     * @deprecated This API is ICU internal only.
418     * @hide draft / provisional / internal are hidden on Android
419     */
420    @Deprecated
421    protected void handleComputeFields(int julianDay) {
422        int year, month, dayOfMonth, dayOfYear;
423
424        long daysSinceEpoch = julianDay - PERSIAN_EPOCH;
425        year = 1 + (int) floorDivide(33 * daysSinceEpoch + 3, 12053);
426
427        long farvardin1 = 365L * (year - 1L) + floorDivide(8L * year + 21, 33L);
428        dayOfYear = (int)(daysSinceEpoch - farvardin1); // 0-based
429        if (dayOfYear < 216) { // Compute 0-based month
430            month = dayOfYear / 31;
431        } else {
432            month = (dayOfYear - 6) / 30;
433        }
434        dayOfMonth = dayOfYear - MONTH_COUNT[month][2] + 1;
435        ++dayOfYear; // Make it 1-based now
436
437        internalSet(ERA, 0);
438        internalSet(YEAR, year);
439        internalSet(EXTENDED_YEAR, year);
440        internalSet(MONTH, month);
441        internalSet(DAY_OF_MONTH, dayOfMonth);
442        internalSet(DAY_OF_YEAR, dayOfYear);
443    }
444
445    /**
446     * {@inheritDoc}
447     *
448     * @deprecated This API is ICU internal only.
449     * @hide draft / provisional / internal are hidden on Android
450     */
451    @Deprecated
452    public String getType() {
453        return "persian";
454    }
455}
456