简体   繁体   English

Java 8格式化日期输入

[英]Java 8 formatted date input

I use this code to format a formatted text field to enter month & day: 我使用以下代码来格式化带格式的文本字段,以输入月份和日期:

SimpleDateFormat sdf = new SimpleDateFormat("MM.dd");
DateFormatter df = new DateFormatter(sdf);
DefaultFormatterFactory ddf = new DefaultFormatterFactory(df, df, df, df);
datumTextField.setValue(new Date(System.currentTimeMillis()));
datumTextField.setFormatterFactory(ddf);

When an invalid date is entered, eg. 输入无效日期时,例如。 13.10, a magican changes it to 1.10 after this line: 13.10,在此行之后,魔术师将其更改为1.10:

DateOfAdding = datumTextField.getText();

so the DateOfAddig value is 1.10. 因此DateOfAddig值为1.10。

How to turm the magican off? 如何关闭魔术师?

tl;dr TL;博士

MonthDay.parse( 
    "12.31" , 
     DateTimeFormatter.ofPattern( "MM.dd" ) 
)

Catch DateTimeParseException for invalid input. 捕获DateTimeParseException以获取无效输入。

java.time.MonthDay

The modern approach uses the java.time classes rather than the troublesome legacy classes seen in the Question. 现代方法使用java.time类,而不是Question中看到的麻烦的旧类。

Among the java.time classes is MonthDay , just what you need. 在java.time类中有MonthDay ,正是您所需要的。

I suggest collecting input as two different numbers. 我建议将输入收集为两个不同的数字。

MonthDay md = MonthDay.of( x , y ) ;

If you insist, you can collect input as a combined string and parse . 如果您坚持,则可以将输入收集为组合的字符串和parse If so I suggest you and your user use standard ISO 8601 format: --MM-DD . 如果是这样,我建议您和您的用户使用标准的ISO 8601格式:-- --MM-DD

MonthDay md = MonthDay.parse( "--12-31" ) ;

Or define a pattern using DateTimeFormatter . 或使用DateTimeFormatter定义模式。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM.dd" ) ;
MonthDay md = MonthDay.parse( input , f ) ;

Trap for DateTimeParseException to detect invalid inputs. 捕获DateTimeParseException以检测无效输入。

String input = "13.10" ;  // Invalid input. Month must be 1-12.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM.dd" ) ;
MonthDay md = null ;
try 
{
    md = MonthDay.parse( input , f ) ;
} catch ( DateTimeParseException e ) { 
    // … handle error …
    System.out.println( "Invalid input: " + input ) ;
} 

See this code run live at IdeOne.com . 看到此代码在IdeOne.com上实时运行

Invalid input: 13.10 无效的输入:13.10

e: java.time.format.DateTimeParseException: Text '13.10' could not be parsed: Unable to obtain MonthDay from TemporalAccessor: {MonthOfYear=13, DayOfMonth=10},ISO of type java.time.format.Parsed e:java.time.format.DateTimeParseException:无法解析文本“ 13.10”:无法从TemporalAccessor获取MonthDay:{MonthOfYear = 13,DayOfMonth = 10},类型为java.time.format.Parsed的ISO

md.toString(): null md.toString():空

You will want to call the SimpleDateFormat 's setLenient method with false as a parameter so that the underlying Calendar used for parsing is set to non-lenient. 您将需要使用false作为参数调用SimpleDateFormatsetLenient方法,以便将用于解析的基础Calendar设置为非宽大。

A non-lenient calendar will refuse field values that aren't in the expected range for this field, rather than accepting them and modifying other fields to make sense of them : in your case the month was rolled-over 12 and reached 1, while the year was increased by 1 and probably reached 1971 rather than the default-when-unspecified 1970. 非宽容日历将拒绝不在此字段的预期范围内的字段值,而不是接受它们并修改其他字段以使其有意义:在您的情况下,该月已滚存12并达到1,而该年份增加了1,可能达到了1971年,而不是未指定时的默认1970年。

From the Calendar 's javadoc : Calendar的javadoc中

Leniency 宽大

Calendar has two modes for interpreting the calendar fields, lenient and non-lenient. 日历具有两种解释日历字段的模式:宽松和不宽松。 When a Calendar is in lenient mode, it accepts a wider range of calendar field values than it produces. 日历处于宽松模式时,它接受的日历字段值范围比生成的范围大。 When a Calendar recomputes calendar field values for return by get(), all of the calendar fields are normalized. 当Calendar重新计算日历字段值以通过get()返回时,所有日历字段都将被标准化。 For example, a lenient GregorianCalendar interprets MONTH == JANUARY, DAY_OF_MONTH == 32 as February 1. 例如,宽大的GregorianCalendar将MONTH == JANUARY,DAY_OF_MONTH == 32解释为2月1日。

When a Calendar is in non-lenient mode, it throws an exception if there is any inconsistency in its calendar fields. 当日历处于非宽松模式时,如果其日历字段中存在任何不一致,它将引发异常。 For example, a GregorianCalendar always produces DAY_OF_MONTH values between 1 and the length of the month. 例如,一个GregorianCalendar总是产生介于1和月份长度之间的DAY_OF_MONTH值。 A non-lenient GregorianCalendar throws an exception upon calculating its time or calendar field values if any out-of-range field value has been set. 如果设置了任何超出范围的值,则非宽松的GregorianCalendar会在计算其时间或日历字段值时引发异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM