preface

A few days ago, the development colleagues in the business department encountered a strange bug. First, they had a business created in the repository that was 8 hours different from the server time. Second, when the time was displayed in the front end, the time was several months different from the service time.

Today, on this issue, let’s make a review and talk about the direction of troubleshooting when the business data time is different from the expected

Screening direction

1. The time of the database and the server is inconsistent

1. View the time zone of the JDBC connection configuration, that is, serverTimezone

Note: All the time zones in this paper are based on edom 8 and the database is mysql

Example:

jdbc:mysql:/ / localhost: 3306 / demo? useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
Copy the code

If the time zone in the figure above is UTC, there will be a difference of 8 hours from east 8. With this configuration, when we use new Date () at the code level, the time to the database will be 8 hours later than we expected. In this case, we can change the time zone parameter configured on JDBC to

serverTimezone=Asia/Shanghai
Copy the code

2. View the default time zone Settings of the database

show variables like '%time_zone%';
Copy the code

It can be seen from the figure that the database time zone is not set to east 8 by default. We can modify it in the following way

  • A. Through the command
# change mysql global time zone to east 8
set global time_zone = From the '+'; 
 ## Change the current session time zone
set time_zone = From the '+';
Copy the code

Note: There is no need to restart the mysql service through the command line, but when the mysql service is restarted again, the above configuration will disappear

  • B. Through the configuration file

For Linux, edit my.cnf and fill in the following

[mysqld] // Set the time zone to default-time_zone=From the '+'
Copy the code

On Windows, edit my.ini and fill in the same content as on Linux

Note: Restart the mysql service after the configuration is modified

The difference in the creation time of the service department is 8 hours because the default creation time of the service department is configured through the database. The default time zone of the database is UTC, so the difference is 8 hours. This was later resolved by adjusting the database time zone

2. The time of the container and server is inconsistent

1. Check the time inside the container

docker exec -it[Container ID or NAME] bin/bash-c date
Copy the code

2. If the container is already generated

You can copy the host’s localtime directly into the docker container, as long as the host’s time is also correct. The command is

docker cp/etc/localtime [container ID or NAME] :/etc/localtimeCopy the code

Or change the time of the Docker container directly. Enter the contents of the container and execute date -s

3. Use Dockerfile to configure the container before generating it.

FROM adoptopenjdk/openjdk8
VOLUME /tmp
#ENV JAVA_OPTS="-Dcom.sun.management.jmxremote.port=39083 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
ENV JAVA_OPTS=""
COPY localtime /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone
COPY demo-biz/target/demo-service-biz-*.jar app.jar
ENTRYPOINT [ "sh"."-c"."exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
Copy the code

Note: Since business dockerfiles are uniformly generated from templates, there is no problem

3. The time format is incorrectly configured

In order to unify the processing time format, the business department made the following configuration in the code

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List
       
        > converters)
       > {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // Format the JSON data format
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        // Avoid loss of precision when serializing, converting to a string
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);

        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
        fastJsonConfig.setSerializeConfig(serializeConfig);
        fastJsonConfig.setDateFormat("yyyy-HH-dd HH:mm:ss");
        fastConverter.setFastJsonConfig(fastJsonConfig);

        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastMediaTypes.add(MediaType.APPLICATION_JSON);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);

        converters.add(0,fastConverter); }}Copy the code

Sharp-eyed friends may find that the time format is not the same as the normal format. Who would have thought that the weird bug was due to accidentally writing the wrong time format. The solution is very simple,

fastJsonConfig.setDateFormat("yyyy-HH-dd HH:mm:ss");
Copy the code

to

fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
Copy the code

conclusion

The above introduces several troubleshooting directions, especially the last one, because the time format is wrong, resulting in the time display error