I have an entity which has java.time.ZonedDateTime
property. I want to parse a string submitted from form in dd/MM/yyyy HH:mm
format to java.time.ZonedDateTime
.
I tried @DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
. But it works only LocalDate
with @DateTimeFormat(pattern = "dd/MM/yyyy")
format.
I also created a Converter
as below
public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
private final ZoneId zoneId;
public ZonedDateTimeConverter(ZoneId zoneId) {
this.zoneId = zoneId;
}
@Override
public ZonedDateTime convert(String source) {
LOG.info("Parsing string {} to ZonedDateTime: {}", source, ZonedDateTime.parse(source, DATE_TIME_FORMATTER));
return ZonedDateTime.parse(source, DATE_TIME_FORMATTER);
}
}
and overwriting webMvcConfiguration as below
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new ZonedDateTimeConverter(ZoneId.systemDefault()));
}
}
I'm not sure what is the right way to make it work. Using Spring Boot 1.5.6. Thymeleaf 3.0.7
Your
DateTimeFormatter
's pattern has only the date (dd/MM/yyyy
) and time (HH:mm
), but aZonedDateTime
also needs a timezone to be parsed directly.As the input doesn't have it, one alternative is to first parse the input to a
java.time.LocalDateTime
and then convert it to aZoneDateTime
, using thezoneId
that you already have:Another alternative is to set the timezone in the formatter, so you can parse directly to a
ZonedDateTime
. But in this case, I also suggest you a refactor: make the formatter a field of your converter class (instead of astatic
field), because it'll depend on theZoneId
you pass in the constructor.Just a note about using
ZoneId.systemDefault()
. This method gets the JVM's default timezone, but keep in mind that it can be changed without notice, even at runtime, so it's better to always specify which timezone you want to use.The API uses IANA timezones names (always in the format
Continent/City
, likeAsia/Kolkata
orEurope/Berlin
). Then you create the timezone usingof
method, such asZoneId.of("Asia/Kolkata")
.Avoid using the 3-letter abbreviations (like
IST
orPST
) because they are ambiguous and not standard. Some of them might work (usually due to retro-compatibility reasons), but it's not guaranteed.You can get a list of all available timezones (and choose the best for your case) with
ZoneId.getAvailableZoneIds()
.