MongoDB's processing of time: the difference between ISODate and our time zone is 8 hours

Keywords: MongoDB Java Database Spring

In mongoDB database, the time is saved as ISODate type, and orm relationship is mapped as java.util.Date type. The time saved is 8 hours earlier than that of us

The original data is:

Person [id=11188, name=doctorwho, age=888888,birth=2016-01-01 13:55:00]

In MongoDB database:

{ 
    "_id" : "11188", 
    "_class" : "com.doctor.domain.Person", 
    "name" : "doctorwho", 
    "age" : NumberInt(888888), 
    "birth" : ISODate("2016-01-01T05:55:00.000+0000")
}

When we use time to query data, let's see what java driver does: (part of logs):

package com.doctor.springdoc;
 
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
 
import com.doctor.domain.Person;
import com.mongodb.WriteResult;
 
/**
 * JSONSerializers L205-216 About mongoDB's processing of time, the difference between ISODate and our time zone is 8 hours (make a time zone conversion)
 * 
 * @author sdcuike
 *
 * @time 2015 December 27, 2016 10:54:16 PM
 */
public class SavingUpdatingRemovingDocuments {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/mongoDBConfig/spring-mongoDB.xml");
        MongoTemplate mongoTemplate = context.getBean(MongoTemplate.class);
 
        Person person = new Person("doctorwho", 28888, "11188");
 
        LocalDateTime localDateTime = LocalDateTime.of(2016, 1, 1, 13, 55);
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
        person.setBirth(Date.from(zonedDateTime.toInstant()));
 
        System.out.println(person);
        if (mongoTemplate.findById(person.getId(), Person.class) == null) {
            mongoTemplate.insert(person);
        }
 
        Person findById = mongoTemplate.findById(person.getId(), Person.class);
        System.out.println(findById);
 
        List<Person> find = mongoTemplate.find(Query.query(Criteria.where("name").is("doctorwho").and("age").is(28888)), Person.class);
        find.forEach(System.out::println);
 
        WriteResult updateMulti = mongoTemplate.updateMulti(Query.query(Criteria.where("age").is(28888)), Update.update("age", 888888), Person.class);
        System.out.println(updateMulti.getN());
 
        System.out.println("time query");
        List<Person> find2 = mongoTemplate.find(Query.query(Criteria.where("birth").is(person.getBirth())), Person.class);
        find2.forEach(System.out::println);
        // JSONSerializers L205-216 about mongoDB's processing of time, the difference between ISODate and our time zone is 8 hours (do a time zone conversion)
    }
 
}

time query

01-02 22:12:37.195 main  DEBUG org.springframework.data.mongodb.core.MongoTemplate - find using query: { "birth" : { "$date" : "2016-01-01T05:55:00.000Z"}} fields: null for class: class com.doctor.domain.Person in collection: person

01-02 22:12:37.196 main  DEBUG org.springframework.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[sdcuike]

Person [id=11188, name=doctorwho, age=888888,birth=2016-01-01 13:55:00]


{ "birth" : { "$date" : "2016-01-01T05:55:00.000Z"}}

The query statement is queried according to our time difference, and the returned data is really what we need, even if the iso date we see in the database is 8 hours different. In fact, java driver helps us to do the transformation.


com.mongodb.util.JSONSerializers.LegacyDateSerializer Code:
 

 private static class LegacyDateSerializer extends CompoundObjectSerializer {
 
        LegacyDateSerializer(ObjectSerializer serializer) {
            super(serializer);
        }
 
        @Override
        public void serialize(Object obj, StringBuilder buf) {
            Date d = (Date) obj;
            SimpleDateFormat format = new SimpleDateFormat(
                    "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            format.setCalendar(new GregorianCalendar(
                    new SimpleTimeZone(0, "GMT")));
            serializer.serialize(
                    new BasicDBObject("$date", format.format(d)),
                    buf);
        }
 
    }

Here, time zone conversion is done.

GregorianCalendar

 

Originate:

https://blog.csdn.net/doctor_who2004/article/details/50449561

Posted by jonnyw6969 on Sat, 23 Nov 2019 08:12:52 -0800