Java 日期验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7332268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:33:30  来源:igfitidea点击:

Java Date validation

javadate

提问by sn s

i need to validate user input as valid date. User can enter dd/mm/yyyy or mm/yyyy (both are valid)

我需要将用户输入验证为有效日期。用户可以输入 dd/mm/yyyy 或 mm/yyyy(两者都有效)

to validate this i was doing

为了验证这一点,我正在做

try{
    GregorianCalendar cal = new GregorianCalendar(); 
    cal.setLenient(false);  
    String []userDate = uDate.split("/");
    if(userDate.length == 3){
        cal.set(Calendar.YEAR, Integer.parseInt(userDate[2]));  
        cal.set(Calendar.MONTH, Integer.parseInt(userDate[1]));  
        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(userDate[0]));
        cal.getTime(); 
    }else if(userDate.length == 2){
        cal.set(Calendar.YEAR, Integer.parseInt(userDate[1]));  
        cal.set(Calendar.MONTH, Integer.parseInt(userDate[0]));  
        cal.getTime(); 
    }else{
            // invalid date
    }
}catch(Exception e){
    //Invalid date
}

as GregorianCalendar start month with 0, 30/01/2009 or 12/2009 gives error.

因为 GregorianCalendar 以 0、30/01/2009 或 12/2009 开始的月份给出了错误。

any suggestion how to solve this issue.

如何解决这个问题的任何建议。

回答by dacwe

Use SimpleDateformat. If the parsing failes it throws a ParseException:

使用SimpleDateformat. 如果解析失败,它会抛出一个ParseException

private Date getDate(String text) throws java.text.ParseException {

    try {
        // try the day format first
        SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        df.setLenient(false);

        return df.parse(text);
    } catch (ParseException e) {

        // fall back on the month format
        SimpleDateFormat df = new SimpleDateFormat("MM/yyyy");
        df.setLenient(false);

        return df.parse(text);
    }
}

回答by Jigar Joshi

Use SimpleDateFormatto validate Dateand setLenientto false.

使用SimpleDateFormat来验证DatesetLenientfalse

回答by Basil Bourque

tl;dr

tl;博士

Use a try - catchto trap DateTimeParseExceptionthrown from LocalDate.parseand YearMonth.parsein the java.timeclasses.

使用 atry - catch来捕获DateTimeParseExceptionjava.timeLocalDate.parseYearMonth.parsejava.time类中抛出的陷阱。

java.time

时间

The modern approach uses the java.timeclasses.

现代方法使用java.time类。

YearMonth

YearMonth

For only a year-month without a day-of-month, use the YearMonthclass.

对于没有月份的年月,请使用YearMonth该类。

If possible, have your users use standard ISO 8601format for data entry: YYYY-MM. The java.timeclasses use the standard formats by default when parsing/generating strings.

如果可能,让您的用户使用标准ISO 8601格式进行数据输入:YYYY-MM. 所述java.time类解析/生成字符串时默认使用的标准格式。

YearMonth ym = YearMonth.parse( "2018-01" ) ;

If not possible, specify a formatting pattern.

如果不可能,请指定格式模式。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ;
YearMonth ym = YearMonth.parse( "01/2018" , f ) ;

To test for invalid input, trap for an exception.

要测试无效输入,请捕获异常。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ;
YearMonth ym = null ;
try{
    ym = YearMonth.parse( "01/2018" , f ) ;
} catch ( DateTimeParseException e ) {
    // Handle faulty input
    …
}

LocalDate

LocalDate

For a date-only value, without a time-of-day and without a time zone, use LocalDateclass.

对于仅限日期的值,没有时间和时区,请使用LocalDateclass。

Again, use standard ISO 8601 format for data-entry if possible: YYYY-MM-DD.

同样,使用标准的ISO 8601格式的数据录入如果可能的话:YYYY-MM-DD

LocalDate ld = LocalDate.parse( "2018-01-23" ) ;

If not, specify a formatting pattern and trap for exception as seen above.

如果没有,请指定格式模式和异常陷阱,如上所示。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = null ;
try{
    ld = LocalDate.parse( "23/01/2018" , f ) ;
} catch ( DateTimeParseException e ) {
    // Handle faulty input
    …
}

Combining

结合

If the input may be either a date-only or a year-month, then test the length of input to determine which is which.

如果输入可能是仅日期或年月,则测试输入的长度以确定哪个是哪个。

int length = input.length() ;
switch ( length ) {
    case 7 :
        …  // Process as year-month using code seen above.

    case 10 :
        …  // Process as date-only using code seen above.

    default: 
        …  // ERROR, unexpected input.
}


About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*classes.

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多