Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Copyright 2001-2013 Stephen Colebourne
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 package org.joda.time.chrono;
 
 import java.util.Map;
 
Implements the Islamic, or Hijri, calendar system using arithmetic rules.

This calendar is a lunar calendar with a shorter year than ISO. Year 1 in the Islamic calendar began on July 16, 622 CE (Julian), thus Islamic years do not begin at the same time as Julian years. This chronology is not proleptic, as it does not allow dates before the first Islamic year.

There are two basic forms of the Islamic calendar, the tabular and the observed. The observed form cannot easily be used by computers as it relies on human observation of the new moon. The tabular calendar, implemented here, is an arithmetical approximation of the observed form that follows relatively simple rules.

The tabular form of the calendar defines 12 months of alternately 30 and 29 days. The last month is extended to 30 days in a leap year. Leap years occur according to a 30 year cycle. There are four recognised patterns of leap years in the 30 year cycle:

 Years 2, 5, 7, 10, 13, 15, 18, 21, 24, 26 & 29 - 15-based, used by Microsoft
 Years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 - 16-based, most commonly used
 Years 2, 5, 8, 10, 13, 16, 19, 21, 24, 27 & 29 - Indian
 Years 2, 5, 8, 11, 13, 16, 19, 21, 24, 27 & 30 - Habash al-Hasib
 
You can select which pattern to use via the factory methods, or use the default (16-based).

This implementation defines a day as midnight to midnight exactly as per the ISO chronology. This correct start of day is at sunset on the previous day, however this cannot readily be modelled and has been ignored.

IslamicChronology is thread-safe and immutable.

