ZonedDateTime with MongoDB ZonedDateTime with MongoDB spring spring

ZonedDateTime with MongoDB


Looks like Spring has support for all the java time converter except ZonedDateTime converter. You can register one as follows.

@Beanpublic CustomConversions customConversions(){    List<Converter<?,?>> converters = new ArrayList<>();    converters.add(new DateToZonedDateTimeConverter());    converters.add(new ZonedDateTimeToDateConverter());    return new CustomConversions(converters);}@Beanpublic MongoTemplate getMongoTemplate() throws UnknownHostException {    MappingMongoConverter converter = new MappingMongoConverter(            new DefaultDbRefResolver(getMongoDbFactory()), new MongoMappingContext());    converter.setCustomConversions(customConversions());    converter.afterPropertiesSet();    return new MongoTemplate(getMongoDbFactory(), converter);}    class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {         @Override     public ZonedDateTime convert(Date source) {              return source == null ? null : ofInstant(source.toInstant(), systemDefault());         }     }    class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {        @Override    public Date convert(ZonedDateTime source) {             return source == null ? null : Date.from(source.toInstant());       }   }

One other alternative solution would be to just use the ZonedDateTime and change it to date while persisting into MongoDB. You can easily change it back from date back to Zoned Date Time while fetching.

Below are the relavant methods to help with conversions.

ZoneId zoneID = ZoneId.of("America/Chicago");

From ZonedDateTime to java util date.

Instant instant = Instant.now();ZonedDateTime zonedDateTime = instant.atZone(zoneId);Date date = Date.from(zdt.toInstant());

From Date to ZonedDateTime

Instant instant = date.toInstant();ZonedDateTime zonedDateTime = instant.atZone(zoneId);

The other alternative is to implement custom codec to help with conversions. I've created one for YearMonth at Filtering YearMonth from Mongo document. I'll leave it as exercise to the reader if they want to create custom codec for Zoned Date Time.

You can use below library for codec based approach.

https://github.com/ylemoigne/mongo-jackson-codec


After spending way too much time debugging this, I finally found a working solution for latest version of spring boot / spring data. This is currently working for me on Spring Boot 2.0.0.M7.

With the accepted answer from veeram, I was getting Couldn't find PersistentEntity for type

I hope this helps someone avoid going down the rabbit hole.

@Configurationpublic class MongoConfiguration {    @Bean    public MongoCustomConversions customConversions(){        List<Converter<?,?>> converters = new ArrayList<>();        converters.add(DateToZonedDateTimeConverter.INSTANCE);        converters.add( ZonedDateTimeToDateConverter.INSTANCE);        return new MongoCustomConversions(converters);    }    enum DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {        INSTANCE;        @Override        public ZonedDateTime convert(Date source) {            return ofInstant(source.toInstant(), systemDefault());        }    }    enum ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {        INSTANCE;        @Override        public Date convert(ZonedDateTime source) {            return Date.from(source.toInstant());        }    }}