 /*
  *******************************************************************************
  * Copyright (C) 2005-2006, International Business Machines Corporation and         *
  * others. All Rights Reserved.                                                *
  *******************************************************************************
  */
package com.ibm.icu.impl;

import java.util.Date;

import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.SimpleTimeZone;
import com.ibm.icu.util.TimeZone;

/**
 * A time zone based on the Olson database.  Olson time zones change
 * behavior over time.  The raw offset, rules, presence or absence of
 * daylight savings time, and even the daylight savings amount can all
 * vary.
 *
 * This class uses a resource bundle named "zoneinfo".  Zoneinfo is a
 * table containing different kinds of resources.  In several places,
 * zones are referred to using integers.  A zone's integer is a number
 * from 0..n-1, where n is the number of zones, with the zones sorted
 * in lexicographic order.
 *
 * 1. Zones.  These have keys corresponding to the Olson IDs, e.g.,
 * "Asia/Shanghai".  Each resource describes the behavior of the given
 * zone.  Zones come in several formats, which are differentiated
 * based on length.
 *
 *  a. Alias (int, length 1).  An alias zone is an int resource.  The
 *  integer is the zone number of the target zone.  The key of this
 *  resource is an alternate name for the target zone.  Aliases
 *  represent Olson links and ICU compatibility IDs.
 *
 *  b. Simple zone (array, length 3).  The three subelements are:
 *
 *   i. An intvector of transitions.  These are given in epoch
 *   seconds.  This may be an empty invector (length 0).  If the
 *   transtions list is empty, then the zone's behavior is fixed and
 *   given by the offset list, which will contain exactly one pair.
 *   Otherwise each transtion indicates a time after which (inclusive)
 *   the associated offset pair is in effect.
 *
 *   ii. An intvector of offsets.  These are in pairs of raw offset /
 *   DST offset, in units of seconds.  There will be at least one pair
 *   (length >= 2 && length % 2 == 0).
 *
 *   iii. A binary resource.  This is of the same length as the
 *   transitions vector, so length may be zero.  Each unsigned byte
 *   corresponds to one transition, and has a value of 0..n-1, where n
 *   is the number of pairs in the offset vector.  This forms a map
 *   between transitions and offset pairs.
 *
 *  c. Simple zone with aliases (array, length 4).  This is like a
 *  simple zone, but also contains a fourth element:
 *
 *   iv. An intvector of aliases.  This list includes this zone
 *   itself, and lists all aliases of this zone.
 *
 *  d. Complex zone (array, length 5).  This is like a simple zone,
 *  but contains two more elements:
 *
 *   iv. A string, giving the name of a rule.  This is the "final
 *   rule", which governs the zone's behavior beginning in the "final
 *   year".  The rule ID is given without leading underscore, e.g.,
 *   "EU".
 *
 *   v. An intvector of length 2, containing the raw offset for the
 *   final rule (in seconds), and the final year.  The final rule
 *   takes effect for years >= the final year.
 *
 *  e. Complex zone with aliases (array, length 6).  This is like a
 *  complex zone, but also contains a sixth element:
 * 
 *   vi. An intvector of aliases.  This list includes this zone
 *   itself, and lists all aliases of this zone.
 *
 * 2. Rules.  These have keys corresponding to the Olson rule IDs,
 * with an underscore prepended, e.g., "_EU".  Each resource describes
 * the behavior of the given rule using an intvector, containing the
 * onset list, the cessation list, and the DST savings.  The onset and
 * cessation lists consist of the month, dowim, dow, time, and time
 * mode.  The end result is that the 11 integers describing the rule
 * can be passed directly into the SimpleTimeZone 13-argument
 * constructor (the other two arguments will be the raw offset, taken
 * from the complex zone element 5, and the ID string, which is not
 * used), with the times and the DST savings multiplied by 1000 to
 * scale from seconds to milliseconds.
 *
 * 3. Countries.  These have keys corresponding to the 2-letter ISO
 * country codes, with a percent sign prepended, e.g., "%US".  Each
 * resource is an intvector listing the zones associated with the
 * given country.  The special entry "%" corresponds to "no country",
 * that is, the category of zones assigned to no country in the Olson
 * DB.
 *
 * 4. Metadata.  Metadata is stored under the key "_".  It is an
 * intvector of length three containing the number of zones resources,
 * rule resources, and country resources.  For the purposes of this
 * count, the metadata entry itself is considered a rule resource,
 * since its key begins with an underscore.
 */
