Skip to content

Commit 7e402ba

Browse files
committed
Improve docs on date and time formatting
Closes gh-24370
1 parent c0fbf6f commit 7e402ba

File tree

3 files changed

+103
-32
lines changed

3 files changed

+103
-32
lines changed

src/docs/asciidoc/core/core-validation.adoc

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,18 +1693,18 @@ See <<web.adoc#mvc-config-conversion, Conversion and Formatting>> in the Spring
16931693
[[format-configuring-formatting-globaldatetimeformat]]
16941694
== Configuring a Global Date and Time Format
16951695

1696-
By default, date and time fields that are not annotated with `@DateTimeFormat` are
1697-
converted from strings by using the `DateFormat.SHORT` style. If you prefer, you can
1698-
change this by defining your own global format.
1696+
By default, date and time fields not annotated with `@DateTimeFormat` are converted from
1697+
strings by using the `DateFormat.SHORT` style. If you prefer, you can change this by
1698+
defining your own global format.
16991699

1700-
To do so, you need to ensure that Spring does not register default formatters. Instead,
1701-
you should register all formatters manually. Use the
1702-
`org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar` or
1703-
`org.springframework.format.datetime.DateFormatterRegistrar` class, depending on whether
1704-
you use the Joda-Time library.
1700+
To do that, ensure that Spring does not register default formatters. Instead, register
1701+
formatters manually with the help of:
17051702

1706-
For example, the following Java configuration registers a global `yyyyMMdd`
1707-
format (this example does not depend on the Joda-Time library):
1703+
* `org.springframework.format.datetime.standard.DateTimeFormatterRegistrar`
1704+
* `org.springframework.format.datetime.DateFormatterRegistrar`, or
1705+
`org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar` for Joda-Time.
1706+
1707+
For example, the following Java configuration registers a global `yyyyMMdd` format:
17081708

