abstractdatetimedv.java

来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 783 行 · 第 1/2 页

JAVA
783
字号
    /**     * Computes index of given char within StringBuffer     *     * @param start     * @param end     * @param ch     character to look for in StringBuffer     * @return index of ch within StringBuffer     */    protected  int indexOf (String buffer, int start, int end, char ch) {        for ( int i=start;i<end;i++ ) {            if ( buffer.charAt(i) == ch ) {                return i;            }        }        return -1;    }    /**     * Validates given date/time object accoring to W3C PR Schema     * [D.1 ISO 8601 Conventions]     *     * @param data     */    protected void validateDateTime (int[] data, int[] timeZone) {        //REVISIT: should we throw an exception for not valid dates        //          or reporting an error message should be sufficient?        if ( data[CY]==0 ) {            throw new RuntimeException("The year \"0000\" is an illegal year value");        }        if ( data[M]<1 || data[M]>12 ) {            throw new RuntimeException("The month must have values 1 to 12");        }        //validate days        if ( data[D]>maxDayInMonthFor(data[CY], data[M]) || data[D]<1 ) {            throw new RuntimeException("The day must have values 1 to 31");        }        //validate hours        if ( data[h]>23 || data[h]<0 ) {            if (data[h] == 24 && data[m] == 0 && data[s] == 0 && data[ms] == 0) {                data[h] = 0;                if (++data[D] > maxDayInMonthFor(data[CY], data[M])) {                    data[D] = 1;                    if (++data[M] > 12) {                        data[M] = 1;                        if (++data[CY] == 0)                            data[CY] = 1;                    }                }            }            else {                throw new RuntimeException("Hour must have values 0-23, unless 24:00:00");            }        }        //validate        if ( data[m]>59 || data[m]<0 ) {            throw new RuntimeException("Minute must have values 0-59");        }        //validate        if ( data[s]>60 || data[s]<0 ) {            throw new RuntimeException("Second must have values 0-60");        }        //validate        if ( timeZone[hh]>14 || timeZone[hh]<-14 ) {            throw new RuntimeException("Time zone should have range -14..+14");        }        //validate        if ( timeZone[mm]>59 || timeZone[mm]<-59 ) {            throw new RuntimeException("Minute must have values 0-59");        }    }    /**     * Return index of UTC char: 'Z', '+', '-'     *     * @param start     * @param end     * @return index of the UTC character that was found     */    protected int findUTCSign (String buffer, int start, int end) {        int c;        for ( int i=start;i<end;i++ ) {            c=buffer.charAt(i);            if ( c == 'Z' || c=='+' || c=='-' ) {                return i;            }        }        return -1;    }    /**     * Given start and end position, parses string value     *     * @param value  string to parse     * @param start  Start position     * @param end    end position     * @return  return integer representation of characters     */    protected  int parseInt (String buffer, int start, int end)    throws NumberFormatException{        //REVISIT: more testing on this parsing needs to be done.        int radix=10;        int result = 0;        int digit=0;        int limit = -Integer.MAX_VALUE;        int multmin = limit / radix;        int i = start;        do {            digit = getDigit(buffer.charAt(i));            if ( digit < 0 ) throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");            if ( result < multmin ) throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");            result *= radix;            if ( result < limit + digit ) throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");            result -= digit;        }while ( ++i < end );        return -result;    }    // parse Year differently to support negative value.    protected int parseIntYear (String buffer, int end){        int radix=10;        int result = 0;        boolean negative = false;        int i=0;        int limit;        int multmin;        int digit=0;        if (buffer.charAt(0) == '-'){            negative = true;            limit = Integer.MIN_VALUE;            i++;        }        else{            limit = -Integer.MAX_VALUE;        }        multmin = limit / radix;        while (i < end)        {            digit = getDigit(buffer.charAt(i++));            if (digit < 0) throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");            if (result < multmin) throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");            result *= radix;            if (result < limit + digit) throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");            result -= digit;        }        if (negative)        {            if (i > 1) return result;            else throw new NumberFormatException("'"+buffer.toString()+"' has wrong format");        }        return -result;    }    /**     * If timezone present - normalize dateTime  [E Adding durations to dateTimes]     *     * @param date   CCYY-MM-DDThh:mm:ss+03     * @return CCYY-MM-DDThh:mm:ssZ     */    protected  void normalize (int[] date, int[] timeZone) {        // REVISIT: we have common code in addDuration() for durations        //          should consider reorganizing it.        //        //add minutes (from time zone)        int negate = 1;        if (date[utc]=='+') {            negate = -1;        }        if ( DEBUG ) {            System.out.println("==>date[m]"+date[m]);            System.out.println("==>timeZone[mm]" +timeZone[mm]);        }        int temp = date[m] + negate*timeZone[mm];        int carry = fQuotient (temp, 60);        date[m]= mod(temp, 60, carry);        if ( DEBUG ) {            System.out.println("==>carry: " + carry);        }        //add hours        temp = date[h] + negate*timeZone[hh] + carry;        carry = fQuotient(temp, 24);        date[h]=mod(temp, 24, carry);        if ( DEBUG ) {            System.out.println("==>date[h]"+date[h]);            System.out.println("==>carry: " + carry);        }        date[D]=date[D]+carry;        while ( true ) {            temp=maxDayInMonthFor(date[CY], date[M]);            if (date[D]<1) {                date[D] = date[D] + maxDayInMonthFor(date[CY], date[M]-1);                carry=-1;            }            else if ( date[D]>temp ) {                date[D]=date[D]-temp;                carry=1;            }            else {                break;            }            temp=date[M]+carry;            date[M]=modulo(temp, 1, 13);            date[CY]=date[CY]+fQuotient(temp, 1, 13);        }        date[utc]='Z';    }    /**     * Resets object representation of date/time     *     * @param data   date/time object     */    protected void resetDateObj (int[] data) {        for ( int i=0;i<TOTAL_SIZE;i++ ) {            data[i]=0;        }    }    /**     * Given {year,month} computes maximum     * number of days for given month     *     * @param year     * @param month     * @return integer containg the number of days in a given month     */    protected int maxDayInMonthFor(int year, int month) {        //validate days        if ( month==4 || month==6 || month==9 || month==11 ) {            return 30;        }        else if ( month==2 ) {            if ( isLeapYear(year) ) {                return 29;            }            else {                return 28;            }        }        else {            return 31;        }    }    private boolean isLeapYear(int year) {        //REVISIT: should we take care about Julian calendar?        return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));    }    //    // help function described in W3C PR Schema [E Adding durations to dateTimes]    //    protected int mod (int a, int b, int quotient) {        //modulo(a, b) = a - fQuotient(a,b)*b        return (a - quotient*b) ;    }    //    // help function described in W3C PR Schema [E Adding durations to dateTimes]    //    protected int fQuotient (int a, int b) {        //fQuotient(a, b) = the greatest integer less than or equal to a/b        return (int)Math.floor((float)a/b);    }    //    // help function described in W3C PR Schema [E Adding durations to dateTimes]    //    protected int modulo (int temp, int low, int high) {        //modulo(a - low, high - low) + low        int a = temp - low;        int b = high - low;        return (mod (a, b, fQuotient(a, b)) + low) ;    }    //    // help function described in W3C PR Schema [E Adding durations to dateTimes]    //    protected int fQuotient (int temp, int low, int high) {        //fQuotient(a - low, high - low)        return fQuotient(temp - low, high - low);    }    protected String dateToString(int[] date) {        StringBuffer message = new StringBuffer(25);        append(message, date[CY], 4);        message.append('-');        append(message, date[M], 2);        message.append('-');        append(message, date[D], 2);        message.append('T');        append(message, date[h], 2);        message.append(':');        append(message, date[m], 2);        message.append(':');        append(message, date[s], 2);        message.append('.');        message.append(date[ms]);        append(message, (char)date[utc], 0);        return message.toString();    }        protected void append(StringBuffer message, int value, int nch) {        if (value < 0) {            message.append('-');            value = -value;        }        if (nch == 4) {            if (value < 10)                message.append("000");            else if (value < 100)                message.append("00");            else if (value < 1000)                message.append("0");            message.append(value);        }        else if (nch == 2) {            if (value < 10)                message.append('0');            message.append(value);        }        else {            if (value != 0)                message.append((char)value);        }    }    //    //Private help functions    //    private void cloneDate (int[] finalValue, int[] tempDate) {        System.arraycopy(finalValue, 0, tempDate, 0, TOTAL_SIZE);    }    /**     * Represents date time data     */    static final class DateTimeData {        // actual data stored in an int array        final int[] data;        // a pointer to the type that was used go generate this data        // note that this is not the actual simple type, but one of the        // statically created XXXDV objects, so this won't cause any GC problem.        final AbstractDateTimeDV type;        private String canonical;        public DateTimeData(int[] data, AbstractDateTimeDV type) {            this.data = data;            this.type = type;        }        public boolean equals(Object obj) {            if (!(obj instanceof DateTimeData))                return false;            int[] odata = ((DateTimeData)obj).data;            return type.compareDates(data, odata, true)==0;        }        public synchronized String toString() {            if (canonical == null) {                canonical = type.dateToString(data);            }            return canonical;        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?