我正在使用一个日期应用程序,用户将在其中输入日期并验证该日期。日期格式为dd/MM/yyyy
。这是我的代码
import java.util.*;
import java.text.SimpleDateFormat;
import java.text.ParseException;
public class HelloWorld {
public static void main(String[] args) {
//Scanner sc = new Scanner(System.in);
String dat = "02/1/2018";
try {
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setLenient(false);
df.parse(dat);
System.out.print("valid");
} catch (ParseException e) {
System.out.print("invalid");
}
}
}
这很完美,可以验证我的日期,但是当我输入22/02/2-19
之类的日期时也同样有效。但这应该是无效的,因为我的年份是2-19
。
答案 0 :(得分:2)
您使用的是可怕的旧日期时间类,而这些类早已被 java.time 类所取代。
对于仅日期值,请使用仅日期类:LocalDate
。
使用DateTimeFormatter
类定义格式设置模式。搜索堆栈溢出以获取更多讨论和示例,因为已经讨论了很多次。
解析时,陷阱DateTimeParseException
以确定是否无效。
String input = "22/02/2-19";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = null;
try {
ld = LocalDate.parse( input , f );
System.out.println( "VALID: " + ld.toString() );
} catch ( DateTimeParseException e ) {
System.out.println( "INVALID: " + input );
e.printStackTrace();
}
无效:22/02 / 2-19
java.time.format.DateTimeParseException:无法在索引6处解析文本“ 22/02 / 2-19”……
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:1)
根据SimpleDateFormat
的{{3}}:
对于解析,如果模式字母的数量大于2,则将按字面意义解释年份,而不考虑位数。因此,使用模式“ MM / dd / yyyy”,“ 01/11/12”解析为公元1月11日
这就是为什么输入22/02/2-19
不会引发解析异常的原因。它以2作为年份,而忽略其余部分。
答案 2 :(得分:0)
Basil Bourque’s excellent answer已经为您的问题提供了最佳解决方案。我不再重复。如果使用该答案,您希望像第一个示例02/1/2018
一样接受1位数的月份,则应在格式模式字符串中仅给出一个M
。然后1
和01
都将被接受。同样,一个d
会在一个月的某天接受2
和02
。
SimpleDateFormat
从字符串中读取尽可能多的字符以匹配格式模式,但很高兴不阅读所有内容。在第二个示例22/02/2-19
中,它将22/02/2
解析为周一1月2日00:00:00 CET 2的Date
(具体结果取决于您的时区), 2016年前由于这是一个有效日期,因此不会引发任何异常。然后,它将忽略字符串的最后三个字符。