public class OlsonTimeZone extends TimeZone {

    // Generated by serialver from JDK 1.4.1_01
    static final long serialVersionUID = -6281977362477515376L;

    private static final boolean ASSERT = false;

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#getOffset(int, int, int, int, int, int)
     */
    public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {
        if (month < Calendar.JANUARY || month > Calendar.DECEMBER) {
            throw new IllegalArgumentException("Month is not in the legal range: " +month);
        } else {
            return getOffset(era, year, month, day, dayOfWeek, milliseconds,MONTH_LENGTH[month + (isLeapYear(year)?12:0)]);
        }
    }

    /**
     * TimeZone API.
     */
    public int getOffset(int era, int year, int month,int dom, int dow, int millis, int monthLength){

        if ((era != GregorianCalendar.AD && era != GregorianCalendar.BC)
            || month < Calendar.JANUARY
            || month > Calendar.DECEMBER
            || dom < 1
            || dom > monthLength
            || dow < Calendar.SUNDAY
            || dow > Calendar.SATURDAY
            || millis < 0
            || millis >= MILLIS_PER_DAY
            || monthLength < 28
            || monthLength > 31) {
            throw new IllegalArgumentException();
        }

        if (era == GregorianCalendar.BC) {
            year = -year;
        }

        if (year > finalYear) { // [sic] >, not >=; see above
            if (ASSERT) Assert.assrt("(finalZone != null)", finalZone != null);
            return finalZone.getOffset(era, year, month, dom, dow,
                                        millis, monthLength);
        }

        // Compute local epoch seconds from input fields
        double time = fieldsToDay(year, month, dom) * SECONDS_PER_DAY +
            Math.floor(millis / (double) MILLIS_PER_SECOND);

        int[] offsets = new int[2];
        getHistoricalOffset(time, true, offsets);
        return offsets[0] + offsets[1];
    }
    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#setRawOffset(int)
     */
    public void setRawOffset(int offsetMillis) {
        finalZone.setRawOffset(offsetMillis);
    }
    public Object clone() {
        OlsonTimeZone other = (OlsonTimeZone) super.clone();
        if(finalZone!=null){
            finalZone.setID(getID());
            other.finalZone = (SimpleTimeZone)finalZone.clone();
        }
        other.transitionTimes = (int[])transitionTimes.clone();
        other.typeData = (byte[])typeData.clone();
        other.typeOffsets = (int[])typeOffsets.clone();
        return other;
    }
    /**
     * TimeZone API.
     */
    public void getOffset(long date, boolean local, int[] offsets)  {
        int rawoff, dstoff;
        // The check against finalMillis will suffice most of the time, except
        // for the case in which finalMillis == DBL_MAX, date == DBL_MAX,
        // and finalZone == 0.  For this case we add "&& finalZone != 0".
        if (date >= finalMillis && finalZone != null) {
            double[] doub = floorDivide(date, (double)MILLIS_PER_DAY);
            double millis=doub[1];
            double days=doub[0];
            int[] temp = dayToFields(days);
            int year=temp[0], month=temp[1], dom=temp[2], dow=temp[3];
            rawoff = finalZone.getRawOffset();

            if (!local) {
                // Adjust from GMT to local
                date += rawoff;
                doub = floorDivide(date, (double)MILLIS_PER_DAY);
                double days2 = doub[0]; 
                millis = doub[1];
                if (days2 != days) {
                    temp = dayToFields(days2);
                    year=temp[0];
                    month=temp[1];
                    dom=temp[2];
                    dow=temp[3];
                }
            }

            dstoff = finalZone.getOffset(GregorianCalendar.AD, year, month, dom,
                                         dow, (int)millis) 
                    - rawoff;
            offsets[0]=rawoff;
            offsets[1]=dstoff;
            return;
        }

        double secs = Math.floor(date / MILLIS_PER_SECOND);
        getHistoricalOffset(secs, local, offsets);
        return;
    }
    double[] floorDivide(double dividend, double divisor) {
        double remainder; 
        double[] ret = new double[2];
        // Only designed to work for positive divisors
        if (ASSERT) Assert.assrt("divisor > 0", divisor > 0);
        double quotient = Math.floor(dividend/divisor);
        remainder = dividend - (quotient * divisor);
        // N.B. For certain large dividends, on certain platforms, there
        // is a bug such that the quotient is off by one. If you doubt
        // this to be true, set a breakpoint below and run cintltst.
        if (remainder < 0 || remainder >= divisor) {
            // E.g. 6.7317038241449352e+022 / 86400000.0 is wrong on my
            // machine (too high by one). 4.1792057231752762e+024 /
            // 86400000.0 is wrong the other way (too low).
            double q = quotient;
            quotient += (remainder < 0) ? -1 : +1;
            if (q == quotient) {
                // For quotients > ~2^53, we won't be able to add or
                // subtract one, since the LSB of the mantissa will be >
                // 2^0; that is, the exponent (base 2) will be larger than
                // the length, in bits, of the mantissa. In that case, we
                // can't give a correct answer, so we set the remainder to
                // zero. This has the desired effect of making extreme
                // values give back an approximate answer rather than
                // crashing. For example, UDate values above a ~10^25
                // might all have a time of midnight.
                remainder = 0;
            } else {
                remainder = dividend - (quotient * divisor);
            }
        }
        if (ASSERT) Assert.assrt("0 <= remainder && remainder < divisor", 0 <= remainder && remainder < divisor);
        ret[0]=quotient;
        ret[1]=remainder;
        return ret;
    }
    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#getRawOffset()
     */
    public int getRawOffset() {
        int[] ret = new int[2];
        getOffset( System.currentTimeMillis(), false, ret);
        return ret[0];
    }

    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#useDaylightTime()
     */
    public boolean useDaylightTime() {
//      If DST was observed in 1942 (for example) but has never been
        // observed from 1943 to the present, most clients will expect
        // this method to return FALSE.  This method determines whether
        // DST is in use in the current year (at any point in the year)
        // and returns TRUE if so.

        double[] dt = floorDivide(System.currentTimeMillis(), (double)MILLIS_PER_DAY); // epoch days
        int days = (int)dt[0];
        int[] it = dayToFields(days);

        int year=it[0]; /*, month=it[1], dom=it[2], dow=it[3]*/
        if (year > finalYear) { // [sic] >, not >=; see above
            if (ASSERT) Assert.assrt("finalZone != null && finalZone.useDaylightTime()", finalZone != null && finalZone.useDaylightTime());
            return true;
        }

        // Find start of this year, and start of next year
        int start = (int) fieldsToDay(year, 0, 1) * SECONDS_PER_DAY;    
        int limit = (int) fieldsToDay(year+1, 0, 1) * SECONDS_PER_DAY;    

        // Return TRUE if DST is observed at any time during the current
        // year.
        for (int i=0; i<transitionCount; ++i) {
            if (transitionTimes[i] >= limit) {
                break;
            }
            if (transitionTimes[i] >= start &&
                dstOffset(typeData[i]) != 0) {
                return true;
            }
        }
        return false;
    }
    /**
     * TimeZone API
     * Returns the amount of time to be added to local standard time
     * to get local wall clock time.
     */
    public int getDSTSavings() {
    	if(finalZone!=null){
    		return finalZone.getDSTSavings();
    	}
    	return super.getDSTSavings();
    	
    }
    /* (non-Javadoc)
     * @see com.ibm.icu.util.TimeZone#inDaylightTime(java.util.Date)
     */
    public boolean inDaylightTime(Date date) {
        int[] temp = new int[2];
        getOffset(date.getTime(), false, temp);
        return temp[1] != 0;
    }
    
