“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

Time formatting is a common occurrence in our daily work, so in this article we will take a look at some of the methods of time formatting in Spring Boot.

Time problem demonstration

For the sake of demonstration, I wrote a simple Spring Boot project in which the database contains a userInfo table with the following structure and data information:The project catalog looks like this:The implementation code of UserController is as follows:

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserMapper userMapper;

    @RequestMapping("/list")
    public List<UserInfo> getList(a) {
        returnuserMapper.getList(); }}Copy the code

The implementation code of UserMapper is as follows:

@Mapper
public interface UserMapper {
    public List<UserInfo> getList(a);
}
Copy the code

The implementation code of UserInfo is as follows:

@Data
public class UserInfo {
    private int id;
    private String username;
    private Date createtime;
    private Date updatetime;
}
Copy the code

The implementation code of userMapper. XML is as follows:

<? xml version="1.0" encoding="UTF-8"? > <! DOCTYPE mapper PUBLIC"- / / mybatis.org//DTD Mapper / 3.0 / EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="getList" resultType="com.example.demo.model.UserInfo">
        select * from userinfo
    </select>
</mapper>
Copy the code

With that in mind, we have a simple Spring Boot project. Next, we use PostMan to simulate calling the UserController interface. The result is as follows:As can be seen from the above results, the time fieldcreatetimeupdatetimeThe display mode is very “messy”, does not conform to our reading habits, and can not be directly displayed to the front end of the user to use, this time, we need to format the time processing.

There are five methods of time formatting.

1. Format the front-end time

If the back end has an absolute right of discourse in the company, or the back end is relatively strong, we can force the time format of the “pot” to the front end to deal with.

In order to make this “pot” more smooth shake some (lei brother do not cook is a pity), we can give front-end engineers to provide a practical time format method, the implementation code is as follows.

JS version time format

function dateFormat(fmt, date) {
    let ret;
    const opt = {
        "Y+": date.getFullYear().toString(),        / / year
        "m+": (date.getMonth() + 1).toString(),     / / month
        "d+": date.getDate().toString(),            / /,
        "H+": date.getHours().toString(),           / /
        "M+": date.getMinutes().toString(),         / / points
        "S+": date.getSeconds().toString()          / / SEC.
        // There are other formatting characters that need to be added, which must be converted to a string
    };
    for (let k in opt) {
        ret = new RegExp("(" + k + ")").exec(fmt);
        if (ret) {
            fmt = fmt.replace(ret[1], (ret[1].length == 1)? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))}; };return fmt;
}
Copy the code

Method calls:

let date = new Date(a); dateFormat("YYYY-mm-dd HH:MM:SS", date);

>>> 2021-07-25 21:45:12
Copy the code

2. SimpleDateFormat format

Most of the time, we’re going to have to do it on our own, and we’re going to have to do it on our own as back-end programmers. The first time formatting method we provide is using SimpleDateFormat, which was an important time formatting method before JDK 8. Its core implementation code is as follows:

// Define the time formatting object and define the formatting style
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Format the time object
String date = dateFormat.format(new Date())
Copy the code

Next, we use SimpleDateFormat to implement the time formatting in this project. Its implementation code is as follows:

@RequestMapping("/list")
public List<UserInfo> getList(a) {
    // Define the time format object
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<UserInfo> list = userMapper.getList();
    // Loop to perform time formatting
    list.forEach(item -> {
        // Use the reserved ctime field to receive the time for createTime formatting (Date->String)
        item.setCtime(dateFormat.format(item.getCreatetime()));
        item.setUtime(dateFormat.format(item.getUpdatetime()));
    });
    return list;
}
Copy the code

The program execution results are as follows:From the above results, we can see that the time formatting is not a problem, and exactly what we expected the purpose. But careful readers will notice why the return field of the interface has changed. (The previous field iscreatetimeNow it isctime…).

This is because # simpleDateFormat. format returns a String result, whereas our createTime and updateTime fields were dates. Therefore, they are not allowed to receive time-formatted results.

Therefore, we need to add two new “time” fields of string type in the entity class UserInfo, and then hide the previous time fields of Data type. The final implementation code of UserInfo is as follows:

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.util.Date;

@Data
public class UserInfo {
    private int id;
    private String username;
    @JsonIgnore // Hide this field when output results
    private Date createtime;
    // Time formatted fields
    private String ctime;
    @JsonIgnore // Hide this field when output results
    private Date updatetime;
    // Time formatted fields
    private String utime;
}
Copy the code

We can use@JsonIgnoreThe annotation will hide the field, and the execution result after hiding is as follows:

3. DateTimeFormatter format

After JDK 8, we can use DateTimeFormatter instead of SimpleDateFormat because SimpleDateFormat is non-thread-safe and DateTimeFormatter is thread-safe. So for projects above JDK 8, try using DateTimeFormatter for time formatting.

DateTimeFormatter format code and SimpleDateFormat similar to the implementation of the following:

@RequestMapping("/list")
public List<UserInfo> getList(a) {
    // Define the time format object
    DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    List<UserInfo> list = userMapper.getList();
    // Loop to perform time formatting
    list.forEach(item -> {
        // Use the reserved ctime field to receive the time for createTime formatting (Date->String)
        item.setCtime(dateFormat.format(item.getCreatetime()));
        item.setUtime(dateFormat.format(item.getUpdatetime()));
    });
    return list;
}
Copy the code

