Skip to content

Commit dda8db0

Browse files
improve date binding with @BindingFormat
Because SimpleDateFormat defaults to lenient=true, when binding to a Date that is marked with @BindingFormat, bogus values result if the supplied date doesn’t match format specified in @BindingFormat. This change makes the formatter be not lenient so a binding error will now result. Fixes #9667
1 parent a03bfd4 commit dda8db0

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

grails-databinding/src/main/groovy/org/grails/databinding/converters/FormattedDateValueConverter.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ class FormattedDateValueConverter implements FormattedValueConverter {
3030
if(value instanceof Date) {
3131
return value
3232
}
33-
new SimpleDateFormat(format).parse((String)value)
33+
def fmt = new SimpleDateFormat(format)
34+
fmt.lenient = false
35+
fmt.parse((String) value)
3436
}
3537

3638
Class<?> getTargetType() {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package grails.databinding
2+
3+
import grails.databinding.errors.BindingError
4+
import grails.databinding.events.DataBindingListenerAdapter
5+
import spock.lang.Specification
6+
7+
import java.text.ParseException
8+
9+
class BindingFormatSpec extends Specification {
10+
11+
void 'bind to a date'() {
12+
given:
13+
def binder = new SimpleDataBinder()
14+
def obj = new SomeWidget()
15+
def listener = new DateBindingListener()
16+
17+
when:
18+
binder.bind obj, [birthDate: '11/15/1969'] as SimpleMapDataBindingSource, listener
19+
def cal = Calendar.getInstance()
20+
cal.time = obj.birthDate
21+
22+
then:
23+
!listener.bindingErrors
24+
cal.get(Calendar.MONTH) == Calendar.NOVEMBER
25+
cal.get(Calendar.YEAR) == 1969
26+
cal.get(Calendar.DATE) == 15
27+
28+
when:
29+
obj = new SomeWidget()
30+
binder.bind obj, [birthDate: '1969/11/15'] as SimpleMapDataBindingSource, listener
31+
32+
then:
33+
!obj.birthDate
34+
listener.bindingErrors
35+
listener.bindingErrors.size() == 1
36+
37+
when:
38+
def error = listener.bindingErrors[0]
39+
40+
then:
41+
error.rejectedValue == '1969/11/15'
42+
error.propertyName == 'birthDate'
43+
error.cause instanceof ParseException
44+
error.cause.message == 'Unparseable date: "1969/11/15"'
45+
}
46+
}
47+
48+
class SomeWidget {
49+
@BindingFormat('MM/dd/yyyy')
50+
Date birthDate
51+
}
52+
53+
class DateBindingListener extends DataBindingListenerAdapter {
54+
55+
def bindingErrors = []
56+
57+
void bindingError(BindingError error, errors) {
58+
bindingErrors << error
59+
}
60+
}

0 commit comments

Comments
 (0)