Java中pickupdate加3天存expirydate时错误基于系统当前日期计算
问题原因
问题出在异常分支的逻辑漏洞:
Calendar c = Calendar.getInstance()执行时,Calendar对象默认初始化为系统当前时间- 当
sdf.parse(pickupdate)解析用户输入日期失败、抛出ParseException时,代码仅打印异常栈信息,没有中断后续流程,也没有修改Calendar对象的状态,此时c仍然持有初始化时的系统当前时间 - 后续执行
c.add(Calendar.DAY_OF_MONTH, 3)时,操作的就是默认的当前时间,最终计算结果自然是当前日期加3天,和用户输入无关 - 触发解析失败的常见场景:用户输入的日期格式和代码定义的
MM-dd-yyyy不匹配、输入内容为空、输入了非法日期值(如13月、0月、超过当月上限的日期),另外SimpleDateFormat默认是宽松解析模式,部分格式偏差的输入可能被自动纠正为其他日期,也会导致计算不符合预期。
修复方案
- 禁止吞掉解析异常:日期解析失败时必须终止后续计算逻辑,同时给用户明确的格式错误提示,不能带着Calendar的默认初始值继续执行
- 给
SimpleDateFormat开启严格校验模式,关闭宽松解析,避免非法输入被自动转换为不符合预期的日期 - 若项目使用Java 8及以上版本,优先替换为
java.time包下的标准日期API,从设计上规避老旧日期类的线程不安全、容错逻辑差的问题
修复代码示例
兼容旧Java版本的写法
String pickupdate = pdate.getText().toString().trim(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy"); // 开启严格日期校验,禁止自动转换非法日期 sdf.setLenient(false); String expirydate; Calendar c = Calendar.getInstance(); try { c.setTime(sdf.parse(pickupdate)); c.add(Calendar.DAY_OF_MONTH, 3); expirydate = sdf.format(c.getTime()); } catch (ParseException e) { e.printStackTrace(); expirydate = ""; // 此处添加用户提示逻辑,例如提醒用户按照MM-dd-yyyy格式输入有效日期 }
Java 8+ 推荐写法(使用java.time现代API)
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; // 业务逻辑部分 String pickupdate = pdate.getText().toString().trim(); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-yyyy"); String expirydate; try { LocalDate pickDate = LocalDate.parse(pickupdate, dtf); LocalDate expiryDate = pickDate.plusDays(3); expirydate = expiryDate.format(dtf); } catch (DateTimeParseException e) { e.printStackTrace(); expirydate = ""; // 此处添加用户输入错误提示逻辑 }
内容的提问来源于stack exchange,提问作者Shahzad Ali
相关产品推荐
相关产品推荐