    /**
     * Construct a GMT+0 zone with no transitions.  This is done when a
     * constructor fails so the resultant object is well-behaved.
     */
    private void constructEmpty(){
        transitionCount = 0;
        typeCount = 1;
        transitionTimes = typeOffsets = new int[]{0,0};
        typeData =  new byte[2];
        
    }
    /**
     * Construct from a resource bundle
     * @param top the top-level zoneinfo resource bundle.  This is used
     * to lookup the rule that `res' may refer to, if there is one.
     * @param res the resource bundle of the zone to be constructed
     */
    public OlsonTimeZone(ICUResourceBundle top, ICUResourceBundle res){
        construct(top, res);
    }
    private void construct(ICUResourceBundle top, ICUResourceBundle res){
        
        if ((top == null || res == null)) {
            throw new IllegalArgumentException();
        }
        if(DEBUG) System.out.println("OlsonTimeZone(" + res.getKey() +")");


        // TODO -- clean up -- Doesn't work if res points to an alias
        //        // TODO remove nonconst casts below when ures_* API is fixed
        //        setID(ures_getKey((UResourceBundle*) res)); // cast away const

        // Size 1 is an alias TO another zone (int)
        // HOWEVER, the caller should dereference this and never pass it in to us
        // Size 3 is a purely historical zone (no final rules)
        // Size 4 is like size 3, but with an alias list at the end
        // Size 5 is a hybrid zone, with historical and final elements
        // Size 6 is like size 5, but with an alias list at the end
        int size = res.getSize();
        if (size < 3 || size > 6) {
           // ec = U_INVALID_FORMAT_ERROR;
            throw new IllegalArgumentException("Invalid Format");
        }

        // Transitions list may be empty
        ICUResourceBundle r = res.get(0);
        transitionTimes = r.getIntVector();
        
        if ((transitionTimes.length<0 || transitionTimes.length>0x7FFF) ) {
            throw new IllegalArgumentException("Invalid Format");
        }
        transitionCount = (int) transitionTimes.length;
        
        // Type offsets list must be of even size, with size >= 2
        r = res.get( 1);
        typeOffsets = r.getIntVector();
        if ((typeOffsets.length<2 || typeOffsets.length>0x7FFE || ((typeOffsets.length&1)!=0))) {
            throw new IllegalArgumentException("Invalid Format");
        }
        typeCount = (int) typeOffsets.length >> 1;

        // Type data must be of the same size as the transitions list        
        r = res.get(2);
        typeData = r.getBinary().array();
        if (typeData.length != transitionCount) {
            throw new IllegalArgumentException("Invalid Format");
        }

        // Process final rule and data, if any
        if (size >= 5) {
            String ruleid = res.getString(3);
            r = res.get(4);
            int[] data = r.getIntVector();

            if (data != null && data.length == 2) {
                int rawOffset = data[0] * MILLIS_PER_SECOND;
                // Subtract one from the actual final year; we
                // actually store final year - 1, and compare
                // using > rather than >=.  This allows us to use
                // INT32_MAX as an exclusive upper limit for all
                // years, including INT32_MAX.
                if (ASSERT) Assert.assrt("data[1] > Integer.MIN_VALUE", data[1] > Integer.MIN_VALUE);
                finalYear = data[1] - 1;
                // Also compute the millis for Jan 1, 0:00 GMT of the
                // finalYear.  This reduces runtime computations.
                finalMillis = fieldsToDay(data[1], 0, 1) * TimeZone.MILLIS_PER_DAY;
                //U_DEBUG_TZ_MSG(("zone%s|%s: {%d,%d}, finalYear%d, finalMillis%.1lf\n",
                  //              zKey,rKey, data[0], data[1], finalYear, finalMillis));
                r = loadRule(top, ruleid);

                // 3, 1, -1, 7200, 0, 9, -31, -1, 7200, 0, 3600
                data = r.getIntVector();
                if ( data.length == 11) {
                    //U_DEBUG_TZ_MSG(("zone%s, rule%s: {%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d}", zKey, ures_getKey(r), 
                      //            data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10]));
                    finalZone = new SimpleTimeZone(rawOffset, "",
                        data[0], data[1], data[2],
                        data[3] * MILLIS_PER_SECOND,
                        data[4],
                        data[5], data[6], data[7],
                        data[8] * MILLIS_PER_SECOND,
                        data[9],
                        data[10] * MILLIS_PER_SECOND);
                } else {
                    throw new IllegalArgumentException("Invalid Format");
                }                
            } else {
                throw new IllegalArgumentException("Invalid Format");
            }
        }       
    }
    public OlsonTimeZone(){
       /*
        * 
        finalYear = Integer.MAX_VALUE;
        finalMillis = Double.MAX_VALUE;
        finalZone = null;
        */
        constructEmpty();
    }


