解析字符串1899-12-30时遇MysqlDataTruncation异常的解决咨询
问题根源纠正
你看到的.0(Timestamp的毫秒部分)并不是触发MysqlDataTruncation异常的原因,真正问题在于:
MySQL的DATE类型支持的日期范围是1000-01-01至9999-12-31,而你要插入的1899-12-30早于该范围最小值,超出了字段合法存储区间,因此抛出截断异常。如果是TIMESTAMP类型,其范围更窄(1970-01-01至2038-01-19),同样无法存储1899年的日期。
具体解决方案
方案1:修改数据库字段类型(需存储早于1000年的日期)
MySQL标准日期类型无法容纳1000年之前的日期,你可以选择两种替代方案:
- 将字段改为
VARCHAR类型,直接存储日期字符串(如1899-12-30),业务查询时再解析为日期对象使用。 - 将字段改为
BIGINT类型,存储日期对应的时间戳(1899年的时间戳为负数,BIGINT可正常容纳),读取时再转回日期对象。
方案2:调整代码逻辑(限制日期在MySQL支持范围内)
如果业务允许限制日期范围,可在代码中增加日期合法性校验,提前拦截超出范围的日期:
public Timestamp convertFromDate(String fromDate) throws ParseException { String[] possibleFormats = { "dd/MM/yyyy", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; ParseException lastException = null; for (String format : possibleFormats) { try { SimpleDateFormat dateFormat = new SimpleDateFormat(format); dateFormat.setLenient(false); Date parsedDate = dateFormat.parse(fromDate); // 校验日期是否在MySQL DATE类型支持的最小范围之后 Calendar minValidDate = Calendar.getInstance(); minValidDate.set(1000, Calendar.JANUARY, 1); if (parsedDate.before(minValidDate.getTime())) { throw new ParseException("日期早于系统支持的最小值:1000-01-01", 0); } return new Timestamp(parsedDate.getTime()); } catch (ParseException e) { lastException = e; } } throw lastException; }
额外说明
如果你的数据库字段是DATETIME/TIMESTAMP类型,JDBC驱动会自动处理Timestamp的毫秒部分,即使toString()显示.0,插入时也会被转换为数据库支持的格式,不会触发截断异常,因此不需要特意去掉毫秒部分。
内容的提问来源于stack exchange,提问作者Ibrahim Alvi
相关产品推荐
相关产品推荐