17091709
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
17101710
.Java
@@ -1721,6 +1721,11 @@ format (this example does not depend on the Joda-Time library):
17211721
// Ensure @NumberFormat is still supported
17221722
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
17231723
1724+
// Register JSR-310 date conversion with a specific global format
1725+
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
1726+
registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"));
1727+
registrar.registerFormatters(conversionService);
1728+
17241729
// Register date conversion with a specific global format
17251730
DateFormatterRegistrar registrar = new DateFormatterRegistrar();
17261731
registrar.setFormatter(new DateFormatter("yyyyMMdd"));
@@ -1740,8 +1745,15 @@ format (this example does not depend on the Joda-Time library):
17401745
fun conversionService(): FormattingConversionService {
17411746
// Use the DefaultFormattingConversionService but do not register defaults
17421747
return DefaultFormattingConversionService(false).apply {
1748+
17431749
// Ensure @NumberFormat is still supported
17441750
addFormatterForFieldAnnotation(NumberFormatAnnotationFormatterFactory())
1751+
1752+
// Register JSR-310 date conversion with a specific global format
1753+
val registrar = DateTimeFormatterRegistrar()
1754+
registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyyMMdd"))
1755+
registrar.registerFormatters(this)
1756+
17451757
// Register date conversion with a specific global format
17461758
val registrar = DateFormatterRegistrar()
17471759
registrar.setFormatter(DateFormatter("yyyyMMdd"))
@@ -1786,18 +1798,10 @@ Time):
17861798
</beans>
17871799
----
17881800

1789-
NOTE: Joda-Time provides separate distinct types to represent `date`, `time`, and `date-time`
1790-
values. The `dateFormatter`, `timeFormatter`, and `dateTimeFormatter` properties of the
1791-
`JodaTimeFormatterRegistrar` should be used to configure the different formats for each
1792-
type. The `DateTimeFormatterFactoryBean` provides a convenient way to create formatters.
1793-
1794-
NOTE: If you use Spring MVC, remember to explicitly configure the conversion service that
1795-
is used. For Java-based `@Configuration`, this means extending the
1796-
`WebMvcConfigurationSupport` class and overriding the `mvcConversionService()` method.
1797-
For XML, you should use the `conversion-service` attribute of the
1798-
`mvc:annotation-driven` element.
1799-
See <<web.adoc#mvc-config-conversion, Conversion and Formatting>> for details.
1800-
1801+
Note there are extra considerations when configuring date and time formats in web
1802+
applications. Please see
1803+
<<web.adoc#mvc-config-conversion, WebMVC Conversion and Formatting>> or
1804+
<<web-reactive.adoc#webflux-config-conversion, WebFlux Conversion and Formatting>>.
18011805

18021806

18031807

src/docs/asciidoc/web/webflux.adoc

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3691,11 +3691,10 @@ class WebConfig : WebFluxConfigurer {
36913691
=== Conversion, formatting
36923692
[.small]#<<web.adoc#mvc-config-conversion, Web MVC>>#
36933693

3694-
By default, formatters for `Number` and `Date` types are installed, including support for
3695-
the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda-Time
3696-
formatting library is also installed if Joda-Time is present on the classpath.
3694+
By default, formatters for various number and date types are installed, along with support
3695+
for customization via `@NumberFormat` and `@DateTimeFormat` on fields.
36973696

3698-
The following example shows how to register custom formatters and converters:
3697+
To register custom formatters and converters in Java config, use the following:
36993698

37003699
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
37013700
.Java
@@ -3724,6 +3723,41 @@ The following example shows how to register custom formatters and converters:
37243723
}
37253724
----
37263725

3726+
By default Spring WebFlux considers the request Locale when parsing and formatting date
3727+
values. This works for forms where dates are represented as Strings with "input" form
3728+
fields. For "date" and "time" form fields, however, browsers use a fixed format defined
3729+
in the HTML spec. For such cases date and time formatting can be customized as follows:
3730+
3731+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
3732+
.Java
3733+
----
3734+
@Configuration
3735+
@EnableWebFlux
3736+
public class WebConfig implements WebFluxConfigurer {
3737+
3738+
@Override
3739+
public void addFormatters(FormatterRegistry registry) {
3740+
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
3741+
registrar.setUseIsoFormat(true);
3742+
registrar.registerFormatters(registry);
3743+
}
3744+
}
3745+
----
3746+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
3747+
.Kotlin
3748+
----
3749+
@Configuration
3750+
@EnableWebFlux
3751+
class WebConfig : WebFluxConfigurer {
3752+
3753+
override fun addFormatters(registry: FormatterRegistry) {
3754+
val registrar = DateTimeFormatterRegistrar()
3755+
registrar.setUseIsoFormat(true)
3756+
registrar.registerFormatters(registry)
3757+
}
3758+
}
3759+
----
3760+
37273761
NOTE: See <<core.adoc#format-FormatterRegistrar-SPI, `FormatterRegistrar` SPI>>
37283762
and the `FormattingConversionServiceFactoryBean` for more information on when to
37293763
use `FormatterRegistrar` implementations.

src/docs/asciidoc/web/webmvc.adoc

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4977,12 +4977,10 @@ sub-elements are available.
49774977
=== Type Conversion
49784978
[.small]#<<web-reactive.adoc#webflux-config-conversion, WebFlux>>#
49794979

4980-
By default formatters, for `Number` and `Date` types are installed, including support for
4981-
the `@NumberFormat` and `@DateTimeFormat` annotations. Full support for the Joda-Time
4982-
formatting library is also installed if Joda-Time is present on the classpath.
4980+
By default, formatters for various number and date types are installed, along with support
4981+
for customization via `@NumberFormat` and `@DateTimeFormat` on fields.
49834982

4984-
In Java configuration, you can register custom formatters and converters, as the
4985-
following example shows:
4983+
To register custom formatters and converters in Java config, use the following:
49864984

49874985
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
49884986
.Java
@@ -5010,7 +5008,7 @@ following example shows:
50105008
}
50115009
----
50125010

5013-
The following example shows how to achieve the same configuration in XML:
5011+
To do the same in XML config, use the following:
50145012

50155013
[source,xml,indent=0,subs="verbatim,quotes"]
50165014
----
@@ -5049,6 +5047,41 @@ The following example shows how to achieve the same configuration in XML:
50495047
</beans>
50505048
----
50515049

5050+
By default Spring MVC considers the request Locale when parsing and formatting date
5051+
values. This works for forms where dates are represented as Strings with "input" form
5052+
fields. For "date" and "time" form fields, however, browsers use a fixed format defined
5053+
in the HTML spec. For such cases date and time formatting can be customized as follows:
5054+
5055+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
5056+
.Java
5057+
----
5058+
@Configuration
5059+
@EnableWebMvc
5060+
public class WebConfig implements WebMvcConfigurer {
5061+
5062+
@Override
5063+
public void addFormatters(FormatterRegistry registry) {
5064+
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
5065+
registrar.setUseIsoFormat(true);
5066+
registrar.registerFormatters(registry);
5067+
}
5068+
}
5069+
----
5070+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
5071+
.Kotlin
5072+
----
5073+
@Configuration
5074+
@EnableWebMvc
5075+
class WebConfig : WebMvcConfigurer {
5076+
5077+
override fun addFormatters(registry: FormatterRegistry) {
5078+
val registrar = DateTimeFormatterRegistrar()
5079+
registrar.setUseIsoFormat(true)
5080+
registrar.registerFormatters(registry)
5081+
}
5082+
}
5083+
----
5084+
50525085
NOTE: See <<core.adoc#format-FormatterRegistrar-SPI, the `FormatterRegistrar` SPI>>
50535086
and the `FormattingConversionServiceFactoryBean` for more information on when to use
50545087
FormatterRegistrar implementations.

0 commit comments

Comments
 (0)