    public OlsonTimeZone(String id){
        ICUResourceBundle top = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "zoneinfo", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
        ICUResourceBundle res = ZoneMeta.openOlsonResource(id);
        construct(top, res);
        if(finalZone!=null){
            finalZone.setID(id);
        }
        super.setID(id);
    }
    public void setID(String id){
        if(finalZone!= null){
            finalZone.setID(id);
        }
        super.setID(id);
    }
    private static final int UNSIGNED_BYTE_MASK =0xFF;
    private int getInt(byte val){
    	return (int)(UNSIGNED_BYTE_MASK & val); 
    }
    private void getHistoricalOffset(double time, boolean local, int[] offsets) {
        if (transitionCount != 0) {
            // Linear search from the end is the fastest approach, since
            // most lookups will happen at/near the end.
            int i = 0;
            for (i = transitionCount - 1; i > 0; --i) {
                int transition = transitionTimes[i];
                if (local) {
                    int zoneOffsetPrev = zoneOffset(getInt(typeData[i-1]));
                    int zoneOffsetCurr = zoneOffset(getInt(typeData[i]));
                    if(zoneOffsetPrev < zoneOffsetCurr) {
                        transition += zoneOffsetPrev;
                    } else {
                        transition += zoneOffsetCurr;
                    }
                }
                if (time >= transition) {
                    break;
                }
            }

            if (ASSERT) Assert.assrt("i>=0 && i<transitionCount", i>=0 && i<transitionCount);

            // Check invariants for GMT times; if these pass for GMT times
            // the local logic should be working too.
            if (ASSERT) {
                Assert.assrt("local || time < transitionTimes[0] || time >= transitionTimes[i]", 
                        local || time < transitionTimes[0] || time >= transitionTimes[i]);
                Assert.assrt("local || i == transitionCount-1 || time < transitionTimes[i+1]", 
                        local || i == transitionCount-1 || time < transitionTimes[i+1]);
            }
            if (i == 0) {
                // Check if the given time is before the very first transition
                int firstTransition = transitionTimes[0];
                int initialRawOffset = rawOffset(getInt(typeData[0]));
                if (local) {
                    firstTransition += initialRawOffset;
                }
                if (time >= firstTransition) {
                    // The given time is between the first and the second transition
                    offsets[0] = initialRawOffset * MILLIS_PER_SECOND;
                    offsets[1] = dstOffset(getInt(typeData[0])) * MILLIS_PER_SECOND;
                } else {
                    // The given time is before the first transition
                    offsets[0] = initialRawOffset * MILLIS_PER_SECOND;
                    offsets[1] = 0;
                }
            } else {
                int index = getInt(typeData[i]);
                offsets[0] = rawOffset(index) * MILLIS_PER_SECOND;
                offsets[1] = dstOffset(index) * MILLIS_PER_SECOND;
            }
        } else {
            // No transitions, single pair of offsets only
            offsets[0] = rawOffset(0) * MILLIS_PER_SECOND;
            offsets[1] = dstOffset(0) * MILLIS_PER_SECOND;
        }
    }
    private int zoneOffset(int index){
        index=index << 1;
        return typeOffsets[index] + typeOffsets[index+1];
    }
    private int rawOffset(int index){
        return typeOffsets[(int)(index << 1)];
    }
    private int dstOffset(int index){
        return typeOffsets[(int)((index << 1) + 1)];
    }
    
