17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 1996-2011, International Business Machines Corporation and    *
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.                                                *
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util;
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale.Category;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>IndianCalendar</code> is a subclass of <code>GregorianCalendar</code>
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * that numbers years since the birth of the Buddha.  This is the civil calendar
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * which is accepted by government of India as Indian National Calendar.
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The two calendars most widely used in India today are the Vikrama calendar
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * followed in North India and the Shalivahana or Saka calendar which is followed
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in South India and Maharashtra.
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * A variant of the Shalivahana Calendar was reformed and standardized as the
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Indian National calendar in 1957.
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Some details of Indian National Calendar (to be implemented) :
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The Months
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Month          Length      Start date (Gregorian)
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * =================================================
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1 Chaitra      30/31          March 22*
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 2 Vaisakha     31             April 21
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 3 Jyaistha     31             May 22
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 4 Asadha       31             June 22
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 5 Sravana      31             July 23
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 6 Bhadra       31             August 23
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 7 Asvina       30             September 23
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 8 Kartika      30             October 23
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 9 Agrahayana   30             November 22
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 10 Pausa       30             December 22
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 11 Magha       30             January 21
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 12 Phalguna    30             February 20
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * In leap years, Chaitra has 31 days and starts on March 21 instead.
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The leap years of Gregorian calendar and Indian National Calendar are in synchornization.
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * So When its a leap year in Gregorian calendar then Chaitra has 31 days.
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The Years
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Years are counted in the Saka Era, which starts its year 0 in 78AD (by gregorian calendar).
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * So for eg. 9th June 2006 by Gregorian Calendar, is same as 19th of Jyaistha in 1928 of Saka
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * era by Indian National Calendar.
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The Indian Calendar has only one allowable era: <code>Saka Era</code>.  If the
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * calendar is not in lenient mode (see <code>setLenient</code>), dates before
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 1/1/1 Saka Era are rejected with an <code>IllegalArgumentException</code>.
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This class should not be subclassed.</p>
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * IndianCalendar usually should be instantiated using
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code>
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * with the tag <code>"@calendar=Indian"</code>.</p>
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see com.ibm.icu.util.Calendar
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see com.ibm.icu.util.GregorianCalendar
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 3.8
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class IndianCalendar extends Calendar {
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // jdk1.4.2 serialver
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final long serialVersionUID = 3617859668165014834L;
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Chaitra, the 1st month of the Indian year.
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int CHAITRA = 0;
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Vaisakha, the 2nd month of the Indian year.
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int VAISAKHA = 1;
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Jyaistha, the 3rd month of the Indian year.
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int JYAISTHA = 2;
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Asadha, the 4th month of the Indian year.
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ASADHA = 3;
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Sravana, the 5th month of the Indian year.
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int SRAVANA = 4 ;
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Bhadra, the 6th month of the Indian year.
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int BHADRA = 5 ;
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Asvina, the 7th month of the Indian year.
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ASVINA = 6 ;
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Kartika, the 8th month of the Indian year.
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int KARTIKA = 7 ;
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Agrahayana, the 9th month of the Indian year.
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int AGRAHAYANA = 8 ;
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Pausa, the 10th month of the Indian year.
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int PAUSA = 9 ;
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Magha, the 11th month of the Indian year.
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int MAGHA = 10;
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Phalguna, the 12th month of the Indian year.
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int PHALGUNA = 11;
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Constructors...
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for the Indian Era.  This is the only allowable <code>ERA</code>
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * value for the Indian calendar.
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see com.ibm.icu.util.Calendar#ERA
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int IE = 0;
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> using the current time
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the default <code>FORMAT</code> locale.
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar() {
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> based on the current time
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the given time zone with the default <code>FORMAT</code> locale.
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param zone the given time zone.
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(TimeZone zone) {
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this(zone, ULocale.getDefault(Category.FORMAT));
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> based on the current time
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the given locale.
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aLocale the given locale.
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(Locale aLocale) {
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(TimeZone.getDefault(), aLocale);
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> based on the current time
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the given locale.
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale the given ulocale.
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(ULocale locale) {
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this(TimeZone.getDefault(), locale);
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> based on the current time
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the given time zone with the given locale.
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param zone the given time zone.
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aLocale the given locale.
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(TimeZone zone, Locale aLocale) {
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(zone, aLocale);
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        setTimeInMillis(System.currentTimeMillis());
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> based on the current time
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the given time zone with the given locale.
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param zone the given time zone.
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale the given ulocale.
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(TimeZone zone, ULocale locale) {
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(zone, locale);
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        setTimeInMillis(System.currentTimeMillis());
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> with the given date set
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the default <code>FORMAT</code> locale.
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date      The date to which the new calendar is set.
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(Date date) {
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.setTime(date);
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>IndianCalendar</code> with the given date set
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the default <code>FORMAT</code> locale.
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field.
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  The value is 0-based. e.g., 0 for January.
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(int year, int month, int date) {
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.YEAR, year);
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.MONTH, month);
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.DATE, date);
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a IndianCalendar with the given date
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and time set for the default time zone with the default <code>FORMAT</code> locale.
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field.
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  The value is 0-based. e.g., 0 for January.
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param hour      The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field.
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param minute    The value used to set the calendar's {@link #MINUTE MINUTE} time field.
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param second    The value used to set the calendar's {@link #SECOND SECOND} time field.
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public IndianCalendar(int year, int month, int date, int hour,
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                             int minute, int second)
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.YEAR, year);
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.MONTH, month);
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.DATE, date);
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.HOUR_OF_DAY, hour);
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.MINUTE, minute);
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       this.set(Calendar.SECOND, second);
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // The only practical difference from a Gregorian calendar is that years
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // are numbered since the Saka Era.  A couple of overrides will
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // take care of that....
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Starts in 78 AD,
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int INDIAN_ERA_START = 78;
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // The Indian year starts 80 days later than the Gregorian year.
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int INDIAN_YEAR_START = 80;
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetExtendedYear() {
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int year;
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) {
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            year = internalGet(EXTENDED_YEAR, 1);
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Ignore the era, as there is only one
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            year = internalGet(YEAR, 1);
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return year;
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetYearLength(int extendedYear) {
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return super.handleGetYearLength(extendedYear);
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetMonthLength(int extendedYear, int month) {
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (month < 0 || month > 11) {
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int[] remainder = new int[1];
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            extendedYear += floorDivide(month, 12, remainder);
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            month = remainder[0];
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(isGregorianLeap(extendedYear + INDIAN_ERA_START) && month == 0) {
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return 31;
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(month >= 1 && month <=5) {
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return 31;
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return 30;
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected void handleComputeFields(int julianDay){
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        double jdAtStartOfGregYear;
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int leapMonth, IndianYear, yday, IndianMonth, IndianDayOfMonth, mday;
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] gregorianDay;          // Stores gregorian date corresponding to Julian day;
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gregorianDay = jdToGregorian(julianDay);                    // Gregorian date for Julian day
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IndianYear = gregorianDay[0] - INDIAN_ERA_START;            // Year in Saka era
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        jdAtStartOfGregYear = gregorianToJD(gregorianDay[0], 1, 1); // JD at start of Gregorian year
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        yday = (int)(julianDay - jdAtStartOfGregYear);              // Day number in Gregorian year (starting from 0)
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (yday < INDIAN_YEAR_START) {
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //  Day is at the end of the preceding Saka year
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IndianYear -= 1;
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            leapMonth = isGregorianLeap(gregorianDay[0] - 1) ? 31 : 30; // Days in leapMonth this year, previous Gregorian year
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            yday += leapMonth + (31 * 5) + (30 * 3) + 10;
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            leapMonth = isGregorianLeap(gregorianDay[0]) ? 31 : 30; // Days in leapMonth this year
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            yday -= INDIAN_YEAR_START;
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (yday < leapMonth) {
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IndianMonth = 0;
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IndianDayOfMonth = yday + 1;
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              mday = yday - leapMonth;
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              if (mday < (31 * 5)) {
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 IndianMonth = mday / 31 + 1;
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 IndianDayOfMonth = (mday % 31) + 1;
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              } else {
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 mday -= 31 * 5;
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 IndianMonth = mday / 30 + 6;
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 IndianDayOfMonth = (mday % 30) + 1;
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              }
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(ERA, 0);
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(EXTENDED_YEAR, IndianYear);
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(YEAR, IndianYear);
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(MONTH, IndianMonth);
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(DAY_OF_MONTH, IndianDayOfMonth );
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(DAY_OF_YEAR, yday + 1); // yday is 0-based
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int LIMITS[][] = {
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Minimum  Greatest     Least    Maximum
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //           Minimum   Maximum
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        0,        0,        0,        0}, // ERA
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { -5000000, -5000000,  5000000,  5000000}, // YEAR
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        0,        0,       11,       11}, // MONTH
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        1,        1,       52,       53}, // WEEK_OF_YEAR
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // WEEK_OF_MONTH
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        1,        1,       30,       31}, // DAY_OF_MONTH
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        1,        1,      365,      366}, // DAY_OF_YEAR
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // DAY_OF_WEEK
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {       -1,       -1,        5,        5}, // DAY_OF_WEEK_IN_MONTH
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // AM_PM
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // HOUR
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // HOUR_OF_DAY
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // MINUTE
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // SECOND
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // MILLISECOND
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // ZONE_OFFSET
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // DST_OFFSET
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { -5000000, -5000000,  5000000,  5000000}, // YEAR_WOY
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // DOW_LOCAL
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { -5000000, -5000000,  5000000,  5000000}, // EXTENDED_YEAR
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // JULIAN_DAY
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                   */}, // MILLISECONDS_IN_DAY
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetLimit(int field, int limitType) {
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return LIMITS[field][limitType];
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleComputeMonthStart(int year, int month, boolean useMonth) {
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       //month is 0 based; converting it to 1-based
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       int imonth;
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       // If the month is out of range, adjust it into range, and adjust the extended year accordingly
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       if (month < 0 || month > 11) {
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           year += month / 12;
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           month %= 12;
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       }
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       if(month == 12) {
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           imonth = 1;
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       } else {
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           imonth = month +1;
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       }
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       double jd = IndianToJD(year ,imonth, 1);
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return (int)jd;
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This routine converts an Indian date to the corresponding Julian date"
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year   The year in Saka Era according to Indian calendar.
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month  The month according to Indian calendar (between 1 to 12)
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date   The date in month
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static double IndianToJD(int year, int month, int date) {
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       int leapMonth, gyear, m;
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       double start, jd;
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       gyear = year + INDIAN_ERA_START;
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       if(isGregorianLeap(gyear)) {
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          leapMonth = 31;
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          start = gregorianToJD(gyear, 3, 21);
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       } else {
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          leapMonth = 30;
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          start = gregorianToJD(gyear, 3, 22);
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       }
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       if (month == 1) {
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          jd = start + (date - 1);
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       } else {
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          jd = start + leapMonth;
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          m = month - 2;
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          m = Math.min(m, 5);
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          jd += m * 31;
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          if (month >= 8) {
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             m = month - 7;
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             jd += m * 30;
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          }
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          jd += date - 1;
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       }
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return jd;
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The following function is not needed for basic calendar functioning.
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This routine converts a gregorian date to the corresponding Julian date"
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year   The year in standard Gregorian calendar (AD/BC) .
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month  The month according to Gregorian calendar (between 0 to 11)
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date   The date in month
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static double gregorianToJD(int year, int month, int date) {
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       double JULIAN_EPOCH = 1721425.5;
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       int y = year - 1;
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       int result = (365 * y)
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (y / 4)
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  - (y / 100)
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (y / 400)
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (((367 * month) - 362) / 12)
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + ((month <= 2) ? 0 : (isGregorianLeap(year) ? -1 : -2))
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + date;
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return result - 1 + JULIAN_EPOCH;
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The following function is not needed for basic calendar functioning.
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This routine converts a julian day (jd) to the corresponding date in Gregorian calendar"
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param jd The Julian date in Julian Calendar which is to be converted to Indian date"
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static int[] jdToGregorian(double jd) {
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       double JULIAN_EPOCH = 1721425.5;
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       double wjd, depoch, quadricent, dqc, cent, dcent, quad, dquad, yindex, yearday, leapadj;
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       int year, month, day;
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       wjd = Math.floor(jd - 0.5) + 0.5;
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       depoch = wjd - JULIAN_EPOCH;
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       quadricent = Math.floor(depoch / 146097);
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       dqc = depoch % 146097;
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       cent = Math.floor(dqc / 36524);
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       dcent = dqc % 36524;
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       quad = Math.floor(dcent / 1461);
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       dquad = dcent % 1461;
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       yindex = Math.floor(dquad / 365);
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       year = (int)((quadricent * 400) + (cent * 100) + (quad * 4) + yindex);
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       if (!((cent == 4) || (yindex == 4))) {
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          year++;
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       }
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       yearday = wjd - gregorianToJD(year, 1, 1);
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       leapadj = ((wjd < gregorianToJD(year, 3, 1)) ? 0
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             :
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             (isGregorianLeap(year) ? 1 : 2)
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             );
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       month = (int)Math.floor((((yearday + leapadj) * 12) + 373) / 367);
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       day = (int)(wjd - gregorianToJD(year, month, 1)) + 1;
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       int[] julianDate = new int[3];
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       julianDate[0] = year;
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       julianDate[1] = month;
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       julianDate[2] = day;
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return julianDate;
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The following function is not needed for basic calendar functioning.
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This routine checks if the Gregorian year is a leap year"
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year      The year in Gregorian Calendar
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static boolean isGregorianLeap(int year)
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert       return ((year % 4) == 0) &&
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          (!(((year % 100) == 0) && ((year % 400) != 0)));
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public String getType() {
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return "indian";
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
585