The execution result is as follows:DateTimeFormatterSimpleDateFormatThe difference in usage isDateTimeFormatterIs used to format the time type provided by JDK 8, such asLocalDateTimeAnd theSimpleDateFormatIt’s for formattingDateSo we need to make the following changes to the UserInfoer entity class:

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class UserInfo {
    private int id;
    private String username;
    @JsonIgnore
    private LocalDateTime createtime;
    private String ctime;
    @JsonIgnore
    private LocalDateTime updatetime;
    private String utime;
}
Copy the code

We can use LocalDateTime to receive datetime from MySQL.

4. Global time formatting

Both of these implementations of back-end formatting have a fatal drawback. They require some changes to the core business class when doing the time formatting, which introduces a new problem in order to solve a problem. Is there a simpler and more elegant solution?

The answer is: yes. We can not change any code, just need to set in the configuration file to implement the time formatting function.

First, we find the Spring Boot configuration file application.properties (or application.yml), just add the following two lines of configuration to the application.properties configuration file:

Date-format = YYYY-mm-dd HH: MM :ss # Specifies the time zone type spring.jackson.time-zone=GMT+8Copy the code

After this setting, we restore the original UserInfo and UserController.

The implementation code of UserInfo is as follows:

import lombok.Data;
import java.util.Date;

@Data
public class UserInfo {
    private int id;
    private String username;
    private Date createtime;
    private Date updatetime;
}
Copy the code

UserController implementation code:

@RequestMapping("/list")
public List<UserInfo> getList(a) {
    return userMapper.getList();
}
Copy the code

Then we run the program and see the following execution result:From the above results and code can be seen, we only need a simple configuration in the program, you can achieve all the time field formatting.

Analysis of implementation principle

Why is it possible to format all time fields by setting them in a configuration file?

Date-format = YYYY-mm-dd HH: MM :ss # Specifies the time zone type spring.jackson.time-zone=GMT+8Copy the code

This is because when the Controller returns data, it automatically calls Jackson, the built-in JSON framework in Spring Boot framework, and performs unified JSON formatting for the returned data. Date-format = YYYY-MM-DD HH: MM :ss. If it is set, the Jackson framework will perform a time format on the output of fields of the time type. In this way, we can implement the global time field formatting function through the configuration.

Why do you specify the time zone type “spring.jackson.time-zone=GMT+8”?

The most realistic reason is that if we do not specify a time zone type, then check out time will be less time than expected to eight hours, this because we (China) time zone of less than 8 hours universal time, and when we set the time zone, we will query time and expected time.

What is GMT?

What does “GMT” mean in the time zone setting?

Greenwich Mean Time (GMT), also known as world Time.

Greenwich Mean time

Greenwich is the location of the former Royal Greenwich Observatory in the south suburb of London. It is the mark boundary of the earth’s prime meridian and the starting point of the world’s calculated time and longitude. It is famous for its maritime history, as the standard point of the prime meridian, and Greenwich Mean Time is named after it. It is a place of historic and local beauty, and the eastern gateway to London on the River Thames.

Greenwich Mean time is used not only by astronomers but also in the press. We know that there are local times everywhere. If a major international event is recorded in local time, it will be complicated and inconvenient. And it’s easy to make mistakes in the future. So astronomers have come up with an acceptable and convenient way to keep track of it: using Local time at Greenwich Mean Time.

The mean solar time calculated from the mean midnight of the prime meridian. Also known as Greenwich Mean time or GMT. The difference between local time and universal time is equal to the geographic longitude of each place. It was widely used as a basic time measurement system before 1960. Until 1960, universal time was considered to be uniform because the earth’s rotation rate was once thought to be uniform. The earth is not a uniform time system due to changes in its rotational speed, and it has no theoretical relationship to either atomic time or mechanical time, which can only be compared by observation. Universal time has since been replaced by almanac time and atomic time, but it is still necessary for daily life, celestial navigation, geodesy and space flight. Meanwhile, the variation of the rotation rate of the earth reflected by universal time is one of the rotation parameters of the Earth, which is still the basic information of astronomy and geophysics.

5. Format for part of the time

In some cases, we do not need to deal with the global time uniformly, in this case we can use annotations to achieve part of the time field formatting.

We need to add @jsonFormat annotation to the entity class UserInfo, so that we can implement the time formatting function, the implementation code is as follows:

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;

@Data
public class UserInfo {
    private int id;
    private String username;
    // Format the createTime field
    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8")
    private Date createtime;
    private Date updatetime;
}
Copy the code

After modifying the code, we run the project execution results are as follows:As you can see from the above results, time can also be formatted using annotations. Its implementation principle and the fourth kind of time formatting implementation principle is similar, are in the return of data before the corresponding field time formatting processing.

conclusion

In this article, we introduce five methods of time formatting, the first one is the front-end time formatting method, the last four are the back-end formatting method, SimpleDateFormat and DateTimeFormatter formatting method is more suitable for ordinary Java projects, SimpleDateFormat is non-thread-safe, and DateTimeFormatter** is thread-safe, but neither is the optimal time formatting scheme for a Spring Boot project.

If it is a Spring Boot project, it is recommended to use the fourth global time format or the fifth local time format, both of which do not need to change the core business code, only a simple configuration, you can complete the time formatting function.

Reference & thanks

www.jianshu.com/p/49fb78bca…

baike.baidu.com/item/ Universal time /692237

Check out the Java Chinese Community for more interesting and informative SpringBoot articles.