📄 schemacalendarbase.java
字号:
temp.value = 0;
if (digits >= 8) // overflow
return false;
}
if (digits < 4) // inalid
return false;
if (digits > 4 && year.value < 10000)
return false;
if (bNegative)
year.value = -year.value;
}
if ((part & (DateTimePart_Month | DateTimePart_Day)) != 0)
{
if ( !context.checkAndAdvance( '-' ) )
return false;
if ( ( part & DateTimePart_Month ) != 0 )
{
if ( !context.readDigitAndAdvance(month, 10, 1 ) ) return false;
if ( !context.readDigitAndAdvance(month, 1, month.value < 10 ? 9 : 2 ) ) return false;
if ( month.value == 0 ) return false;
}
if ( ( part & DateTimePart_Day ) != 0 )
{
if ( !context.checkAndAdvance('-') ) return false;
int maxFirstDigit = month.value != 2 ? 3 : 2;
// complicate things by making them complicated.
if ( !context.readDigitAndAdvance( day, 10, maxFirstDigit ) ) return false;
if ( !context.readDigitAndAdvance( day, 1, 9 ) ) return false;
if ( day.value == 0 || day.value > 31 ) return false;
if ( ( part & DateTimePart_Month ) != 0 )
{
boolean b1 = month.value <= 7;
boolean b2 = ( month.value & 1 ) == 0;
// month 1, 3, 5, 7, 8, 10, 12
if ( b1 == b2 && day.value > 30 )
return false;
// february.
if ( month.value == 2 && day.value > 29 )
return false;
// leap years.
if (month.value == 2 && (part & DateTimePart_Year) != 0 &&
(year.value % 4 != 0 || year.value % 100 == 0) &&
year.value % 400 != 0 && day.value > 28)
return false;
}
}
}
if ( bTimePart )
{
// a 'T' must follow
if ( !context.checkAndAdvance('T') ) return false;
}
}
if ( bTimePart )
{
// check format here
// hour from 0 to 2
if ( !context.readDigitAndAdvance( hour, 10, 2 ) ) return false;
if ( !context.readDigitAndAdvance( hour, 1, hour.value < 20 ? 9 : 4 ) ) return false;
if ( !context.checkAndAdvance( ':' ) ) return false;
int maxFirstDigit = hour.value == 24 ? 0 : 5;
int maxSecondDigit = hour.value == 24 ? 0 : 9;
if ( !context.readDigitAndAdvance( minute, 10, maxFirstDigit ) ) return false;
if ( !context.readDigitAndAdvance( minute, 1, maxSecondDigit ) ) return false;
if ( !context.checkAndAdvance( ':' ) ) return false;
RefInt secondInt = new RefInt (0);
if ( !context.readDigitAndAdvance( secondInt, 10, maxFirstDigit ) ) return false;
if ( !context.readDigitAndAdvance( secondInt, 1, maxSecondDigit ) ) return false;
second = secondInt.value;
if ( context.checkAndAdvance( '.' ) )
{
// fraction. do whatever seems fit.
RefInt val = new RefInt(0);
int digits = 0;
while ( context.readDigitAndAdvance( val, 1, 9) )
{
val.value *= 10;
digits += 1;
if ( digits >= 8 ) // precision loss - ignore
break;
}
if ( digits == 0 )
return false;
second += val.value * Math.pow( 10.0, -digits - 1 );
// skip any further digits.
while ( context.readDigitAndAdvance( val, 0, 9) )
;
}
}
// timezone
if ( context.checkAndAdvance('Z') )
{
// timezone specified, it is UTC.
hasTZ = TZ_UTC;
offsetTZ = 0;
}
else if ( context.check('+') || context.check('-' ) )
{
// timezone offset, in hour:minute format
boolean bNegative = context.check('-');
context.advance();
// do not check the hour part, for those who are obscure.
RefInt temp = new RefInt(0);
if ( !context.readDigitAndAdvance( temp, 600, 9 ) ) return false;
if ( !context.readDigitAndAdvance( temp, 60, 9 ) ) return false;
if ( !context.checkAndAdvance( ':' ) ) return false;
if ( !context.readDigitAndAdvance( temp, 10, 5 ) ) return false;
if ( !context.readDigitAndAdvance( temp, 1, 9 ) ) return false;
hasTZ = TZ_OFFSET;
offsetTZ = bNegative ? -temp.value : temp.value;
}
if ( context.isValid() )
return false;
setInternalValues(year.value, month.value, day.value, hour.value, minute.value, (int)second, ((second * 1000) % 1000)/1000, hasTZ, offsetTZ);
return true;
}
public double getApproximatedTotal() {
// approximated because month is approximated to have always 31 days.
return (double)second + 60.0*((double)minute + 60.0*((double)hour + 24.0*((double)day + 31.0*((double)month + 12.0*(double)year)))) + partsecond;
}
static int[] monthStart = new int[]
{
0, // 1st of Jan
31, // 1st of Feb
59, // 1st of Mar
90, // 1st of Apr
120, // 1st of May
151, // 1st of Jun
181, // 1st of Jul
212, // 1st of Aug
243, // 1st of Sep
273, // 1st of Oct
304, // 1st of Nov
334, // 1st of Dec
365, // 1st of next year
};
static int[] monthStartLeap = new int[]
{
0, // 1st of Jan
31, // 1st of Feb
60, // 1st of Mar
91, // 1st of Apr
121, // 1st of May
152, // 1st of Jun
182, // 1st of Jul
213, // 1st of Aug
244, // 1st of Sep
274, // 1st of Oct
305, // 1st of Nov
335, // 1st of Dec
366, // 1st of next year
};
public long getTimeValue()
{
long value = 0;
int realYear = year;
int monthRem = ( month - 1 ) % 12;
if ( monthRem < 0 ) monthRem += 12;
realYear += ( month - monthRem - 1 ) / 12;
int yearRed = realYear - 1;
int yearRem = yearRed % 400;
if ( yearRem < 0 ) yearRem += 400;
value += ( ( yearRed - yearRem ) / 400 ) * (303 * 365 + 97 * 366);
value += ( yearRem / 100 ) * (76 * 365 + 24 * 366);
yearRem %= 100;
value += ( yearRem / 4 ) * (365 * 3 + 366);
yearRem %= 4;
value += yearRem * 365;
if ( ( realYear % 4 == 0 ) && ( ( realYear % 100 != 0 ) || ( realYear % 400 == 0 ) ) )
value += monthStartLeap[ monthRem ];
else
value += monthStart[ monthRem ];
value += day - 1;
value = value * 24 + hour;
value = value * 60 + minute - offsetTZ;
value = ( long )( ( value * 60 + second + partsecond ) * 1000 );
return value;
}
public void setTimeFromTimeValue(long tv)
{
tv %= (86400 * 1000);
if ( tv < 0 )
tv += 86400 * 1000;
partsecond = (tv % 1000) / 1000.0;
tv /= 1000;
second = (int)(tv % 60);
tv /= 60;
minute = (int) (tv % 60);
tv /= 60;
hour = (int) (tv % 24);
}
public void setDateFromTimeValue(long tv)
{
long dayTime = tv % ( 86400 * 1000 );
int days = (int)(tv / (86400 * 1000));
if ( dayTime < 0 )
days -= 1;
year = days < 0 ? -1 : +1; // there is no year 0
month = 1;
day = 1;
year += 400 * ( days / (303 * 365 + 97 * 366) );
days %= (303 * 365 + 97 * 366);
if ( days == (303 * 365 + 97 * 366) - 1 )
{
year += 399;
days = 365;
}
else
{
year += 100 * ( days / (76 * 365 + 24 * 366) );
days %= (76 * 365 + 24 * 366);
year += 4 * ( days / (365 * 3 + 366) );
days %= (365 * 3 + 366);
if ( days == (365 * 3 + 366) - 1 ) // last day of leap year
{
year += 3;
days = 365;
}
else
{
year += days / 365;
days %= 365;
}
}
if ( days < 0 )
days += 365;
int[] monthStarts;
if ( ( year % 4 == 0 ) && ( ( year % 100 != 0 ) || ( year % 400 == 0 ) ) )
monthStarts = monthStartLeap;
else
monthStarts = monthStart;
while ( days >= monthStarts[ month ] )
++month;
day = days - monthStarts[ month - 1 ] + 1;
}
public Date getDate() {
String s = toDateString() + " " + toTimeString();
try {
return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s));
} catch( java.text.ParseException e ) {
throw new StringParseException("Could not convert to date.", 0);
}
}
protected void setInternalValues(int newyear, int newmonth, int newday, int newhour, int newminute, int newsecond, double newpartsecond, int newhasTZ, int newoffsetTZ) {
year = newyear;
month = newmonth;
day = newday;
hour = newhour;
minute = newminute;
second = newsecond;
partsecond = newpartsecond;
hasTZ = newhasTZ;
offsetTZ = newoffsetTZ;
isempty = false;
}
// ---------- interface SchemaTypeCalendar ----------
public SchemaDuration durationValue() {
throw new TypesIncompatibleException(this, new SchemaDuration( "PT" ) );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -