在String转Timestamp时,可调用Timestamp.valueOf(dateStr),可能会遇到下面这种异常,java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]。今天就遇到了这种问题,于是去翻翻源码。抛出该异常,可以有好几处:
1、dataStr 日期和时间之间需要空格隔开
dividingSpace = s.indexOf(' ');
if (dividingSpace > 0) {
date_s = s.substring(0,dividingSpace);
time_s = s.substring(dividingSpace+1);
} else {
throw new java.lang.IllegalArgumentException(formatError);
}
2、转换日期时,检验日期的年月日长度和范围,要求年要等于四位(yyyy),月要大于等于1位并且小于等于两位而且小于等于12(MM),日要大于等于1位并且小于等于两位而且小于等于31(dd)
// Convert the date
boolean parsedDate = false;
if ((firstDash > 0) && (secondDash > 0) && (secondDash < date_s.length() - 1)) {
String yyyy = date_s.substring(0, firstDash);
String mm = date_s.substring(firstDash + 1, secondDash);
String dd = date_s.substring(secondDash + 1);
if (yyyy.length() == YEAR_LENGTH &&
(mm.length() >= 1 && mm.length() <= MONTH_LENGTH) &&
(dd.length() >= 1 && dd.length() <= DAY_LENGTH)) {
year = Integer.parseInt(yyyy);
month = Integer.parseInt(mm);
day = Integer.parseInt(dd);
if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
parsedDate = true;
}
}
}
if (! parsedDate) {
throw new java.lang.IllegalArgumentException(formatError);
}
3、在转换时间,也是如此。
// Convert the time; default missing nanos
if ((firstColon > 0) & (secondColon > 0) &
(secondColon < time_s.length()-1)) {
hour = Integer.parseInt(time_s.substring(0, firstColon));
minute =
Integer.parseInt(time_s.substring(firstColon+1, secondColon));
if ((period > 0) & (period < time_s.length()-1)) {
second =
Integer.parseInt(time_s.substring(secondColon+1, period));
nanos_s = time_s.substring(period+1);
if (nanos_s.length() > 9)
throw new java.lang.IllegalArgumentException(formatError);
if (!Character.isDigit(nanos_s.charAt(0)))
throw new java.lang.IllegalArgumentException(formatError);
nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
a_nanos = Integer.parseInt(nanos_s);
} else if (period > 0) {
throw new java.lang.IllegalArgumentException(formatError);
} else {
second = Integer.parseInt(time_s.substring(secondColon+1));
}
} else {
throw new java.lang.IllegalArgumentException(formatError);
}
针对这些检验规则,所以我们写入字符格式的日期时,就要注意了。
异常原因详解:
另外,其实我的问题是异常抛出来
<span style="white-space:pre"> </span>String createDate=new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(new Date());
Timestamp timestamp = Timestamp.valueOf(createDate);
System.out.println(timestamp);
对照了异常说明的格式:java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]。发现SimpleDateFormat里似乎是没有错啊。其实这里是真的写错了,正确的写法是yyyy-MM-dd hh:mm:ss 或者 yyyy-MM-dd HH:mm:ss ,也就是说月份的格式mm必须是大写的,如果是小写,那么月份将获取到的是分钟数,分钟数可能大于12,那么很明显,根据检验规则,一定会抛异常。另外一个问题,按这种形式获取时间戳时,小时的格式应该使用大写HH,HH表示24小时制,hh表示12小时制,使用hh时间会不准确,因此推荐使用的格式是:yyyy-MM-dd HH:mm:ss。
下面是示例:
yyyy-mm-dd
HH:mm:ss格式
yyyy-MM-dd
HH:mm:ss格式