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

import java.io.IOException;
import java.io.ObjectInputStream;
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);

        return zoneOffset(findTransition(time, true)) * MILLIS_PER_SECOND;
    }
    /* (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);
        int i = findTransition(secs, local);
        rawoff = rawOffset(i) * MILLIS_PER_SECOND;
        dstoff = dstOffset(i) * MILLIS_PER_SECOND;
        offsets[0]=rawoff;
        offsets[1]=dstoff;
        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
     * @param ec input-output error code
     */
    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 int findTransition(double time, boolean local) {
        int i = 0;
        
        if (transitionCount != 0) {
            // Linear search from the end is the fastest approach, since
            // most lookups will happen at/near the end.
            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]);
            }

            i = typeData[i];
        }

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

    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
    }
    */
}

