diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/Jsr310DateTimeFormatAnnotationFormatterFactory.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/Jsr310DateTimeFormatAnnotationFormatterFactory.java index 4c112bfc27f..da3afad6045 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/Jsr310DateTimeFormatAnnotationFormatterFactory.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/Jsr310DateTimeFormatAnnotationFormatterFactory.java @@ -16,6 +16,7 @@ package org.springframework.format.datetime.standard; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -57,6 +58,7 @@ public class Jsr310DateTimeFormatAnnotationFormatterFactory extends EmbeddedValu static { // Create the set of field types that may be annotated with @DateTimeFormat. Set> fieldTypes = new HashSet<>(8); + fieldTypes.add(Instant.class); fieldTypes.add(LocalDate.class); fieldTypes.add(LocalTime.class); fieldTypes.add(LocalDateTime.class); diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java index cea8340132d..ef9cd0a8c05 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java @@ -17,6 +17,7 @@ package org.springframework.format.datetime.standard; import java.text.ParseException; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -115,7 +116,10 @@ public TemporalAccessor parse(String text, Locale locale) throws ParseException private TemporalAccessor doParse(String text, Locale locale, DateTimeFormatter formatter) throws DateTimeParseException { DateTimeFormatter formatterToUse = DateTimeContextHolder.getFormatter(formatter, locale); - if (LocalDate.class == this.temporalAccessorType) { + if (Instant.class == this.temporalAccessorType) { + return formatterToUse.parse(text, Instant::from); + } + else if (LocalDate.class == this.temporalAccessorType) { return LocalDate.parse(text, formatterToUse); } else if (LocalTime.class == this.temporalAccessorType) { 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 1fe57b428c5..d133522024a 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 @@ -397,6 +397,15 @@ void testBindInstant() { assertThat(binder.getBindingResult().getFieldValue("instant").toString().startsWith("2009-10-31T12:00")).isTrue(); } + @Test + void testBindInstantAnnotated() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + propertyValues.add("styleInstant", "2017-02-21T13:00"); + binder.bind(propertyValues); + assertThat(binder.getBindingResult().getErrorCount()).isEqualTo(0); + assertThat(binder.getBindingResult().getFieldValue("styleInstant")).isEqualTo("2017-02-21T13:00"); + } + @Test @SuppressWarnings("deprecation") void testBindInstantFromJavaUtilDate() { @@ -622,6 +631,9 @@ public static class DateTimeBean { private Instant instant; + @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm") + private Instant styleInstant; + private Period period; private Duration duration; @@ -762,6 +774,14 @@ public void setInstant(Instant instant) { this.instant = instant; } + public Instant getStyleInstant() { + return this.styleInstant; + } + + public void setStyleInstant(Instant styleInstant) { + this.styleInstant = styleInstant; + } + public Period getPeriod() { return this.period; }