2月29日的SimpleDateFormat分析日期错误
我已经连接好了
public static boolean isFirstDayOfMonth(String format, String value) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date date = null;
try {
date = sdf.parse(value);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
return dayOfMonth == 1;
}
测试并返回True:
boolean actual = CommonUtil.isFirstDayOfMonth("yyyy-MM-dd", "2021-02-29");
assertTrue(actual);
I Found Out SimpleDateFormat将日期转换为2021年3月1日,尽管2021年没有2月29日。如果我在2021-02-30中通过,这是无效的,但它返回正确的结果。
解决方案
tl;dr
java.time.LocalDate.parse( "2021-02-29" )
…
catch ( DateTimeParseException e ) // Thrown for invalid inputs
java.time
您正在使用几年前被JSR 310中定义的java.time类取代的可怕的日期-时间类。
默认情况下,java.time.LocalDate
类拒绝解析无效输入。分析异常的陷阱。
try {
LocalDate ld = LocalDate.parse( "2021-02-29" ) ;
System.out.println( ld ) ;
} catch ( DateTimeParseException e ) {
// … handle invalid input
System.out.println( "Faulty input" ) ;
}
查看此code run live at IdeOne.com。
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期-时间类,如java.util.Date
、Calendar
、&;SimpleDateFormat
。
要了解更多信息,请参阅Oracle Tutorial。和搜索堆栈溢出以获取许多示例和解释。规范为JSR 310。
Joda-Time项目现在位于maintenance mode中,建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC driver。不需要字符串,也不需要java.sql.*
类。Hibernate 5&;JPA 2.2支持java.time。
从哪里获取java.time类?
- Java SE 8、Java SE 9、Java SE 10、Java SE 11以及更高版本--标准Java API的一部分,具有捆绑实现。
- Java 9带来了一些次要功能和修复。
- Java SE 6和Java SE 7
- 大部分java.time功能已后移植到ThreeTen-Backport中的Java 6&;7。
- Android
- 更高版本的Android(26+)捆绑了java.time类的实现。
- 对于更早的Android(<;26),API desugaring的进程带来了Android最初没有内置的subset of the java.time功能。
- 如果去糖化不能满足您的需求,ThreeTenABP工程会将ThreeTen-Backport(上面提到的)适配到Android。请参见How to use ThreeTenABP…。
相关文章