diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java index 19e5cd0c3b..63b8e4d838 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java @@ -26,8 +26,10 @@ import org.joda.time.Duration; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; +import org.joda.time.MonthDay; import org.joda.time.Period; import org.joda.time.ReadableInstant; +import org.joda.time.YearMonth; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; @@ -56,7 +58,7 @@ import org.springframework.format.annotation.DateTimeFormat.ISO; */ public class JodaTimeFormatterRegistrar implements FormatterRegistrar { - private static enum Type {DATE, TIME, DATE_TIME} + private enum Type {DATE, TIME, DATE_TIME} /** @@ -198,6 +200,8 @@ public class JodaTimeFormatterRegistrar implements FormatterRegistrar { registry.addFormatterForFieldType(Period.class, new PeriodFormatter()); registry.addFormatterForFieldType(Duration.class, new DurationFormatter()); + registry.addFormatterForFieldType(YearMonth.class, new YearMonthFormatter()); + registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter()); registry.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory()); } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java new file mode 100644 index 0000000000..b1e3e9560a --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/MonthDayFormatter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2015 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.joda; + +import java.text.ParseException; +import java.util.Locale; + +import org.joda.time.MonthDay; + +import org.springframework.format.Formatter; + +/** + * {@link Formatter} implementation for a Joda-Time {@link MonthDay}, + * following Joda-Time's parsing rules for a MonthDay. + * + * @author Juergen Hoeller + * @since 4.2.4 + * @see MonthDay#parse + */ +public class MonthDayFormatter implements Formatter { + + @Override + public MonthDay parse(String text, Locale locale) throws ParseException { + return MonthDay.parse(text); + } + + @Override + public String print(MonthDay object, Locale locale) { + return object.toString(); + } + +} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java new file mode 100644 index 0000000000..7d94e53f23 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/YearMonthFormatter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2015 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.joda; + +import java.text.ParseException; +import java.util.Locale; + +import org.joda.time.YearMonth; + +import org.springframework.format.Formatter; + +/** + * {@link Formatter} implementation for a Joda-Time {@link YearMonth}, + * following Joda-Time's parsing rules for a YearMonth. + * + * @author Juergen Hoeller + * @since 4.2.4 + * @see YearMonth#parse + */ +public class YearMonthFormatter implements Formatter { + + @Override + public YearMonth parse(String text, Locale locale) throws ParseException { + return YearMonth.parse(text); + } + + @Override + public String print(YearMonth object, Locale locale) { + return object.toString(); + } + +} 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 9de51d10ca..07a65cc960 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 @@ -21,9 +21,11 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.MonthDay; import java.time.OffsetDateTime; import java.time.OffsetTime; import java.time.Period; +import java.time.YearMonth; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; @@ -52,7 +54,7 @@ import org.springframework.lang.UsesJava8; @UsesJava8 public class DateTimeFormatterRegistrar implements FormatterRegistrar { - private static enum Type {DATE, TIME, DATE_TIME} + private enum Type {DATE, TIME, DATE_TIME} /** @@ -186,6 +188,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(YearMonth.class, new YearMonthFormatter()); + registry.addFormatterForFieldType(MonthDay.class, new MonthDayFormatter()); registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory()); } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/MonthDayFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/MonthDayFormatter.java new file mode 100644 index 0000000000..029bb76c37 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/MonthDayFormatter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002-2015 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.MonthDay; +import java.util.Locale; + +import org.springframework.format.Formatter; +import org.springframework.lang.UsesJava8; + +/** + * {@link Formatter} implementation for a JSR-310 {@link MonthDay}, + * following JSR-310's parsing rules for a MonthDay. + * + * @author Juergen Hoeller + * @since 4.2.4 + * @see MonthDay#parse + */ +@UsesJava8 +public class MonthDayFormatter implements Formatter { + + @Override + public MonthDay parse(String text, Locale locale) throws ParseException { + return MonthDay.parse(text); + } + + @Override + public String print(MonthDay object, Locale locale) { + return object.toString(); + } + +} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/YearMonthFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/YearMonthFormatter.java new file mode 100644 index 0000000000..5b278494d5 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/YearMonthFormatter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002-2015 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.YearMonth; +import java.util.Locale; + +import org.springframework.format.Formatter; +import org.springframework.lang.UsesJava8; + +/** + * {@link Formatter} implementation for a JSR-310 {@link YearMonth}, + * following JSR-310's parsing rules for a YearMonth. + * + * @author Juergen Hoeller + * @since 4.2.4 + * @see YearMonth#parse + */ +@UsesJava8 +public class YearMonthFormatter implements Formatter { + + @Override + public YearMonth parse(String text, Locale locale) throws ParseException { + return YearMonth.parse(text); + } + + @Override + public String print(YearMonth object, Locale locale) { + return object.toString(); + } + +} diff --git a/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java b/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java index b8e1db83e7..1e96b13c07 100644 --- a/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java +++ b/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java @@ -29,7 +29,9 @@ import org.joda.time.Instant; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; +import org.joda.time.MonthDay; import org.joda.time.Period; +import org.joda.time.YearMonth; import org.joda.time.chrono.ISOChronology; import org.junit.After; import org.junit.Before; @@ -68,7 +70,6 @@ public class JodaTimeFormattingTests { private void setUp(JodaTimeFormatterRegistrar registrar) { conversionService = new FormattingConversionService(); DefaultConversionService.addDefaultConverters(conversionService); - registrar.registerFormatters(conversionService); JodaTimeBean bean = new JodaTimeBean(); @@ -477,6 +478,24 @@ public class JodaTimeFormattingTests { assertTrue(binder.getBindingResult().getFieldValue("duration").toString().equals("PT72.345S")); } + @Test + public void testBindYearMonth() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("yearMonth", "2007-12"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("yearMonth").toString().equals("2007-12")); + } + + @Test + public void testBindMonthDay() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("monthDay", "--12-03"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("monthDay").toString().equals("--12-03")); + } + @SuppressWarnings("unused") private static class JodaTimeBean { @@ -539,6 +558,10 @@ public class JodaTimeFormattingTests { private Duration duration; + private YearMonth yearMonth; + + private MonthDay monthDay; + private final List children = new ArrayList(); public LocalDate getLocalDate() { @@ -718,6 +741,22 @@ public class JodaTimeFormattingTests { this.duration = duration; } + public YearMonth getYearMonth() { + return yearMonth; + } + + public void setYearMonth(YearMonth yearMonth) { + this.yearMonth = yearMonth; + } + + public MonthDay getMonthDay() { + return monthDay; + } + + public void setMonthDay(MonthDay monthDay) { + this.monthDay = monthDay; + } + public List getChildren() { return children; } 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 a2ac65d20d..a60fbd69db 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,7 +21,9 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.MonthDay; import java.time.Period; +import java.time.YearMonth; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; @@ -66,7 +68,6 @@ public class DateTimeFormattingTests { private void setUp(DateTimeFormatterRegistrar registrar) { conversionService = new FormattingConversionService(); DefaultConversionService.addDefaultConverters(conversionService); - registrar.registerFormatters(conversionService); DateTimeBean bean = new DateTimeBean(); @@ -354,6 +355,24 @@ public class DateTimeFormattingTests { assertTrue(binder.getBindingResult().getFieldValue("duration").toString().equals("PT8H6M12.345S")); } + @Test + public void testBindYearMonth() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("yearMonth", "2007-12"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("yearMonth").toString().equals("2007-12")); + } + + @Test + public void testBindMonthDay() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("monthDay", "--12-03"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("monthDay").toString().equals("--12-03")); + } + public static class DateTimeBean { @@ -390,6 +409,10 @@ public class DateTimeFormattingTests { private Duration duration; + private YearMonth yearMonth; + + private MonthDay monthDay; + private final List children = new ArrayList(); public LocalDate getLocalDate() { @@ -496,6 +519,22 @@ public class DateTimeFormattingTests { this.duration = duration; } + public YearMonth getYearMonth() { + return yearMonth; + } + + public void setYearMonth(YearMonth yearMonth) { + this.yearMonth = yearMonth; + } + + public MonthDay getMonthDay() { + return monthDay; + } + + public void setMonthDay(MonthDay monthDay) { + this.monthDay = monthDay; + } + public List getChildren() { return children; }