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 aZonedDateTimealso 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.LocalDateTimeand then convert it to aZoneDateTime, using thezoneIdthat 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 astaticfield), because it'll depend on theZoneIdyou 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/KolkataorEurope/Berlin). Then you create the timezone usingofmethod, such asZoneId.of("Asia/Kolkata").Avoid using the 3-letter abbreviations (like
ISTorPST) 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().