FULL PRODUCT VERSION :
java version "1.6.0_27"
Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
Java HotSpot(TM) Server VM (build 20.2-b06, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux oskar 2.6.30.10-105.2.23.fc11.i586
Linux pawel 2.6.35.6-48.fc14.i686
Linux newapps 2.6.32-5-686-bigmem
A DESCRIPTION OF THE PROBLEM :
Similar to bug ID=6763465.
I have upgraded Java 1.6.0_11 to Java 1.6.0_22 and problem appeared.
Method java.util.Date.valueOf stopped accept one digit month and one digit day. For example Date.valueOf("2011-9-8") will throw exception java.lang.IllegalArgumentException. But in Java 1.6.0_11 this format was accepted.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Java 1.6.0_22
and call
java.util.Date.valueOf("2011-8-13");
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect that Date.valueOf will accept one digit month and one digit day.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/**
* 28-09-2011
*/
package pl.ziaja.test.date;
import java.util.Date;
/**
* Test of valueOf methods - Java 1.6.0_11 vs Java 1.6.0_22.
* This snipped of code is source from java.util.Date
* @author Oskar Sawicki
*/
public class TestDateValueOf {
public static Date valueOf22(String s) {
final int YEAR_LENGTH = 4;
final int MONTH_LENGTH = 2;
final int DAY_LENGTH = 2;
final int MAX_MONTH = 12;
final int MAX_DAY = 31;
int firstDash;
int secondDash;
Date d = null;
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
firstDash = s.indexOf('-');
secondDash = s.indexOf('-', firstDash + 1);
if (firstDash > 0 && secondDash > 0 && secondDash < s.length() - 1) {
String yyyy = s.substring(0, firstDash);
String mm = s.substring(firstDash + 1, secondDash);
String dd = s.substring(secondDash + 1);
if (yyyy.length() == YEAR_LENGTH && mm.length() == MONTH_LENGTH
&& dd.length() == DAY_LENGTH) {
int year = Integer.parseInt(yyyy);
int month = Integer.parseInt(mm);
int day = Integer.parseInt(dd);
if (month >= 1 && month <= MAX_MONTH) {
int maxDays = MAX_DAY;
switch (month) {
// February determine if a leap year or not
case 2:
if (year % 4 == 0 && !(year % 100 == 0) || year % 400 == 0) {
maxDays = MAX_DAY - 2; // leap year so 29 days in
// February
} else {
maxDays = MAX_DAY - 3; // not a leap year so 28 days
// in February
}
break;
// April, June, Sept, Nov 30 day months
case 4:
case 6:
case 9:
case 11:
maxDays = MAX_DAY - 1;
break;
}
if (day >= 1 && day <= maxDays) {
d = new Date(year - 1900, month - 1, day);
}
}
}
}
if (d == null) {
throw new java.lang.IllegalArgumentException();
}
return d;
}
public static Date valueOf11(String s) {
int year;
int month;
int day;
int firstDash;
int secondDash;
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
firstDash = s.indexOf('-');
secondDash = s.indexOf('-', firstDash + 1);
if (firstDash > 0 & secondDash > 0 & secondDash < s.length() - 1) {
year = Integer.parseInt(s.substring(0, firstDash)) - 1900;
month = Integer.parseInt(s.substring(firstDash + 1, secondDash)) - 1;
day = Integer.parseInt(s.substring(secondDash + 1));
} else {
throw new java.lang.IllegalArgumentException();
}
return new Date(year, month, day);
}
public static void main(String[] a) {
System.out.println(valueOf11("2011-8-13")); // OK
System.out.println(valueOf22("2011-8-13")); // exception
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
// This is modification of java.util.Date.valueOf method from Java 1.6.0_22
public static Date valueOf(String s) {
final int YEAR_LENGTH = 4;
final int MONTH_MAX_LENGTH = 2;
final int DAY_MAX_LENGTH = 2;
final int MONTH_MIN_LENGTH = 1;
final int DAY_MIN_LENGTH = 1;
final int MAX_MONTH = 12;
final int MAX_DAY = 31;
int firstDash;
int secondDash;
Date d = null;
if (s == null) {
throw new java.lang.IllegalArgumentException();
}
firstDash = s.indexOf('-');
secondDash = s.indexOf('-', firstDash + 1);
if (firstDash > 0 && secondDash > 0 && secondDash < s.length() - 1) {
String yyyy = s.substring(0, firstDash);
String mm = s.substring(firstDash + 1, secondDash);
String dd = s.substring(secondDash + 1);
if (yyyy.length() == YEAR_LENGTH && mm.length() >= MONTH_MIN_LENGTH
&& mm.length() <= MONTH_MAX_LENGTH && dd.length() >= DAY_MIN_LENGTH
&& dd.length() <= DAY_MAX_LENGTH) {
int year = Integer.parseInt(yyyy);
int month = Integer.parseInt(mm);
int day = Integer.parseInt(dd);
if (month >= 1 && month <= MAX_MONTH) {
int maxDays = MAX_DAY;
switch (month) {
// February determine if a leap year or not
case 2:
if (year % 4 == 0 && !(year % 100 == 0) || year % 400 == 0) {
maxDays = MAX_DAY - 2; // leap year so 29 days in
// February
} else {
maxDays = MAX_DAY - 3; // not a leap year so 28 days
// in February
}
break;
// April, June, Sept, Nov 30 day months
case 4:
case 6:
case 9:
case 11:
maxDays = MAX_DAY - 1;
break;
}
if (day >= 1 && day <= maxDays) {
d = new Date(year - 1900, month - 1, day);
}
}
}
}
if (d == null) {
throw new java.lang.IllegalArgumentException();
}
return d;
}