Consistently strict parsing of date overflows (using java.time's strict resolution style)
Issue: SPR-13567
This commit is contained in:
parent
028a690100
commit
7b1fcfc7c3
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -75,6 +75,12 @@ public @interface DateTimeFormat {
|
|||
* <p>Defaults to empty String, indicating no custom pattern String has been specified.
|
||||
* Set this attribute when you wish to format your field in accordance with a custom
|
||||
* date time pattern not represented by a style or ISO format.
|
||||
* <p>Note: This pattern follows the original {@link java.text.SimpleDateFormat} style,
|
||||
* as also supported by Joda-Time, with strict parsing semantics towards overflows
|
||||
* (e.g. rejecting a Feb 29 value for a non-leap-year). As a consequence, 'yy'
|
||||
* characters indicate a year in the traditional style, not a "year-of-era" as in the
|
||||
* {@link java.time.format.DateTimeFormatter} specification (i.e. 'yy' turns into 'uu'
|
||||
* when going through that {@code DateTimeFormatter} with strict resolution mode).
|
||||
*/
|
||||
String pattern() default "";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.format.datetime.standard;
|
|||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.time.format.ResolverStyle;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
||||
|
|
@ -174,7 +175,11 @@ public class DateTimeFormatterFactory {
|
|||
public DateTimeFormatter createDateTimeFormatter(DateTimeFormatter fallbackFormatter) {
|
||||
DateTimeFormatter dateTimeFormatter = null;
|
||||
if (StringUtils.hasLength(this.pattern)) {
|
||||
dateTimeFormatter = DateTimeFormatter.ofPattern(this.pattern);
|
||||
// Using strict parsing to align with Joda-Time and standard DateFormat behavior:
|
||||
// otherwise, an overflow like e.g. Feb 29 for a non-leap-year wouldn't get rejected.
|
||||
// However, with strict parsing, a year digit needs to be specified as 'u'...
|
||||
String patternToUse = this.pattern.replace("yy", "uu");
|
||||
dateTimeFormatter = DateTimeFormatter.ofPattern(patternToUse).withResolverStyle(ResolverStyle.STRICT);
|
||||
}
|
||||
else if (this.iso != null && this.iso != ISO.NONE) {
|
||||
switch (this.iso) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -148,6 +148,14 @@ public class DateFormattingTests {
|
|||
assertEquals("10/31/09 1:05", binder.getBindingResult().getFieldValue("dateAnnotatedPattern"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindDateTimeOverflow() {
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
propertyValues.add("dateAnnotatedPattern", "02/29/09 12:00 PM");
|
||||
binder.bind(propertyValues);
|
||||
assertEquals(1, binder.getBindingResult().getErrorCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindISODate() {
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -317,6 +317,14 @@ public class JodaTimeFormattingTests {
|
|||
assertEquals("10/31/09 12:00 PM", binder.getBindingResult().getFieldValue("dateTimeAnnotatedPattern"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindDateTimeOverflow() {
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
propertyValues.add("dateTimeAnnotatedPattern", "02/29/09 12:00 PM");
|
||||
binder.bind(propertyValues);
|
||||
assertEquals(1, binder.getBindingResult().getErrorCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindDateTimeAnnotatedDefault() {
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -292,6 +292,14 @@ public class DateTimeFormattingTests {
|
|||
assertEquals("10/31/09 12:00 PM", binder.getBindingResult().getFieldValue("dateTimeAnnotatedPattern"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindDateTimeOverflow() {
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
propertyValues.add("dateTimeAnnotatedPattern", "02/29/09 12:00 PM");
|
||||
binder.bind(propertyValues);
|
||||
assertEquals(1, binder.getBindingResult().getErrorCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindISODate() {
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
|
|
|
|||
Loading…
Reference in New Issue