diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java index 5a832d9789..f840baad79 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -21,10 +21,12 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Month; import java.time.MonthDay; import java.time.OffsetDateTime; import java.time.OffsetTime; import java.time.Period; +import java.time.Year; import java.time.YearMonth; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -190,6 +192,8 @@ public class DateTimeFormatterRegistrar implements FormatterRegistrar { registry.addFormatterForFieldType(Instant.class, new InstantFormatter()); registry.addFormatterForFieldType(Period.class, new PeriodFormatter()); registry.addFormatterForFieldType(Duration.class, new DurationFormatter()); + registry.addFormatterForFieldType(Year.class, new YearFormatter()); + registry.addFormatterForFieldType(Month.class, new MonthFormatter()); registry.addFormatterForFieldType(YearMonth.class, new YearMonthFormatter()); registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter()); diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/MonthFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/MonthFormatter.java new file mode 100644 index 0000000000..4b7fa7f836 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/MonthFormatter.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.format.datetime.standard; + +import java.text.ParseException; +import java.time.Month; +import java.util.Locale; + +import org.springframework.format.Formatter; + +/** + * {@link Formatter} implementation for a JSR-310 {@link Month}, + * resolving a given String against the Month enum values (ignoring case). + * + * @author Juergen Hoeller + * @since 5.0.4 + * @see Month#valueOf + */ +class MonthFormatter implements Formatter { + + @Override + public Month parse(String text, Locale locale) throws ParseException { + return Month.valueOf(text.toUpperCase()); + } + + @Override + public String print(Month object, Locale locale) { + return object.toString(); + } + +} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/YearFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/YearFormatter.java new file mode 100644 index 0000000000..ebd24f6bbe --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/YearFormatter.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2018 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.format.datetime.standard; + +import java.text.ParseException; +import java.time.Year; +import java.util.Locale; + +import org.springframework.format.Formatter; + +/** + * {@link Formatter} implementation for a JSR-310 {@link Year}, + * following JSR-310's parsing rules for a Year. + * + * @author Juergen Hoeller + * @since 5.0.4 + * @see Year#parse + */ +class YearFormatter implements Formatter { + + @Override + public Year parse(String text, Locale locale) throws ParseException { + return Year.parse(text); + } + + @Override + public String print(Year object, Locale locale) { + return object.toString(); + } + +} diff --git a/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java b/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java index 75e6515a69..bfc444b964 100644 --- a/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java +++ b/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java @@ -21,8 +21,10 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Month; import java.time.MonthDay; import java.time.Period; +import java.time.Year; import java.time.YearMonth; import java.time.ZoneId; import java.time.format.DateTimeFormatter; @@ -60,12 +62,12 @@ public class DateTimeFormattingTests { @Before - public void setUp() { + public void setup() { DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); - setUp(registrar); + setup(registrar); } - private void setUp(DateTimeFormatterRegistrar registrar) { + private void setup(DateTimeFormatterRegistrar registrar) { conversionService = new FormattingConversionService(); DefaultConversionService.addDefaultConverters(conversionService); registrar.registerFormatters(conversionService); @@ -82,7 +84,7 @@ public class DateTimeFormattingTests { } @After - public void tearDown() { + public void cleanup() { LocaleContextHolder.setLocale(null); DateTimeContextHolder.setDateTimeContext(null); } @@ -98,10 +100,10 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalDateWithSpecificStyle() throws Exception { + public void testBindLocalDateWithSpecificStyle() { DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setDateStyle(FormatStyle.LONG); - setUp(registrar); + setup(registrar); MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localDate", "October 31, 2009"); binder.bind(propertyValues); @@ -110,10 +112,10 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalDateWithSpecificFormatter() throws Exception { + public void testBindLocalDateWithSpecificFormatter() { DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd")); - setUp(registrar); + setup(registrar); MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localDate", "20091031"); binder.bind(propertyValues); @@ -177,7 +179,7 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalDateFromJavaUtilCalendar() throws Exception { + public void testBindLocalDateFromJavaUtilCalendar() { MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localDate", new GregorianCalendar(2009, 9, 31, 0, 0)); binder.bind(propertyValues); @@ -195,10 +197,10 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalTimeWithSpecificStyle() throws Exception { + public void testBindLocalTimeWithSpecificStyle() { DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setTimeStyle(FormatStyle.MEDIUM); - setUp(registrar); + setup(registrar); MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localTime", "12:00:00 PM"); binder.bind(propertyValues); @@ -207,10 +209,10 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalTimeWithSpecificFormatter() throws Exception { + public void testBindLocalTimeWithSpecificFormatter() { DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setTimeFormatter(DateTimeFormatter.ofPattern("HHmmss")); - setUp(registrar); + setup(registrar); MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localTime", "130000"); binder.bind(propertyValues); @@ -228,7 +230,7 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalTimeFromJavaUtilCalendar() throws Exception { + public void testBindLocalTimeFromJavaUtilCalendar() { MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localTime", new GregorianCalendar(1970, 0, 0, 12, 0)); binder.bind(propertyValues); @@ -259,7 +261,7 @@ public class DateTimeFormattingTests { } @Test - public void testBindLocalDateTimeFromJavaUtilCalendar() throws Exception { + public void testBindLocalDateTimeFromJavaUtilCalendar() { MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localDateTime", new GregorianCalendar(2009, 9, 31, 12, 0)); binder.bind(propertyValues); @@ -270,10 +272,10 @@ public class DateTimeFormattingTests { } @Test - public void testBindDateTimeWithSpecificStyle() throws Exception { + public void testBindDateTimeWithSpecificStyle() { DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setDateTimeStyle(FormatStyle.MEDIUM); - setUp(registrar); + setup(registrar); MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("localDateTime", LocalDateTime.of(2009, 10, 31, 12, 0)); binder.bind(propertyValues); @@ -356,7 +358,7 @@ public class DateTimeFormattingTests { @Test @SuppressWarnings("deprecation") - public void testBindInstantFromJavaUtilDate() throws Exception { + public void testBindInstantFromJavaUtilDate() { MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("instant", new Date(109, 9, 31, 12, 0)); binder.bind(propertyValues); @@ -382,6 +384,33 @@ public class DateTimeFormattingTests { assertTrue(binder.getBindingResult().getFieldValue("duration").toString().equals("PT8H6M12.345S")); } + @Test + public void testBindYear() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("year", "2007"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("year").toString().equals("2007")); + } + + @Test + public void testBindMonth() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("month", "JULY"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("month").toString().equals("JULY")); + } + + @Test + public void testBindMonthInAnyCase() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("month", "July"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("month").toString().equals("JULY")); + } + @Test public void testBindYearMonth() { MutablePropertyValues propertyValues = new MutablePropertyValues(); @@ -436,6 +465,10 @@ public class DateTimeFormattingTests { private Duration duration; + private Year year; + + private Month month; + private YearMonth yearMonth; private MonthDay monthDay; @@ -546,6 +579,22 @@ public class DateTimeFormattingTests { this.duration = duration; } + public Year getYear() { + return year; + } + + public void setYear(Year year) { + this.year = year; + } + + public Month getMonth() { + return month; + } + + public void setMonth(Month month) { + this.month = month; + } + public YearMonth getYearMonth() { return yearMonth; }