19

Using Spring Boot 1.5.4.RELEASE and Mongo driver 3.4.2.

I want to store LocalDate in mongo DB, but I am facing a weird problem:

LocalDate startDate = LocalDate.now();
LocalDate endDate = LocalDate.of(2020,12,01);
System.out.println("---- StartDate : ---"+startDate); 
System.out.println("-----End Date : ----"+endDate);
        
        repository.save(new Person("Mehraj","Malik", startDate, endDate));

Output on console:

---- StartDate : ---2017-08-26

-----End Date : ----2020-12-01

But In MongoDb it is storing incorrect dates.

Following is the json from MongoDb:

"startDate" : ISODate("2017-08-25T18:30:00.000Z"),

"endDate" :ISODate("2020-11-30T18:30:00.000Z")

Also, I have noticed that the stored time is also incorrect according to Indian time.

Why the dates are correct on console but not in MongoDB and how to resolve this problem?

ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
Mehraj Malik
  • 14,872
  • 15
  • 58
  • 85
  • 1
    MongoDB stores UTC datetime, and LocalDate doesn't contain timezone – Viet Aug 26 '17 at 05:46
  • Mongo Java client is free to represent your date objects how it pleases. If you want to store strings, then do so instead – OneCricketeer Aug 26 '17 at 05:46
  • 1
    LocalDate ignores time fields. They are undefined. if time is important use LocalDate.atStartOfDay and store a datetime in mongodb – thst Aug 26 '17 at 05:47
  • @Jerry06 Is ISO and UTC are the same? 'coz As per posted json it is showing in ISO? – Mehraj Malik Aug 26 '17 at 05:50
  • 1
    iso is a time format, utc is a time zone (a 'no timezone' timezone) – thst Aug 26 '17 at 05:59
  • @thst Thank, btw any way to make upper code work or any suggestion? – Mehraj Malik Aug 26 '17 at 06:01
  • When you read the person back, is there actually any problem with the date beeing different? LocalDate officially has no time. If you are interested in time use localdatetime. – thst Aug 26 '17 at 06:04
  • You can develop and register custom codecs (custom transformation) and store timestamp Long value: ```com.mongodb.MongoClientOptions.Builder#codecRegistry``` – alex.b Aug 26 '17 at 06:07
  • Yeah, The date should be the same as passed.. – Mehraj Malik Aug 26 '17 at 06:07
  • The problem in here is that a time component is being stores where he expects to find no time at all! I have the same problem in here, but even worse that a Local date is being stored like `ISODate("2017-06-30T03:00:00Z")` and if I export/import this data between machines with different timezones, that search for this field won't simply work. – Cotta Oct 24 '18 at 11:01

2 Answers2

13

The mongo-java client for a date object returns as instance of java.util.Date.

The problem could possibly be that while you save the startDate and the endDate value, its toString() method would probably use the JVM's default time zone to update the value.

The doc here states that The official BSON specification refers to the BSON Date type as the UTC datetime. and that could be the reason your LocalDateTime attributes were converted to the UTC time zone prior to being saved to the DB.

Also to avoid such confusion would suggest using the bson type timestamp to update date fields.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 20
    I dream of the day where specifications won't destroy data based on assumptions, and just store the data as this. Just like Java 8 did with its new date format. – Guillaume F. Aug 26 '17 at 07:44
8

In the MongoDB Java Driver 3.7 release : http://mongodb.github.io/mongo-java-driver/3.7/whats-new/ we can see that the driver now support LocalDate :

JSR-310 Instant, LocalDate & LocalDateTime support Support for Instant, LocalDate and LocalDateTime has been added to the driver.