    // temp
    public String toString() {
    	StringBuffer buf = new StringBuffer();
    	buf.append(super.toString());
    	buf.append('[');
    	buf.append("transitionCount=" + transitionCount);
    	buf.append(",typeCount=" + typeCount);
    	buf.append(",transitionTimes=");
    	if (transitionTimes != null) {
    		buf.append('[');
    		for (int i = 0; i < transitionTimes.length; ++i) {
    			if (i > 0) {
    				buf.append(',');
    			}
    			buf.append(Integer.toString(transitionTimes[i]));
    		}
    		buf.append(']');
    	} else {
    		buf.append("null");
    	}
    	buf.append(",typeOffsets=");
    	if (typeOffsets != null) {
    		buf.append('[');
    		for (int i = 0; i < typeOffsets.length; ++i) {
    			if (i > 0) {
    				buf.append(',');
    			}
    			buf.append(Integer.toString(typeOffsets[i]));
    		}
    		buf.append(']');
    	} else {
    		buf.append("null");
    	}
    	buf.append(",finalYear=" + finalYear);
    	buf.append(",finalMillis=" + finalMillis);
    	buf.append(",finalZone=" + finalZone);
    	buf.append(']');
    	
    	return buf.toString();
    }
    /**
     * Number of transitions, 0..~370
     */
    private int transitionCount;