Author(s):
Stephen Colebourne
Since:
1.2
See also:
Wikipedia
 
 public final class IslamicChronology extends BasicChronology {

    
Serialization lock
 
     private static final long serialVersionUID = -3663823829888L;

    
Constant value for 'Anno Hegirae', equivalent to the value returned for AD/CE.
 
     public static final int AH = .;

    
A singleton era field.
 
     private static final DateTimeField ERA_FIELD = new BasicSingleEraDateTimeField("AH");

    
Leap year 15-based pattern.
 
     public static final LeapYearPatternType LEAP_YEAR_15_BASED = new LeapYearPatternType(0, 623158436);
    
Leap year 16-based pattern.
 
     public static final LeapYearPatternType LEAP_YEAR_16_BASED = new LeapYearPatternType(1, 623191204);
    
Leap year Indian pattern.
 
     public static final LeapYearPatternType LEAP_YEAR_INDIAN = new LeapYearPatternType(2, 690562340);
    
Leap year Habash al-Hasib pattern.
 
     public static final LeapYearPatternType LEAP_YEAR_HABASH_AL_HASIB = new LeapYearPatternType(3, 153692453);

    
The lowest year that can be fully supported.
 
     private static final int MIN_YEAR = -292269337;

    
The highest year that can be fully supported. Although calculateFirstDayOfYearMillis can go higher without overflowing, the getYear method overflows when it adds the approximate millis at the epoch.
 
     private static final int MAX_YEAR = 292271022;

    
The days in a pair of months.
    private static final int MONTH_PAIR_LENGTH = 59;

    
The length of the long month.
    private static final int LONG_MONTH_LENGTH = 30;

    
The length of the short month.
    private static final int SHORT_MONTH_LENGTH = 29;

    
The length of the long month in millis.
    private static final long MILLIS_PER_MONTH_PAIR = 59L * .;

    
The length of the long month in millis.
    private static final long MILLIS_PER_MONTH = (long) (29.53056 * .);

    
The length of the long month in millis.
    private static final long MILLIS_PER_LONG_MONTH = 30L * .;

    
The typical millis per year.
    private static final long MILLIS_PER_YEAR = (long) (354.36667 * .);

    
The typical millis per year.
    private static final long MILLIS_PER_SHORT_YEAR = 354L * .;

    
The typical millis per year.
    private static final long MILLIS_PER_LONG_YEAR = 355L * .;

    
The millis of 0001-01-01.
    private static final long MILLIS_YEAR_1 = -42521587200000L;
                                    //        -42520809600000L;
//    long start = 0L - 278L * DateTimeConstants.MILLIS_PER_DAY;
//    long cy = 46L * MILLIS_PER_CYCLE;  // 1381-01-01
//    long rem = 5L * MILLIS_PER_SHORT_YEAR +
//            3L * MILLIS_PER_LONG_YEAR;  // 1389-01-01

    
The length of the cycle of leap years.
    private static final int CYCLE = 30;

    
The millis of a 30 year cycle.
    private static final long MILLIS_PER_CYCLE = ((19L * 354L + 11L * 355L) * .);

    
Cache of zone to chronology arrays
    private static final Map<DateTimeZoneIslamicChronology[]> cCache = new HashMap<DateTimeZoneIslamicChronology[]>();

    
Singleton instance of a UTC IslamicChronology
    private static final IslamicChronology INSTANCE_UTC;
    static {
        // init after static fields
    }

    
The leap years to use.
    private final LeapYearPatternType iLeapYears;
    //-----------------------------------------------------------------------
    
Gets an instance of the IslamicChronology. The time zone of the returned instance is UTC.

Returns:
a singleton UTC instance of the chronology
    public static IslamicChronology getInstanceUTC() {
        return ;
    }

    
Gets an instance of the IslamicChronology in the default time zone.

Returns:
a chronology in the default time zone
    public static IslamicChronology getInstance() {
        return getInstance(DateTimeZone.getDefault(), );
    }

    
Gets an instance of the IslamicChronology in the given time zone.

Parameters:
zone the time zone to get the chronology in, null is default
Returns:
a chronology in the specified time zone
    public static IslamicChronology getInstance(DateTimeZone zone) {
        return getInstance(zone);
    }

    
Gets an instance of the IslamicChronology in the given time zone.

Parameters:
zone the time zone to get the chronology in, null is default
leapYears the type defining the leap year pattern
Returns:
a chronology in the specified time zone
    public static IslamicChronology getInstance(DateTimeZone zoneLeapYearPatternType leapYears) {
        if (zone == null) {
            zone = DateTimeZone.getDefault();
        }
        IslamicChronology chrono;
        synchronized () {
            IslamicChronology[] chronos = .get(zone);
            if (chronos == null) {
                chronos = new IslamicChronology[4];
                .put(zonechronos);
            }
            chrono = chronos[leapYears.index];
            if (chrono == null) {
                if (zone == .) {
                    // First create without a lower limit.
                    chrono = new IslamicChronology(nullnullleapYears);
                    // Impose lower limit and make another IslamicChronology.
                    DateTime lowerLimit = new DateTime(1, 1, 1, 0, 0, 0, 0, chrono);
                    chrono = new IslamicChronology(
                        LimitChronology.getInstance(chronolowerLimitnull),
                         nullleapYears);
                } else {
                    chrono = getInstance(.leapYears);
                    chrono = new IslamicChronology
                        (ZonedChronology.getInstance(chronozone), nullleapYears);
                }
                chronos[leapYears.index] = chrono;
            }
        }
        return chrono;
    }
    // Constructors and instance variables
    //-----------------------------------------------------------------------
    
Restricted constructor.
    IslamicChronology(Chronology baseObject paramLeapYearPatternType leapYears) {
        super(baseparam, 4);
        this. = leapYears;
    }

    
Serialization singleton.
    private Object readResolve() {
        Chronology base = getBase();
        return base == null ? getInstanceUTC() : getInstance(base.getZone());
    }
    //-----------------------------------------------------------------------
    
Gets the leap year pattern type.

Returns:
the pattern type
        return ;
    }
    // Conversion
    //-----------------------------------------------------------------------
    
Gets the Chronology in the UTC time zone.

Returns:
the chronology in UTC
    public Chronology withUTC() {
        return ;
    }

    
Gets the Chronology in a specific time zone.

