Reputation: 3
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:
DateOfAdding = datumTextField.getText();
so the DateOfAddig value is 1.10.
How to turm the magican off?
Upvotes: 0
Views: 89
Reputation: 339043
MonthDay.parse(
"12.31" ,
DateTimeFormatter.ofPattern( "MM.dd" )
)
Catch DateTimeParseException
for invalid input.
java.time.MonthDay
The modern approach uses the java.time classes rather than the troublesome legacy classes seen in the Question.
Among the java.time classes is MonthDay
, just what you need.
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. If so I suggest you and your user use standard ISO 8601 format: --MM-DD
.
MonthDay md = MonthDay.parse( "--12-31" ) ;
Or define a pattern using DateTimeFormatter
.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM.dd" ) ;
MonthDay md = MonthDay.parse( input , f ) ;
Trap for DateTimeParseException
to detect invalid inputs.
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.
Invalid input: 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
md.toString(): null
Upvotes: 1
Reputation: 24802
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.
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.
From the Calendar
's 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. For example, a lenient GregorianCalendar interprets MONTH == JANUARY, DAY_OF_MONTH == 32 as February 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. 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.
Upvotes: 0