    /**
     * Number of types, 1..255
     */
    private int typeCount;

    /**
     * Time of each transition in seconds from 1970 epoch.
     * Length is transitionCount int32_t's.
     */
    private int[] transitionTimes; // alias into res; do not delete

    /**
     * Offset from GMT in seconds for each type.
     * Length is typeCount int32_t's.
     */
    private int[] typeOffsets; // alias into res; do not delete

    /**
     * Type description data, consisting of transitionCount uint8_t
     * type indices (from 0..typeCount-1).
     * Length is transitionCount int8_t's.
     */
    private byte[] typeData; // alias into res; do not delete

    /**
     * The last year for which the transitions data are to be used
     * rather than the finalZone.  If there is no finalZone, then this
     * is set to INT32_MAX.  NOTE: This corresponds to the year _before_
     * the one indicated by finalMillis.
     */
    private int finalYear = Integer.MAX_VALUE;

    /**
     * The millis for the start of the first year for which finalZone
     * is to be used, or DBL_MAX if finalZone is 0.  NOTE: This is
     * 0:00 GMT Jan 1, <finalYear + 1> (not <finalMillis>).
     */
    private double finalMillis = Double.MAX_VALUE;

    /**
     * A SimpleTimeZone that governs the behavior for years > finalYear.
     * If and only if finalYear == INT32_MAX then finalZone == 0.
     */
    private SimpleTimeZone finalZone = null; // owned, may be NULL
    
    private static final boolean DEBUG = ICUDebug.enabled("olson");
    private static final int[] DAYS_BEFORE = new int[] {0,31,59,90,120,151,181,212,243,273,304,334,
                                           0,31,60,91,121,152,182,213,244,274,305,335};

    private static final int[] MONTH_LENGTH = new int[]{31,28,31,30,31,30,31,31,30,31,30,31,
                                        31,29,31,30,31,30,31,31,30,31,30,31};
    private static final int JULIAN_1_CE    = 1721426; // January 1, 1 CE Gregorian
    private static final int JULIAN_1970_CE = 2440588; // January 1, 1970 CE Gregorian
    private static final int MILLIS_PER_SECOND  = 1000;
    private static final int SECONDS_PER_DAY = 24*60*60;
    
    private static final double fieldsToDay(int year, int month, int dom) {
        int y = year - 1;
        double julian = 365 * y + myFloorDivide(y, 4) + (JULIAN_1_CE - 3) + // Julian cal
        myFloorDivide(y, 400) - myFloorDivide(y, 100) + 2 + // => Gregorian cal
            DAYS_BEFORE[month + (isLeapYear(year) ? 12 : 0)] + dom; // => month/dom
    
        return julian - JULIAN_1970_CE; // JD => epoch day
    }
    private static final boolean isLeapYear(int year) {
        // year&0x3 == year%4
        return ((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0));
    }