Parameters:
zone the zone to get the chronology in, null is default
Returns:
the chronology
    public Chronology withZone(DateTimeZone zone) {
        if (zone == null) {
            zone = DateTimeZone.getDefault();
        }
        if (zone == getZone()) {
            return this;
        }
        return getInstance(zone);
    }
    //-----------------------------------------------------------------------
    
Checks if this chronology instance equals another.

Parameters:
obj the object to compare to
Returns:
true if equal
Since:
2.3
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof IslamicChronology) {
            IslamicChronology chrono = (IslamicChronologyobj;
            return getLeapYearPatternType(). == chrono.getLeapYearPatternType(). &&
                    super.equals(obj);
        }
        return false;
    }

    
A suitable hash code for the chronology.

Returns:
the hash code
Since:
1.6
    public int hashCode() {
        return super.hashCode() * 13 + getLeapYearPatternType().hashCode();
    }
    //-----------------------------------------------------------------------
    int getYear(long instant) {
        long millisIslamic = instant - ;
        long cycles = millisIslamic / ;
        long cycleRemainder = millisIslamic % ;
        
        int year = (int) ((cycles * ) + 1L);
        long yearMillis = (isLeapYear(year) ?  : );
        while (cycleRemainder >= yearMillis) {
            cycleRemainder -= yearMillis;
            yearMillis = (isLeapYear(++year) ?  : );
        }
        return year;
    }
    long setYear(long instantint year) {
        // optimsed implementation of set, due to fixed months
        int thisYear = getYear(instant);
        int dayOfYear = getDayOfYear(instantthisYear);
        int millisOfDay = getMillisOfDay(instant);
        if (dayOfYear > 354) {
            // Current year is leap, and day is leap.
            if (!isLeapYear(year)) {
                // Moving to a non-leap year, leap day doesn't exist.
                dayOfYear--;
            }
        }
        instant = getYearMonthDayMillis(year, 1, dayOfYear);
        instant += millisOfDay;
        return instant;
    }
    //-----------------------------------------------------------------------
    long getYearDifference(long minuendInstantlong subtrahendInstant) {
        // optimsed implementation of getDifference, due to fixed months
        int minuendYear = getYear(minuendInstant);
        int subtrahendYear = getYear(subtrahendInstant);
        // Inlined remainder method to avoid duplicate calls to get.
        long minuendRem = minuendInstant - getYearMillis(minuendYear);
        long subtrahendRem = subtrahendInstant - getYearMillis(subtrahendYear);
        int difference = minuendYear - subtrahendYear;
        if (minuendRem < subtrahendRem) {
            difference--;
        }
        return difference;
    }
    //-----------------------------------------------------------------------
    long getTotalMillisByYearMonth(int yearint month) {
        if (--month % 2 == 1) {
            month /= 2;
            return month *  + ;
        } else {
            month /= 2;
            return month * ;
        }
    }
    //-----------------------------------------------------------------------
    int getDayOfMonth(long millis) {
        // optimised for simple months
        int doy = getDayOfYear(millis) - 1;
        if (doy == 354) {
            return 30;
        }
        return (doy % ) %  + 1;
    }
    //-----------------------------------------------------------------------
    boolean isLeapYear(int year) {
        return .isLeapYear(year);
    }
    //-----------------------------------------------------------------------
    int getDaysInYearMax() {
        return 355;
    }
    //-----------------------------------------------------------------------
    int getDaysInYear(int year) {
        return isLeapYear(year) ? 355 : 354;
    }
    //-----------------------------------------------------------------------
    int getDaysInYearMonth(int yearint month) {
        if (month == 12 && isLeapYear(year)) {
            return ;
        }
        return (--month % 2 == 0 ?  : );
    }
    //-----------------------------------------------------------------------
    int getDaysInMonthMax() {
        return ;
    }
    //-----------------------------------------------------------------------
    int getDaysInMonthMax(int month) {
        if (month == 12) {
            return ;
        }
        return (--month % 2 == 0 ?  : );
    }
    //-----------------------------------------------------------------------
    int getMonthOfYear(long millisint year) {
        int doyZeroBased = (int) ((millis - getYearMillis(year)) / .);
        if (doyZeroBased == 354) {
            return 12;
        }
        return ((doyZeroBased * 2) / ) + 1;
//        return (int) (doyZeroBased / 29.9f) + 1;
//        
//        int monthPairZeroBased = doyZeroBased / MONTH_PAIR_LENGTH;
//        int monthPairRemainder = doyZeroBased % MONTH_PAIR_LENGTH;
//        return (monthPairZeroBased * 2) + 1 + (monthPairRemainder >= LONG_MONTH_LENGTH ? 1 : 0);
    }
    //-----------------------------------------------------------------------
    long getAverageMillisPerYear() {
        return ;
    }
    //-----------------------------------------------------------------------
        return  / 2;
    }
    //-----------------------------------------------------------------------
    long getAverageMillisPerMonth() {
        return ;
    }
    //-----------------------------------------------------------------------
    long calculateFirstDayOfYearMillis(int year) {
        if (year > ) {
            throw new ArithmeticException("Year is too large: " + year + " > " + );
        }
        if (year < ) {
            throw new ArithmeticException("Year is too small: " + year + " < " + );
        }
        // Java epoch is 1970-01-01 Gregorian which is 0622-07-16 Islamic.
        // 0001-01-01 Islamic is -42520809600000L
        // would prefer to calculate against year zero, but leap year
        // can be in that year so it doesn't work
        year--;
        long cycle = year / ;
        long millis =  + cycle * ;
        int cycleRemainder = (year % ) + 1;
        
        for (int i = 1; i < cycleRemainderi++) {
            millis += (isLeapYear(i) ?  : );
        }
        
        return millis;
    }
    //-----------------------------------------------------------------------
    int getMinYear() {
        return 1; //MIN_YEAR;
    }
    //-----------------------------------------------------------------------
    int getMaxYear() {
        return ;
    }
    //-----------------------------------------------------------------------
        // Epoch 1970-01-01 ISO = 1389-10-22 Islamic
        return (-) / 2;
    }
    //-----------------------------------------------------------------------
    protected void assemble(Fields fields) {
        if (getBase() == null) {
            super.assemble(fields);
            fields.era = ;
            fields.monthOfYear = new BasicMonthOfYearDateTimeField(this, 12);
            fields.months = fields.monthOfYear.getDurationField();
        }
    }
    //-----------------------------------------------------------------------
    
