From d5ca5b74a58c96c91c12799f935ef7e402c7dfee Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Nov 2015 00:21:03 +0100 Subject: [PATCH] DateTimeFormatterRegistrar supports Duration and Period as well Issue: SPR-13721 --- .../datetime/standard/DateTimeConverters.java | 19 +++++++- .../standard/DateTimeFormatterRegistrar.java | 6 ++- .../datetime/standard/DurationFormatter.java | 47 ++++++++++++++++++ .../datetime/standard/PeriodFormatter.java | 48 +++++++++++++++++++ .../standard/DateTimeFormattingTests.java | 40 ++++++++++++++++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatter.java create mode 100644 spring-context/src/main/java/org/springframework/format/datetime/standard/PeriodFormatter.java diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeConverters.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeConverters.java index 0c48e74f5f..fe5a1162d3 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeConverters.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeConverters.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -85,6 +85,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class LocalDateTimeToLocalDateConverter implements Converter { @@ -94,6 +95,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class LocalDateTimeToLocalTimeConverter implements Converter { @@ -103,6 +105,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class ZonedDateTimeToLocalDateConverter implements Converter { @@ -112,6 +115,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class ZonedDateTimeToLocalTimeConverter implements Converter { @@ -121,6 +125,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class ZonedDateTimeToLocalDateTimeConverter implements Converter { @@ -139,6 +144,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class ZonedDateTimeToInstantConverter implements Converter { @@ -149,6 +155,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class OffsetDateTimeToLocalDateConverter implements Converter { @@ -158,6 +165,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class OffsetDateTimeToLocalTimeConverter implements Converter { @@ -167,6 +175,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class OffsetDateTimeToLocalDateTimeConverter implements Converter { @@ -176,6 +185,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class OffsetDateTimeToZonedDateTimeConverter implements Converter { @@ -185,6 +195,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class OffsetDateTimeToInstantConverter implements Converter { @@ -194,6 +205,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class CalendarToZonedDateTimeConverter implements Converter { @@ -203,6 +215,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class CalendarToOffsetDateTimeConverter implements Converter { @@ -212,6 +225,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class CalendarToLocalDateConverter implements Converter { @@ -221,6 +235,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class CalendarToLocalTimeConverter implements Converter { @@ -230,6 +245,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class CalendarToLocalDateTimeConverter implements Converter { @@ -239,6 +255,7 @@ final class DateTimeConverters { } } + @UsesJava8 private static class CalendarToInstantConverter implements Converter { 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 6cda2edd2a..9de51d10ca 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-2014 the original author or authors. + * 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. @@ -16,12 +16,14 @@ package org.springframework.format.datetime.standard; +import java.time.Duration; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.OffsetTime; +import java.time.Period; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; @@ -182,6 +184,8 @@ public class DateTimeFormatterRegistrar implements FormatterRegistrar { new TemporalAccessorParser(OffsetTime.class, timeFormatter)); registry.addFormatterForFieldType(Instant.class, new InstantFormatter()); + registry.addFormatterForFieldType(Period.class, new PeriodFormatter()); + registry.addFormatterForFieldType(Duration.class, new DurationFormatter()); registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory()); } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatter.java new file mode 100644 index 0000000000..77f93a3a70 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatter.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.Duration; +import java.util.Locale; + +import org.springframework.format.Formatter; +import org.springframework.lang.UsesJava8; + +/** + * {@link Formatter} implementation for a JSR-310 {@link Duration}, + * following JSR-310's parsing rules for a Duration. + * + * @author Juergen Hoeller + * @since 4.2.4 + * @see Duration#parse + */ +@UsesJava8 +public class DurationFormatter implements Formatter { + + @Override + public Duration parse(String text, Locale locale) throws ParseException { + return Duration.parse(text); + } + + @Override + public String print(Duration object, Locale locale) { + return object.toString(); + } + +} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/PeriodFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/PeriodFormatter.java new file mode 100644 index 0000000000..0c158eac21 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/PeriodFormatter.java @@ -0,0 +1,48 @@ +/* + * 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.Instant; +import java.time.Period; +import java.util.Locale; + +import org.springframework.format.Formatter; +import org.springframework.lang.UsesJava8; + +/** + * {@link Formatter} implementation for a JSR-310 {@link Period}, + * following JSR-310's parsing rules for a Period. + * + * @author Juergen Hoeller + * @since 4.2.4 + * @see Period#parse + */ +@UsesJava8 +public class PeriodFormatter implements Formatter { + + @Override + public Period parse(String text, Locale locale) throws ParseException { + return Period.parse(text); + } + + @Override + public String print(Period 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 136e634e15..a2ac65d20d 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 @@ -16,10 +16,12 @@ package org.springframework.format.datetime.standard; +import java.time.Duration; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Period; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; @@ -334,6 +336,24 @@ public class DateTimeFormattingTests { assertTrue(binder.getBindingResult().getFieldValue("instant").toString().startsWith("2009-10-31")); } + @Test + public void testBindPeriod() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("period", "P6Y3M1D"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("period").toString().equals("P6Y3M1D")); + } + + @Test + public void testBindDuration() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("duration", "PT8H6M12.345S"); + binder.bind(propertyValues); + assertEquals(0, binder.getBindingResult().getErrorCount()); + assertTrue(binder.getBindingResult().getFieldValue("duration").toString().equals("PT8H6M12.345S")); + } + public static class DateTimeBean { @@ -366,6 +386,10 @@ public class DateTimeFormattingTests { private Instant instant; + private Period period; + + private Duration duration; + private final List children = new ArrayList(); public LocalDate getLocalDate() { @@ -456,6 +480,22 @@ public class DateTimeFormattingTests { this.instant = instant; } + public Period getPeriod() { + return period; + } + + public void setPeriod(Period period) { + this.period = period; + } + + public Duration getDuration() { + return duration; + } + + public void setDuration(Duration duration) { + this.duration = duration; + } + public List getChildren() { return children; }