    private static ICUResourceBundle loadRule(ICUResourceBundle top, String ruleid) {
        ICUResourceBundle r = top.get("Rules");
        r = r.get(ruleid);
        return r;
    }
    /**
     * Divide two long integers, returning the floor of the quotient.
     * <p>
     * Unlike the built-in division, this is mathematically well-behaved.
     * E.g., <code>-1/4</code> => 0
     * but <code>floorDivide(-1,4)</code> => -1.
     * @param numerator the numerator
     * @param denominator a divisor which must be > 0
     * @return the floor of the quotient.
     * @stable ICU 2.0
     */
    private static final long myFloorDivide(long numerator, long denominator) {
        // We do this computation in order to handle
        // a numerator of Long.MIN_VALUE correctly
        return (numerator >= 0) ?
            numerator / denominator :
            ((numerator + 1) / denominator) - 1;
    }
    int[] dayToFields(double day) {
         int year, month, dom, dow;
         double doy;
         int[] ret = new int[5];
         
        // Convert from 1970 CE epoch to 1 CE epoch (Gregorian calendar)
        day += JULIAN_1970_CE - JULIAN_1_CE;
        
        // Convert from the day number to the multiple radix
        // representation.  We use 400-year, 100-year, and 4-year cycles.
        // For example, the 4-year cycle has 4 years + 1 leap day; giving
        // 1461 == 365*4 + 1 days.
        double[]temp  = floorDivide(day, 146097); // 400-year cycle length
        double n400 = temp[0];
        doy  = temp[1];
        temp = floorDivide(doy, 36524); // 100-year cycle length
        double n100 = temp[0];
        doy = temp[1];
        temp = floorDivide(doy, 1461); // 4-year cycle length
        double n4 = temp[0];
        doy = temp[1];
        temp = floorDivide(doy, 365);
        double n1 = temp[0];
        doy = temp[1];
        year = (int)( 400*n400 + 100*n100 + 4*n4 + n1);
        if (n100 == 4 || n1 == 4) {
            doy = 365; // Dec 31 at end of 4- or 400-year cycle
        } else {
            ++year;
        }
    
        boolean isLeap = isLeapYear(year);
        
        // Gregorian day zero is a Monday.
        dow = (int) ((day + 1) % 7);
        dow += (dow < 0) ? (Calendar.SUNDAY + 7) : Calendar.SUNDAY;
        
        // Common Julian/Gregorian calculation
        int correction = 0;
        int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
        if (doy >= march1) {
            correction = isLeap ? 1 : 2;
        }
        month = (int)((12 * (doy + correction) + 6) / 367); // zero-based month
        dom = (int)(doy - DAYS_BEFORE[month + (isLeap ? 12 : 0)] + 1); // one-based DOM
        doy++; // one-based doy
        ret[0]=year;
        ret[1]=month;
        ret[2]=dom;
        ret[3]=dow;
        ret[4]=(int)doy;
        return ret;
    }
    public boolean equals(Object obj){
        if (!super.equals(obj)) return false; // super does class check
        
        OlsonTimeZone z = (OlsonTimeZone) obj;

        return (Utility.arrayEquals(typeData, z.typeData) ||
                 // If the pointers are not equal, the zones may still
                 // be equal if their rules and transitions are equal
                 (finalYear == z.finalYear &&
                  // Don't compare finalMillis; if finalYear is ==, so is finalMillis
                  ((finalZone == null && z.finalZone == null) ||
                   (finalZone != null && z.finalZone != null &&
                    finalZone.equals(z.finalZone)) &&
                  transitionCount == z.transitionCount &&
                  typeCount == z.typeCount &&
                  Utility.arrayEquals(transitionTimes, z.transitionTimes) &&
                  Utility.arrayEquals(typeOffsets, z.typeOffsets) &&
                  Utility.arrayEquals(typeData, z.typeData)
                  )));

    }
    public int hashCode(){
    	int ret =   (int)  (finalYear ^ (finalYear>>>4) +
    			   transitionCount ^ (transitionCount>>>6) +
    			   typeCount ^ (typeCount>>>8) + 
    			   Double.doubleToLongBits(finalMillis)+
    			   (finalZone == null ? 0 : finalZone.hashCode()) + 
    			   super.hashCode());
    	for(int i=0; i<transitionTimes.length; i++){
    		ret+=transitionTimes[i]^(transitionTimes[i]>>>8);
    	}
	    for(int i=0; i<typeOffsets.length; i++){
    		ret+=typeOffsets[i]^(typeOffsets[i]>>>8);
    	}
	    for(int i=0; i<typeData.length; i++){
    		ret+=typeData[i] & UNSIGNED_BYTE_MASK;
    	} 
	    return ret;
    }
    /*
    private void readObject(ObjectInputStream s) throws IOException  {
        s.defaultReadObject();
        // customized deserialization code
       
        // followed by code to update the object, if necessary
    }
    */
}