Opaque object describing a leap year pattern for the Islamic Chronology.

Since:
1.2
    public static class LeapYearPatternType implements Serializable {
        
Serialization lock
        private static final long serialVersionUID = 26581275372698L;
//        /** Leap year raw data encoded into bits. */
//        private static final int[][] LEAP_YEARS = {
//            {2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29},  // 623158436
//            {2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29},  // 623191204
//            {2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29},  // 690562340
//            {0, 2, 5, 8, 11, 13, 16, 19, 21, 24, 27},   // 153692453
//        };
        
        
The index.
        final byte index;
        
The leap year pattern, a bit-based 1=true pattern.
        final int pattern;
        
        
Constructor. This constructor takes a bit pattern where bits 0-29 correspond to years 0-29 in the 30 year Islamic cycle of years. This allows a highly efficient lookup by bit-matching.

Parameters:
index the index
pattern the bit pattern
        LeapYearPatternType(int indexint pattern) {
            super();
            this. = (byteindex;
            this. = pattern;
        }
        
        
Is the year a leap year.

Parameters:
year the year to query
Returns:
true if leap
        boolean isLeapYear(int year) {
            int key = 1 << (year % 30);
            return (( & key) > 0);
        }
        
        
Ensure a singleton is returned if possible.

Returns:
the singleton instance
        private Object readResolve() {
            switch () {
                case 0:
                    return ;
                case 1:
                    return ;
                case 2:
                    return ;
                case 3:
                    return ;
                default:
                    return this;
            }
        }
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof LeapYearPatternType) {
                return  == ((LeapYearPatternTypeobj).;
            }
            return false;
        }
        @Override
        public int hashCode() {
            return ;
        }
    }
New to GrepCode? Check out our FAQ X