I am using the java 8 java.time.LocalDate to parse around dates.
But trying to insert a LocalDate object to mongodb. I get errors in the java driver:
Unfortunately, the MongoDB driver uses the java.util.Date
type, see the docs here
So you have to convert your LocalDate to a Date instance first, for example:
MongoClient mongoClient = new MongoClient("localhost", 27017);
DB db = mongoClient.getDB("test");
DBCollection coll = db.getCollection("testcol");
LocalDate ld = LocalDate.now();
Instant instant = ld.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);
BasicDBObject doc = new BasicDBObject("localdate", date);
coll.insert(doc);
I would suggest using something like Morphia or Jongo to wrap the MongoDB driver though, as you can register global mappers to implicitly do these conversions on the fly, so that you can use LocalDate, etc, in your domain model
For anyone coming across this question, the following converter would get someone started in the right direction. This TypeConverter
converts between Date
and LocalDateTime
(Making this distinction because the OP specifically asked about LocalDate).
Add the following converter to Morphia as follows:
morphia.getMapper().getConverters().addConverter(new LocalDateTimeConverter());
Here is the converter class:
public class LocalDateTimeConverter extends TypeConverter implements SimpleValueConverter {
public LocalDateTimeConverter() {
// TODO: Add other date/time supported classes here
// Other java.time classes: LocalDate.class, LocalTime.class
// Arrays: LocalDateTime[].class, etc
super(LocalDateTime.class);
}
@Override
public Object decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
if (fromDBObject == null) {
return null;
}
if (fromDBObject instanceof Date) {
return ((Date) fromDBObject).toInstant().atZone(ZoneOffset.systemDefault()).toLocalDateTime();
}
if (fromDBObject instanceof LocalDateTime) {
return fromDBObject;
}
// TODO: decode other types
throw new IllegalArgumentException(String.format("Cannot decode object of class: %s", fromDBObject.getClass().getName()));
}
@Override
public Object encode(Object value, MappedField optionalExtraInfo) {
if (value == null) {
return null;
}
if (value instanceof Date) {
return value;
}
if (value instanceof LocalDateTime) {
ZonedDateTime zoned = ((LocalDateTime) value).atZone(ZoneOffset.systemDefault());
return Date.from(zoned.toInstant());
}
// TODO: encode other types
throw new IllegalArgumentException(String.format("Cannot encode object of class: %s", value.getClass().getName()));
}
}
As Oliver Gierke mentions here
This datatype is not supported yet. I hope this will be available soon.