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 + -
显示快捷键?